From 31b825b183bfae702c8ceb2fa48b29a4b830cf73 Mon Sep 17 00:00:00 2001 From: Fuwn Date: Tue, 2 Jun 2026 00:25:29 +0000 Subject: fix(security): sanitize badge_wall_css server-side, render via textContent Custom badge-wall CSS was sanitised only client-side with a fragile regex and injected via innerHTML, while the stored value stayed raw. Sanitise at the write boundary instead (setCSS, covering both the REST and GraphQL paths) with a css-tree pass that parses leniently and drops @import, behavior/-moz-binding, expression()/javascript: values, and break-out attempts; render with textContent instead of innerHTML so break-out is impossible by construction (CSP already blocks inline script). css-tree stays server-only. A behaviour-gate test confirms ordinary CSS (backdrop-filter, content, url(), @media, @keyframes) is preserved while the dangerous constructs are removed. The previous regex also silently stripped all `content:` declarations; those now render correctly. --- package.json | 2 ++ 1 file changed, 2 insertions(+) (limited to 'package.json') diff --git a/package.json b/package.json index ac44767c..c6f795a5 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@sveltejs/adapter-vercel": "5.0.0", "@sveltejs/kit": "2.5.27", "@sveltejs/vite-plugin-svelte": "^4.0.0", + "@types/css-tree": "^2.3.11", "@types/fast-levenshtein": "^0.0.4", "@types/jsdom": "^21.1.6", "@types/string-similarity": "^4.0.2", @@ -57,6 +58,7 @@ "@vercel/speed-insights": "^1.0.9", "botid": "^1.5.10", "caniuse-lite": "^1.0.30001655", + "css-tree": "^3.2.1", "dexie": "^4.0.1-alpha.25", "dompurify": "^3.4.7", "effect": "4.0.0-beta.25", -- cgit v1.2.3