Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessAuthenticate to Tina CMS
-
DeliveryCreate symlink in media root
-
ExploitRequest path through symlink
-
ExecutionTraverse outside media directory
-
ImpactRead/write arbitrary files
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V5 - File Handling Path canonicalization, traversal prevention
MITRE ATT&CK
2 techniques across 2 tactics: Discovery, Collection The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Requires authenticated user access to @tinacms/cli dev media routes. Attacker must have low privilege (PR:L) and a symlink or junction must already exist under the media root directory. No user interaction needed. Affects default configurations where symlink validation is not implemented. |
| Impact | CVSS 7.1 (High) reflects network-accessible attack vector with high attack complexity, low privileges required, and high confidentiality/integrity impact with low availability impact. The AC:H rating is critical-exploitation requires an attacker to first create or influence a symlink/junction within the media directory, which typically requires filesystem access or social engineering in repository workflows. PR:L indicates authenticated access to TinaCMS dev server is required. Real-world risk is elevated primarily in development and self-hosted scenarios where symlinks may exist legitimately in media directories (e.g., linking to external asset stores) or where attackers have limited filesystem access to plant junctions. The impact is genuine-confirmed arbitrary file read/write outside media root-but the prerequisite conditions limit widespread exploitability. EPSS probability not provided for risk calibration. No CISA KEV listing or public weaponization identified, suggesting limited active targeting. SSVC factors: exploitation status is POC (researcher demonstrated local Windows junction); automatable is NO due to symlink prerequisite; technical impact is TOTAL (arbitrary file operations). Priority is MEDIUM for dev environments with symlinks, LOW for production deployments without user-controlled filesystem state. This is a legitimate high-severity issue in affected configurations but not an emergency patch requiring immediate universal deployment. |
| Exploit ScenarioDerived | An attacker with low-privilege authenticated access to a TinaCMS development server first creates a Windows junction or symlink named 'pivot' under the media uploads directory, pointing to a sensitive directory like /etc or C:\Windows\System32. They then send a GET request to /media/list/pivot which passes path validation because 'pivot' resolves lexically within the media root, but Node.js readdir follows the junction and returns a directory listing of the external target, leaking sensitive filesystem structure. The attacker escalates by POST uploading a malicious file to /media/upload/pivot/malicious.exe, which TinaCMS writes through the junction to the system directory, achieving arbitrary file write outside the media sandbox. The researcher's Windows proof-of-concept demonstrates this pattern with a junction linking public/uploads/pivot to an outside directory, successfully writing 'MEDIA_ESCAPE' content to outside/written-from-media.txt. No public exploit identified at time of analysis beyond the researcher's local demonstration. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Apr 01, 2026
TinaCMS CLI media handlers can be bypassed via symlink/junction traversal, allowing authenticated low-privilege attackers to list, write, and delete files outside the configured media root directory. The vulnerability exists in @tinacms/cli's dev server media routes despite recent path-traversal hardening, because validation performs only lexical string checks without resolving symlink targets. Attack complexity is high (requires pre-existing symlink under media root), but impact is significant with confirmed read/write primitives. Vendor patch available via GitHub commit f124eaba. EPSS and KEV data not provided; no public exploit identified at time of analysis beyond researcher's local Windows junction proof-of-concept.
RemediationAI
Vendor-released patch: GitHub commit f124eabaca10dac9a4d765c9e4135813c4830955 addresses the symlink traversal vulnerability by implementing canonical path resolution. Users should upgrade @tinacms/cli to the patched version specified in the advisory at https://github.com/tinacms/tinacms/security/advisories/GHSA-g87c-r2jp-293w. The fix replaces lexical string validation with fs.realpath() canonicalization to resolve symlink targets before performing containment checks, ensuring filesystem operations cannot escape the media root via indirection. Until patching is complete, immediate workarounds include auditing the media directory tree to identify and remove any symlinks or junctions, restricting filesystem write access to prevent symlink creation under the media root, and limiting dev server exposure to trusted networks only. For self-hosted production deployments, consider disabling dev server media routes entirely if not required. Review application logs for suspicious media route access patterns targeting paths with multiple directory components that could indicate reconnaissance or exploitation attempts. The delete endpoint uses identical validation logic and is addressed by the same patch.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in npm, euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
TinaCMS CLI (npm package @tinacms/cli) provides development server routes for media file management. The affected code in media.ts and path.ts implements path-traversal protection using path.resolve() with lexical string prefix matching (startsWith checks). This approach validates that user-supplied paths resolve to strings beginning with the media base directory but does not account for filesystem indirection via symbolic links or Windows junctions. CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) occurs because the validated path is passed directly to Node.js fs operations (readdir, createWriteStream, remove) which follow symlinks by default. When a symlink exists under the media root pointing outside it, paths like 'pivot/file.txt' pass lexical validation but filesystem operations target the link destination. The vulnerability affects the /media/list, /media/upload, and DELETE /media endpoints in the dev server. Canonical path resolution with fs.realpath() is required to detect and block symlink-based directory escapes before filesystem operations occur.
Know when Canonical gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:L
Primary rating from GitHub Advisory · only source for this CVE.
CVSS VectorGitHub Advisory
Lifecycle Timeline
2DescriptionGitHub Advisory
Summary
@tinacms/cli recently added lexical path-traversal checks to the dev media routes, but the implementation still validates only the path string and does not resolve symlink or junction targets.
If a link already exists under the media root, Tina accepts a path like pivot/written-from-media.txt as "inside" the media directory and then performs real filesystem operations through that link target. This allows out-of-root media listing and write access, and the same root cause also affects delete.
Details
The dev media handlers validate user-controlled paths with:
function resolveWithinBase(userPath: string, baseDir: string): string {
const resolvedBase = path.resolve(baseDir);
const resolved = path.resolve(path.join(baseDir, userPath));
if (resolved === resolvedBase) {
return resolvedBase;
}
if (resolved.startsWith(resolvedBase + path.sep)) {
return resolved;
}
throw new PathTraversalError(userPath);
}
function resolveStrictlyWithinBase(userPath: string, baseDir: string): string {
const resolvedBase = path.resolve(baseDir) + path.sep;
const resolved = path.resolve(path.join(baseDir, userPath));
if (!resolved.startsWith(resolvedBase)) {
throw new PathTraversalError(userPath);
}
return resolved;
}But the validated path is then used directly for real filesystem access:
filesStr = await fs.readdir(validatedPath);
...
await fs.ensureDir(path.dirname(saveTo));
file.pipe(fs.createWriteStream(saveTo));
...
await fs.remove(file);This does not account for symlinks/junctions already present below the media root. A path such as pivot/secret.txt can be lexically inside the media directory while the filesystem target is outside it.
Local Reproduction
I verified this locally with a real junction on Windows.
Test layout:
- media root:
D:\bugcrowd\tinacms\temp\junction-repro4\public\uploads - junction under media root:
public\uploads\pivot -> D:\bugcrowd\tinacms\temp\junction-repro4\outside - file outside the media root:
outside\secret.txt
Tina's current media-path validation logic was applied and used to perform the same list/write operations the route handlers use.
Observed result:
{
"media": {
"base": "D:\\bugcrowd\\tinacms\\temp\\junction-repro4\\public\\uploads",
"resolvedListPath": "D:\\bugcrowd\\tinacms\\temp\\junction-repro4\\public\\uploads\\pivot",
"listedEntries": [
"secret.txt"
],
"resolvedWritePath": "D:\\bugcrowd\\tinacms\\temp\\junction-repro4\\public\\uploads\\pivot\\written-from-media.txt",
"outsideWriteExists": true,
"outsideWriteContents": "MEDIA_ESCAPE"
}
}This shows the problem clearly:
- the path validator accepted
pivot - listing revealed a file from outside the media root
- writing to
pivot/written-from-media.txtcreatedoutside\written-from-media.txt
The delete path uses the same flawed containment model and should be hardened at the same time.
Impact
- Out-of-root file listing via
/media/list/... - Out-of-root file write via
/media/upload/... - Likely out-of-root file delete via
/media/...DELETE, using the same path-validation gap - Bypass of the recent path traversal hardening for any deployment whose media tree contains a link to another location
This is especially relevant in development and self-hosted workflows where the media directory may contain symlinks or junctions intentionally or via repository content.
Recommended Fix
Harden media path validation with canonical filesystem checks:
- resolve the real base path with
fs.realpath() - resolve the real target path, or for writes the nearest existing parent
- compare canonical paths rather than lexical strings
- reject any operation that traverses through a symlink/junction to leave the real media root
path.resolve(...).startsWith(...) is not sufficient for filesystem security on linked paths.
Resources
packages/@tinacms/cli/src/next/commands/dev-command/server/media.tspackages/@tinacms/cli/src/server/models/media.tspackages/@tinacms/cli/src/utils/path.ts
Blast Radius
ecosystem impact- 6 npm packages depend on @tinacms/graphql (3 direct, 3 indirect)
Ecosystem-wide dependent count for version 2.2.2.
Executive ViewAI
TinaCMS CLI versions prior to the patched release contain a symlink traversal vulnerability affecting authenticated users with low privileges, enabling unauthorized file read, write, and delete operations outside the intended media directory. Organizations using TinaCMS for content management should prioritize patching to prevent credential-holding developers from accessing sensitive project files and configuration data.
Apply vendor patch. Interim mitigations pending patch deployment: (1) Restrict developer access to TinaCMS dev server to trusted networks only; (2) Disable dev server media routes if not actively in use; (3) Monitor filesystem access to sensitive files within media directory scope; (4) Enforce file system permissions preventing creation of symlinks/junctions under media root directories.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Path traversal exploits occur when applications use user-controlled input to construct file system paths without proper validation.
Related Vulnerabilities in TinaCMS Path Traversal Vulnerabilities
View all 2Oracle Java SE JDK/JRE 7 and 6 Update 27 and earlier allows remote code execution with complete system compromise throug
In PHP versions 7.1.x below 7.1.33, 7.2.x below 7.2.24 and 7.3.x below 7.3.11 in certain configurations of FPM setup it
GNU Bash through 4.3 processes trailing strings after function definitions in the values of environment variables, which
Multiple vulnerabilities in Oracle Java 7 before Update 11 allow remote attackers to execute arbitrary code by (1) using
The (1) EPHEMERAL, (2) HTTPS, (3) MVG, (4) MSL, (5) TEXT, (6) SHOW, (7) WIN, and (8) PLT coders in ImageMagick before 6.
When running Apache Tomcat versions 9.0.0.M1 to 9.0.0, 8.5.0 to 8.5.22, 8.0.0.RC1 to 8.0.46 and 7.0.0 to 7.0.81 with HTT
Remote code execution is possible with Apache Tomcat before 6.0.48, 7.x before 7.0.73, 8.x before 8.0.39, 8.5.x before 8
GNU Bash through 4.3 bash43-025 processes trailing strings after certain malformed function definitions in the values of
The (1) TLS and (2) DTLS implementations in OpenSSL 1.0.1 before 1.0.1g do not properly handle Heartbeat Extension packe
Race condition in mm/gup.c in the Linux kernel 2.x through 4.x before 4.8.3 allows local users to gain privileges by lev
Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 17 and earlier, and
Local privilege escalation in the GNU C Library (glibc) dynamic loader ld.so allows unprivileged local users on affected
EUVD-2026-17964
GHSA-g87c-r2jp-293w
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB