@ASTROJS/PRISM · GHSA-ff38-p3qj-4pmf · Package
FIX → 4.1.2 · 2.1.2
Code blocks with a language Prism does not support are inserted into the page as raw HTML instead of escaped text. An attacker who can write content, such as a CMS editor or outside contributor on a Markdoc site, can run scripts for every visitor.
first public Oct 28, 2026 · 1 source
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Sites built with Astro that use the <Prism /> component with untrusted or user-controlled lang values, or the prism() extension in Markdoc where content comes from less-trusted authors. Markdoc does not render HTML by default, but the Prism fallback bypasses that setting inside code fences. Sites using Shiki, Markdown-only content from trusted authors, or only supported Prism languages are not affected.
Not affected if shiki-highlighting, supported-languages-only, trusted-authors
Who cares astro, cms, markdoc, prism, static-sites
@astrojs/prism with npm ls @astrojs/prism and of @astrojs/markdoc with .@astrojs/prism did not escape code when the requested language was not supported by Prism. runHighlighterWithAstro() only HTML-escaped code through Prism.highlight() when a grammar was found. For any unsupported language, it returned the original code unchanged, and every caller inserted that result into the page as raw HTML.
As a result, a code block with an unsupported language label, including common labels such as vue, svelte, mdx, console, or text, was rendered as live HTML instead of displayed as code.
The affected fallback is in packages/astro-prism/src/highlighter.ts:
const grammar = Prism.languages[lang];
let html = code;
(grammar) {
html = .(code, grammar, lang);
}
Check it with your coding agent
It reads this page and tells you if your code is affected.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
npm ls @astrojs/markdoc<Prism /> component with untrusted code or user-controlled lang props.prism() extension in the Markdoc config.Upgrade to 4.1.2 · 2.1.2
@astrojs/prism: 4.1.2@astrojs/markdoc: 2.1.2The returned html is rendered without further escaping by:
<Prism /> component in @astrojs/prism, through set:html.prism() syntax highlighting extension in @astrojs/markdoc (@astrojs/markdoc/prism), for every code fence.Supported languages, and code blocks with no language (which default to plaintext), were escaped correctly.
Affected applications could be vulnerable to stored cross-site scripting.
allowHTML: false). On sites that use the prism() extension, a content author could get around this by placing HTML inside a code fence with an unsupported language. The HTML and JavaScript would then be rendered and executed on the site's origin for every visitor. This matters for sites where Markdoc content is written by people who cannot otherwise add HTML or code to the site, such as CMS editors or outside contributors.<Prism /> component: Applications that pass untrusted input to the code prop together with an unsupported or user-controlled lang were vulnerable in the same way.Markdown and MDX content highlighted with markdown.syntaxHighlight: 'prism' goes through the same fallback. This does not add new capability there, because Markdown and MDX already allow raw HTML.
Fixed in @astrojs/prism 4.1.2 and @astrojs/markdoc 2.1.2. Code is now escaped when no Prism grammar is available, so unsupported languages are displayed as plain text.
shiki() extension for Markdoc).<Prism /> component, or HTML-escape untrusted code before passing it in.prism() extension until a patched version is available.Reported by @oss-security-shopify.