Skip to main content

Microsoft CVE-2026-34603

| EUVDEUVD-2026-17964 HIGH
Path Traversal (CWE-22)
2026-04-01 https://github.com/tinacms/tinacms GHSA-g87c-r2jp-293w
7.1
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
7.1 HIGH
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

Attack Vector
Network
Attack Complexity
High
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
Low

Lifecycle Timeline

4
EUVD ID Assigned
Apr 01, 2026 - 00:30 euvd
EUVD-2026-17964
Analysis Generated
Apr 01, 2026 - 00:30 vuln.today
Patch released
Apr 01, 2026 - 00:30 nvd
Patch available
CVE Published
Apr 01, 2026 - 00:23 nvd
HIGH 7.1

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 2 npm packages depend on @tinacms/graphql (2 direct, 0 indirect)

Ecosystem-wide dependent count for version 2.2.2.

DescriptionGitHub 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:

ts
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:

ts
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:

json
{
  "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.txt created outside\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:

  1. resolve the real base path with fs.realpath()
  2. resolve the real target path, or for writes the nearest existing parent
  3. compare canonical paths rather than lexical strings
  4. 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.ts
  • packages/@tinacms/cli/src/server/models/media.ts
  • packages/@tinacms/cli/src/utils/path.ts

AnalysisAI

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.

Technical ContextAI

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.

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.

CVE-2011-3544 CRITICAL POC
9.8 Oct 19

Oracle Java SE JDK/JRE 7 and 6 Update 27 and earlier allows remote code execution with complete system compromise throug

CVE-2019-11043 CRITICAL POC
9.8 Oct 28

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

CVE-2014-6271 CRITICAL POC
9.8 Sep 24

GNU Bash through 4.3 processes trailing strings after function definitions in the values of environment variables, which

CVE-2013-0422 CRITICAL POC
9.8 Jan 10

Multiple vulnerabilities in Oracle Java 7 before Update 11 allow remote attackers to execute arbitrary code by (1) using

CVE-2016-3714 HIGH POC
8.4 May 05

The (1) EPHEMERAL, (2) HTTPS, (3) MVG, (4) MSL, (5) TEXT, (6) SHOW, (7) WIN, and (8) PLT coders in ImageMagick before 6.

CVE-2017-12617 HIGH POC
8.1 Oct 04

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

CVE-2016-8735 CRITICAL POC
9.8 Apr 06

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

CVE-2014-7169 CRITICAL POC
9.8 Sep 25

GNU Bash through 4.3 bash43-025 processes trailing strings after certain malformed function definitions in the values of

CVE-2014-0160 HIGH POC
7.5 Apr 07

The (1) TLS and (2) DTLS implementations in OpenSSL 1.0.1 before 1.0.1g do not properly handle Heartbeat Extension packe

CVE-2016-5195 HIGH POC
7.0 Nov 10

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

CVE-2013-2423 LOW POC
3.7 Apr 17

Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 17 and earlier, and

CVE-2023-4911 HIGH POC
7.8 Oct 03

Local privilege escalation in the GNU C Library (glibc) dynamic loader ld.so allows unprivileged local users on affected

Share

CVE-2026-34603 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy