Skip to main content

TinaCMS CLI CVE-2026-108259

| EUVDEUVD-2026-95987 HIGH
Code Injection (CWE-94)
2026-10-09 GitHub_M GHSA-pwhx-cvv3-qj5c
8.2
CVSS 3.1 · Vendor: GitHub_M
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Gain ability to set build branch name
  2. Delivery
    Push crafted branch with quote payload
  3. Exploit
    Trigger preview build running @tinacms/cli codegen
  4. Execution
    Generated client interpolates branch into JS string
  5. Persist
    Import of client module executes injected expression
  6. Impact
    Read env credentials and tamper with deployment artifacts

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Code injection prevention, sandbox exec
MITRE ATT&CK

2 techniques across 2 tactics: Execution, Initial Access

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

Exploitation requires a TinaCMS project whose build runs @tinacms/cli codegen (notably preview builds) using versions <= 2.7.0, AND an attacker able to control the Git branch value that the CLI reads from VERCEL_GIT_COMMIT_REF, GITHUB_BRANCH, or HEAD - for example by pushing a branch or opening a pull request whose branch name is consumed by the CI/preview pipeline. The branch name must be git-check-ref-format-valid, which permits a single quote (GITHUB_BRANCH is free text and additionally permits backslash/newline); the quote closes the generated URL string literal and injects an expression that runs when the generated client module is imported during the build. Limiting factors: the codegen step and the import of the generated client must actually execute in the build (so AC is high), the attacker needs some privilege to influence the branch (PR:L, not fully anonymous in typical configurations), and only versions at or below 2.7.0 are affected - 3.0.0 emits all values as JS literals via JSON.stringify.

Impact

This is a genuine, well-substantiated code-injection flaw (CWE-94) rather than an inflated high-CVSS issue, but its real-world priority is moderate and gated by preconditions. The provided CVSS 3.1 vector (AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:N = 8.2) is internally coherent: high complexity reflects the need for a crafted branch name to flow through codegen during a preview build, low privileges reflect the attacker's need to influence the Git branch (e.g., via a pushed branch, pull request, or control of GITHUB_BRANCH/VERCEL_GIT_COMMIT_REF), and the changed scope (S:C) is justified because injected JavaScript executes in the build process rather than only the generated client module. A detailed proof-of-concept - including a git-check-ref-format-valid payload branch (x'+(globalThis.__TINA_PROBE='hit')+') and a full reproduction harness - is published in the GHSA advisory, so publicly available exploit code exists; however, there is NO EPSS score and NO CISA KEV entry in the provided data, so there is no evidence of active or widespread exploitation. The absence of EPSS/KEV combined with the AC:H build-pipeline dependency suggests this is a supply-chain/CI-hardening concern most relevant to teams running TinaCMS preview builds on untrusted branch input, not a mass-exploitation threat. Authentication requirements map to PR:L (authenticated/some access to influence the branch), consistent with the CVSS vector.

Exploit ScenarioDerived

An attacker who can introduce a branch name into a TinaCMS preview build pipeline (for example by opening a pull request or pushing a branch whose name is read from VERCEL_GIT_COMMIT_REF, GITHUB_BRANCH, or HEAD) crafts a git-valid branch name containing a quote, such as x'+(globalThis.__TINA_PROBE='hit')+'. When @tinacms/cli codegen runs, the raw branch name is interpolated unescaped into the generated client module's URL string literal; importing that module during the build terminates the string and executes the attacker's JavaScript with build-process privileges, allowing theft of environment credentials or tampering with deployment artifacts. A complete working proof-of-concept and reproduction steps are published in the GHSA advisory.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.3% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Oct 09, 2026

Code injection in @tinacms/cli versions up to and including 2.7.0 lets a crafted Git branch name break out of the string literal used for the generated client's API URL and execute arbitrary JavaScript when that generated client module is imported during a preview or CI build. The flaw, rated CVSS 8.2 (AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:N), requires the build to actually run codegen and import the generated client, and requires an attacker able to influence the branch value read from VERCEL_GIT_COMMIT_REF, GITHUB_BRANCH, or HEAD, so exploitation is gated by meaningful preconditions rather than being trivially remote. Injected code runs with build-process privileges, allowing theft of environment credentials, tampering with deployment artifacts, and outbound network requests; no public exploit tooling identified at time of analysis, though the vendor advisory documents a working proof-of-concept branch-name payload, and there is no evidence of active exploitation (no CISA KEV listing) or EPSS data provided.

RemediationAI

Upgrade to the vendor-released patch: @tinacms/cli 3.0.0 (released as @tinacms/cli@3.0.0), which emits every value written into the generated client as a JavaScript literal via JSON.stringify instead of interpolating between quotes, covering the URL/branch as well as the token, cache directory, and error policy; the changeset explicitly notes that branch names containing a quote, backslash, or newline are now kept inside the URL string. If upgrading is not immediately possible, pin an explicit, hard-coded branch value in the Tina config (tina/config.ts) where the template permits it so the untrusted VERCEL_GIT_COMMIT_REF/GITHUB_BRANCH value is never read, or unset/override those environment variables during codegen - the trade-off is that preview builds will then target the wrong branch or content rather than the branch under review. Additional compensating controls with their trade-offs: restrict who can create or push branches and PR head refs in repositories wired to preview/CI builds (reduces the PR:L foothold but does not help if a compromised account is used), and treat the codegen/preview build environment as untrusted by scoping down available secrets and CI tokens (credentials are still exposed if the injection fires, but blast radius shrinks). Sanitizing branch names at the pipeline level (stripping quotes, backslashes, and newlines before the build) is a viable stopgap, though it changes the effective branch identifier used for content previews. See the advisory at https://github.com/tinacms/tinacms/security/advisories/GHSA-pwhx-cvv3-qj5c for details and the fix at https://github.com/tinacms/tinacms/pull/7526; no KEV or EPSS signal is available to justify emergency-only handling, but preview pipelines that auto-build pull-request branches should be remediated promptly given the credential-exposure impact.

Affected VersionsENISA

cli < 3.0.0
tinacms < 3.0.0

Affected Packages

npm @tinacms/cli fix: 3.0.0
euvd cli fix: 3.0.0
euvd tinacms fix: 3.0.0

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 3 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

The root cause is CWE-94 (Improper Control of Generation of Code / code injection) arising from unescaped string interpolation into generated source. In the @tinacms/cli codegen pipeline, the init template (packages/@tinacms/cli/src/cmds/init/templates/config.ts) reads a branch value from the environment variables VERCEL_GIT_COMMIT_REF or GITHUB_BRANCH, falling back to the local HEAD ref, and stores it in config.branch. _createApiUrl() in packages/@tinacms/cli/src/next/codegen/index.ts then concatenates that raw branch into the Content API URL without apply URL encoding (no encodeURIComponent), and genClient() interpolates the resulting URL directly into a single-quoted JavaScript string literal, url: '${apiURL}'. The sibling template in packages/@tinacms/cli/src/next/codegen/codegen/plugin.ts (line 55, url: "${apiURL}") uses the same unescaped double-quote pattern, and the token, cache directory, and error policy values are interpolated the same way. Git ref names legitimately permit a single quote (and GITHUB_BRANCH is free text, additionally permitting backslash and newline), so a branch such as x'+(globalThis.__TINA_PROBE='hit')+' closes the URL string literal and injects a JavaScript expression that evaluates at module import time under the build process's privileges. CPE data confirms the affected packages as cpe:2.3:a:tinacms:tinacms (all versions in the affected range) and cpe:2.3:a:@tinacms:cli, and the fix in 3.0.0 replaces quote-delimited interpolation with JSON.stringify so every generated value is emitted as a proper JavaScript literal.

Know when Tinacms 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

Vendor (GitHub_M) PRIMARY 8.2 HIGH
AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:N
vuln.today AI 8.2 HIGH

Attacker remotely supplies a branch name (AV:N) but needs codegen/preview-build execution and a crafted ref (AC:H) plus privilege to set the branch (PR:L); injected code escapes into the build process (S:C) enabling credential read (C:H) and artifact tampering (I:H), with no availability impact (A:N).

3.1 AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:N
4.0 AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N

Primary rating from Vendor (GitHub_M).

CVSS VectorVendor: GitHub_M

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

Lifecycle Timeline

2
Patch available
Oct 09, 2026 - 22:17 EUVD
CVE Published
Oct 09, 2026 - 20:36 cve.org
HIGH 8.2

DescriptionCVE.org

Tina is a headless content management system. Prior to 3.0.0, @tinacms/cli reads Git branch values from VERCEL_GIT_COMMIT_REF, GITHUB_BRANCH, or HEAD, incorporates the raw value into the API URL, and interpolates that URL into JavaScript string literals in packages/@tinacms/cli/src/next/codegen/index.ts and packages/@tinacms/cli/src/next/codegen/codegen/plugin.ts. A crafted Git-valid branch name containing a quote can terminate the generated string and inject an expression that executes when the generated client module is imported during a preview build. The injected code runs with the build process privileges and can read environment credentials, modify deployment artifacts, or make network requests. This issue is fixed in version 3.0.0.

Technical POC Analysis

CWE-94 (Improper Control of Generation of Code / Code Injection).

Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.

Executive ViewAI

Why It Matters

@tinacms/cli versions through 2.7.0 contain a code injection flaw that allows a crafted Git branch name to execute arbitrary JavaScript inside the build pipeline whenever the generated Tina client is compiled and imported. Organizations running TinaCMS preview or CI builds on Vercel, GitHub Actions, or similar platforms could expose build-time credentials and deployment artifacts to anyone able to create or influence a branch, making this a supply-chain-adjacent risk for engineering teams and the products they ship. Leadership should care because the affected credentials often include cloud, repository, and deployment secrets that extend well beyond a single project.

Business Impact: High
Compensating Controls

No vendor-released patch identified at time of analysis. Interim mitigations: restrict who can create or push branches used by preview/CI builds; disable preview builds for forked or untrusted branches; validate and allowlist branch-name characters before they reach codegen; scope and rotate build-time environment credentials to least privilege; isolate build runners with restricted outbound network egress; monitor build logs for anomalous outbound requests or artifact tampering; avoid importing the generated client in jobs triggered by untrusted branch values.

Threat Intelligence Overview

EPSS Score
0.3%
Top 85% exploitable
Prevalence
Low
niche headless CMS/CLI used by a subset of Jamstack developers
Threat Intel
1
1 source
Social Media
2
Sightings
Data Quality
6 sources
Confidence: High

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.

SignalValue
Severity HIGH
CISA KEV No
Public POC No
EPSS 0.3%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation· derived
None
System Exposure· derived
Open
Automatable· derived
No
Human Impact
High

Priority Score

41
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +41
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Code Injection CRITICAL

Code injection occurs when an application accepts user input and passes it directly into a language interpreter or evaluator without proper sanitization.

Remote Code Execution represents the critical moment when an attacker successfully runs arbitrary code on a target system without physical access.

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