# Sanitizer blocklist namespace and animation bypass

Sanitizers matching bare tag names miss namespace prefixes, SVG animate, and entity-encoded tags

_Area: Web injection and code execution. Seen in 2 disclosed reports; one confirmed bounty: $10,000; latest 2026-04-01. Updated 2026-10-27._

## How it works
A sanitizer decides safety by comparing parsed tag names against a blocklist of dangerous bare names (script, iframe, etc.). The assumption that breaks: the parser reports a *qualified* name, not the local name. Namespace-prefixed elements (`x:script`) keep their prefix in the tag field, so they never equal the blocklisted bare name and pass through [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-73g7-86qr-jrg3.md). The same assumption fails when the dangerous construct is not a tag at all but an attribute-driven animation (`<animate>` rewriting `xlink:href` to a `javascript:` URI) [E3](https://bugbountylibrary.com/r/h1%3A271007.md), or when the tag is entity-encoded inside a delimiter the downstream parser still processes [E2](https://bugbountylibrary.com/r/blog%3Asaajan-bhujel-cyou-blog-web-2022-10-16-how-i-got-10000-from-github-for-bypassing-filtration-of-html-tags.md). In each case the sanitizer inspects one representation while the browser executes another.

## Where it shows up
- Sanitizer compares `tagName`/`Data` to a list of bare local names without stripping namespace prefixes [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-73g7-86qr-jrg3.md)
- SVG output served as `image/svg+xml` with no CSP, so the XML parser resolves prefixes [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-73g7-86qr-jrg3.md)
- Markdown/math renderers that post-process delimiters (`{}`, backslash escapes) after HTML filtering [E2](https://bugbountylibrary.com/r/blog%3Asaajan-bhujel-cyou-blog-web-2022-10-16-how-i-got-10000-from-github-for-bypassing-filtration-of-html-tags.md)
- SVG animation elements (`animate`, `set`) that mutate `href`/`xlink:href` to script URIs [E3](https://bugbountylibrary.com/r/h1%3A271007.md)
- Entity-encoded tags (`&lt;tag&gt;`) surviving because only the literal leading tag was stripped [E2](https://bugbountylibrary.com/r/blog%3Asaajan-bhujel-cyou-blog-web-2022-10-16-how-i-got-10000-from-github-for-bypassing-filtration-of-html-tags.md)

## How to review
The invariant: every element and attribute that reaches the browser must be validated on its *resolved* form, not its source text. Check that the sanitizer (a) compares local names after splitting on `:`, or better, allowlists rather than blocklists; (b) treats SVG/MathML foreign content and animation attributes as untrusted; (c) runs after all decoding and delimiter expansion, not before; (d) is paired with a restrictive CSP on any endpoint returning attacker-influenced markup. Confirm the served content type and CSP for SVG-rendering endpoints [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-73g7-86qr-jrg3.md).

## Variants seen
- Namespace-prefixed tag bypassing a Go HTML5-parser blocklist in an unauthenticated SVG endpoint [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-73g7-86qr-jrg3.md)
- Backslash-escaped and entity-encoded tags smuggled through MathJax delimiters in Markdown [E2](https://bugbountylibrary.com/r/blog%3Asaajan-bhujel-cyou-blog-web-2022-10-16-how-i-got-10000-from-github-for-bypassing-filtration-of-html-tags.md)
- SVG `<animate>` with `javascript:` xlink:href in stored Markdown notes [E3](https://bugbountylibrary.com/r/h1%3A271007.md)

## Why fixes fail
E2 shows iterative patching: each fix closed one encoding/delimiter and the reporter found another, because filtering stripped the leading tag but not entity-encoded tags inside braces. Blocklist patching invites the next representation.

## Impact and severity
Reflected XSS at server origin, unauthenticated [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-73g7-86qr-jrg3.md); stored XSS executing in the app origin on note view [E3](https://bugbountylibrary.com/r/h1%3A271007.md); UI/CSS spoofing via injected HTML [E2](https://bugbountylibrary.com/r/blog%3Asaajan-bhujel-cyou-blog-web-2022-10-16-how-i-got-10000-from-github-for-bypassing-filtration-of-html-tags.md). Severity rises with origin trust, lack of CSP, and unauthenticated reachability; the $10,000 payout [E2](https://bugbountylibrary.com/r/blog%3Asaajan-bhujel-cyou-blog-web-2022-10-16-how-i-got-10000-from-github-for-bypassing-filtration-of-html-tags.md) reflects a high-trust origin.

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-73g7-86qr-jrg3.md
- E2: https://bugbountylibrary.com/r/blog%3Asaajan-bhujel-cyou-blog-web-2022-10-16-how-i-got-10000-from-github-for-bypassing-filtration-of-html-tags.md
- E3: https://bugbountylibrary.com/r/h1%3A271007.md
