Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
PR:L because editor authentication is required; S:C because stored XSS crosses to victim browsers; no availability impact.
Primary rating from Vendor (https://github.com/tinacms/tinacms).
CVSS VectorVendor: https://github.com/tinacms/tinacms
Lifecycle Timeline
3Blast Radius
ecosystem impact- 7 npm packages depend on @tinacms/mdx (3 direct, 4 indirect)
- 3 npm packages depend on tinacms (3 direct, 0 indirect)
Ecosystem-wide dependent count for version 2.1.7 and other introduced versions.
DescriptionCVE.org
TinaCMS rich-text parsing and the default link/image renderers did not sanitize the url field on Slate link/image nodes. Content containing javascript: or data:text/html URLs - including case-variant, whitespace-padded, and control-character-obfuscated forms - is rendered into href/src and executes when the content is viewed. Any actor able to author rich-text content (for example a lower-privileged editor, or imported/external content) can achieve stored XSS against editors and site viewers.
Fixed in https://github.com/tinacms/tinacms/pull/7056 via a sanitizeUrl() helper (case-insensitive, whitespace/control-character-normalized scheme allow-list) applied recursively to Slate trees at parse time and in the default rich-text rendering.
AnalysisAI
Stored XSS in TinaCMS rich-text rendering allows any content author with editor-level access to inject javascript: or data:text/html URLs into Slate link/image nodes, which execute in the browsers of editors and site visitors when affected content is viewed. Both tinacms (< 3.9.3) and @tinacms/mdx (< 2.1.7) are confirmed affected, with the vulnerable path covering case-variant, whitespace-padded, and control-character-obfuscated scheme bypass techniques indicating deliberate evasion of naive sanitization. No public exploit or CISA KEV listing exists; vendor-released patches are available.
Technical ContextAI
TinaCMS uses Slate.js as its rich-text editor framework, serializing editor content as 'slatejson' - a recursive node tree where link and image nodes carry a url field. The @tinacms/mdx package (pkg:npm/@tinacms/mdx) handles parsing this Slate tree and provides the default link/image renderers. Prior to the fix, neither the parser nor the renderers validated the URL scheme, so values like javascript:alert(1), JAVASCRIPT:alert(1) (case bypass), leading-whitespace variants, or control-character-embedded strings passed directly into href and src HTML attributes. The root cause is CWE-79 (Improper Neutralization of Input During Web Page Generation - XSS), specifically a stored variant: the malicious payload persists in the CMS content store and fires on every subsequent render, affecting any user who views the page.
RemediationAI
Upgrade tinacms to version 3.9.3 or later and @tinacms/mdx to version 2.1.7 or later via npm; both patched versions are introduced in PR #7056 (https://github.com/tinacms/tinacms/pull/7056). The fix adds a sanitizeUrl() helper that lowercases, strips whitespace and control characters from URL schemes, and rejects any scheme not on an explicit allow-list; it is applied recursively to Slate trees at parse time and in the default rich-text renderers. If an immediate upgrade is not feasible, restrict rich-text content authoring strictly to fully trusted users and disable or quarantine any content import pipelines that ingest external Slate JSON or markdown - these pipelines represent the highest-risk injection path. Any custom rich-text renderer that overrides the default link or image components must apply equivalent URL scheme sanitization independently, as the fix does not retroactively harden downstream renderer overrides. See the full advisory at https://github.com/tinacms/tinacms/security/advisories/GHSA-2vcc-5v34-9jc8.
Same weakness CWE-79 – Cross-site Scripting (XSS)
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-41141
GHSA-2vcc-5v34-9jc8