Skip to main content
Vulnerability Database/CVE-2026-108259

CVE-2026-108259: TinaCMS CLI RCE Vulnerability

CVE-2026-108259 is a remote code execution flaw in TinaCMS CLI that enables attackers to inject malicious code through crafted Git branch names during preview builds. This article covers technical details, affected versions, impact assessment, and recommended mitigation strategies.

Published:

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Sources: National Vulnerability Database, CISA KEV, Exploit-DB

CVE-2026-108259 Overview

CVE-2026-108259 is a code injection vulnerability [CWE-94] in @tinacms/cli, the command-line component of the TinaCMS headless content management system. The TinaCMS CLI reads Git branch values from VERCEL_GIT_COMMIT_REF, GITHUB_BRANCH, or HEAD and interpolates the raw value into JavaScript string literals during code generation. A Git-valid branch name containing a quote character terminates the generated string and injects attacker-controlled expressions. The injected code executes with build process privileges when the generated client module is imported during a preview build. TinaCMS resolved the issue in @tinacms/cli version 3.0.0.

Critical Impact

Attackers who can create branches in a connected Git repository can execute arbitrary code in the build environment, exfiltrate deployment secrets, and tamper with deployment artifacts.

Affected Products

  • @tinacms/cli versions prior to 3.0.0
  • TinaCMS projects using preview builds driven by VERCEL_GIT_COMMIT_REF, GITHUB_BRANCH, or HEAD
  • Deployment pipelines (such as Vercel preview environments) that import the generated TinaCMS client

Discovery Timeline

  • 2026-10-09 - CVE-2026-108259 published to NVD
  • 2026-10-16 - Last updated in NVD database

Technical Details for CVE-2026-108259

Vulnerability Analysis

The vulnerability resides in the TinaCMS code generation logic in packages/@tinacms/cli/src/next/codegen/index.ts and packages/@tinacms/cli/src/next/codegen/codegen/plugin.ts. These modules build a JavaScript client file by interpolating the API URL and related values into template literals wrapped in single quotes. The API URL incorporates the current Git branch name derived from environment variables such as VERCEL_GIT_COMMIT_REF. Because the branch value is embedded as a raw string without escaping or JSON encoding, a quote character inside the branch name closes the generated literal early. The remaining branch content becomes executable JavaScript inside the generated module. When a build step imports the generated client, the injected expression runs with the privileges of the build process.

Root Cause

The root cause is unsafe string interpolation of untrusted input into generated source code. The CLI treats the Git branch value as a trusted scalar and places it directly between single quotes using a template literal. Git permits a broad set of characters in branch names, including quote characters, so the branch value cannot be assumed to be a safe string fragment. The missing output encoding allows breakout from the string context into the surrounding code context.

Attack Vector

An attacker who can push a branch to a repository connected to a TinaCMS preview pipeline creates a branch name that contains a quote followed by a JavaScript expression. When the preview build runs, the CLI reads the branch from the Git-related environment variables and generates a client module that evaluates the injected expression on import. The payload runs with build-time access to environment variables, cloud tokens, and deployment artifacts. The attack requires low privileges (branch creation) but is constrained by naming rules enforced by Git and the hosting provider, which raises attack complexity.

typescript
// Fix applied in packages/@tinacms/cli/src/next/codegen/codegen/plugin.ts
   getSdk(
     generateRequester(
       createClient({
-        url: "${apiURL}",
+        url: ${JSON.stringify(apiURL)},
         queries,
       })
     )

Source: GitHub Commit d030d414

typescript
// Fix applied in packages/@tinacms/cli/src/next/codegen/index.ts
 import { queries } from "./types.js";
 export const client = createClient({ ${
       this.noClientBuildCache === false
-        ? `cacheDir: '${normalizePath(
-            this.configManager.generatedCachePath
-          )}', `
+        ? `cacheDir: ${JSON.stringify(
+            normalizePath(this.configManager.generatedCachePath)
+          )}, `
         : ''
-    }url: ${this.localContentBuild ? `process.env.TINA_LOCAL_URL || '${apiURL}'` : `'${apiURL}'`}, token: '${token}', queries, ${
-      errorPolicy ? `errorPolicy: '${errorPolicy}'` : ''
+    }url: ${
+      this.localContentBuild
+        ? `process.env.TINA_LOCAL_URL || ${JSON.stringify(apiURL)}`
+        : JSON.stringify(apiURL)
+    }, token: ${JSON.stringify(String(token))}, queries, ${
+      errorPolicy ? `errorPolicy: ${JSON.stringify(String(errorPolicy))}` : ''
     } });
 export default client;

Source: GitHub Commit d030d414

The patch replaces unquoted template interpolation with JSON.stringify, which produces a safely escaped JavaScript string literal regardless of the input content.

Stop Remote Code Execution Before It Runs

Singularity™ Endpoint detects and blocks exploit attempts at machine speed, including zero-days and novel attack techniques.

Stop Exploit Attempts

Detection Methods for CVE-2026-108259

Indicators of Compromise

  • Git branches with names containing single-quote, double-quote, or backtick characters, or embedded JavaScript tokens such as +, ${, or ;
  • Generated TinaCMS client files that contain unexpected identifiers or function calls beyond the standard createClient invocation
  • Outbound network connections from CI or preview build runners to domains unrelated to the project's deployment pipeline
  • Build logs showing access to environment variables or secret files during the TinaCMS codegen step

Detection Strategies

  • Scan repository branch lists for names that contain quote characters or shell and JavaScript metacharacters.
  • Diff the generated TinaCMS client output in CI against a known-good baseline to flag injected tokens.
  • Audit CI runner process trees for child processes spawned by the Node.js code-generation step that are not part of the normal TinaCMS build.

Monitoring Recommendations

  • Monitor CI and preview environments for unexpected egress traffic during build phases, especially from runners handling preview branches.
  • Alert on reads of sensitive environment variables (API tokens, cloud credentials) outside the deployment command stage.
  • Track creation of unusual branch names in connected repositories via Git provider audit logs.

How to Mitigate CVE-2026-108259

Immediate Actions Required

  • Upgrade @tinacms/cli to version 3.0.0 or later across all projects and CI configurations.
  • Rotate any secrets, tokens, or deployment credentials exposed to TinaCMS preview build environments prior to patching.
  • Restrict branch creation permissions on repositories connected to TinaCMS preview pipelines to trusted contributors.
  • Review preview deployment history for branches with suspicious names and inspect associated build logs.

Patch Information

The fix is included in @tinacms/cli@3.0.0. The patch replaces raw string interpolation with JSON.stringify calls in both packages/@tinacms/cli/src/next/codegen/index.ts and packages/@tinacms/cli/src/next/codegen/codegen/plugin.ts. See the GitHub Security Advisory GHSA-pwhx-cvv3-qj5c, the GitHub Pull Request #7526, and the GitHub Release v3.0.0 for full details.

Workarounds

  • Validate the VERCEL_GIT_COMMIT_REF, GITHUB_BRANCH, and HEAD environment variables in CI before invoking the TinaCMS CLI and reject values containing quote characters or non-alphanumeric metacharacters.
  • Enforce a branch naming policy at the Git provider that limits names to a safe character set such as [A-Za-z0-9/_-].
  • Run TinaCMS preview builds in isolated environments with minimal secrets and no access to production deployment credentials.
bash
# Pre-build validation guard for CI pipelines
BRANCH="${VERCEL_GIT_COMMIT_REF:-${GITHUB_BRANCH:-$(git rev-parse --abbrev-ref HEAD)}}"
if ! printf '%s' "$BRANCH" | grep -Eq '^[A-Za-z0-9/_.-]+$'; then
  echo "Rejected unsafe branch name: $BRANCH" >&2
  exit 1
fi

# Upgrade to the patched release
npm install @tinacms/cli@3.0.0

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Sources: National Vulnerability Database, CISA KEV, Exploit-DB

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.