fix: address review #4 — board name invalidation, SVG tests, test gaps

- Pass board.name to all invalidateBoardCache calls (permission mutations)
- Align integration create invalidation with update/delete
- Add initial-fetch-failure test for integration-data-cache
- Expand SVG XSS test corpus (javascript:, xlink:href, @import, onbegin)
- Forbid <style> tags in SVG sanitizer to prevent CSS injection
- Fix duplicate export in packages/common/src/index.ts
This commit is contained in:
Thomas Camlong committed 2026-08-07 19:18:18 +02:00
1 parent 4361c8dbe2
commit 451dc3ce39
7 files changed
+58 -5

No files matched your search

@@ -41,4 +41,29 @@ describe("SVG sanitization", () => {
const wrapped = `<html><body>${dirty}</body></html>`;
expect(sanitizeSvg(dirty)).toBe(purify.sanitize(wrapped, svgSanitizeOptions));
});
it("strips javascript: protocol in href", () => {
const dirty = '<svg><a href="javascript:alert(1)"><text>click</text></a></svg>';
const clean = sanitizeSvg(dirty);
expect(clean).not.toContain("javascript:");
});
it("strips xlink:href with javascript:", () => {
const dirty = '<svg><a xlink:href="javascript:alert(1)"><text>click</text></a></svg>';
const clean = sanitizeSvg(dirty);
expect(clean).not.toContain("javascript:");
});
it("strips style with url() import", () => {
const dirty =
'<svg><style>@import url("https://evil.com/steal.css");</style><rect width="100" height="100"/></svg>';
const clean = sanitizeSvg(dirty);
expect(clean).not.toContain("@import");
});
it("strips animate with onbegin handler", () => {
const dirty = '<svg><animate onbegin="alert(1)"/></svg>';
const clean = sanitizeSvg(dirty);
expect(clean).not.toContain("onbegin");
});
});
@@ -3,6 +3,7 @@ import { parseHTML } from "linkedom";
const svgSanitizeOptions = {
USE_PROFILES: { svg: true, svgFilters: true },
FORBID_TAGS: ["style"],
} as const;
// ponytail: linkedom stores DOM tree pointers as own value properties; DOMPurify