feat(deps): isomorphic-dompurify for send-document preview hardening
Defense-in-depth XSS guard at the client-side preview boundary. `renderEmailBody()` already escapes-then-allowlists on the server, but mounting that output via dangerouslySetInnerHTML still exposes a single point of failure: a server-side regression in the sanitizer would silently produce a client-side XSS via the preview surface. DOMPurify sanitizes one more time before injection, with the exact allow-list `renderEmailBody` produces: <p>, <br>, <strong>, <em>, <code>, <a> (with href/target/rel, https/mailto only). Anything broader gets stripped at the DOM-injection boundary. Wrapped in useMemo so the sanitize only runs when the preview HTML changes — negligible perf, no per-render cost. The hand-rolled markdown-email.ts pipeline stays as-is: its escape-first-then-rule-replace architecture is correct and the "don't add DOMPurify as a dep at the conversion layer" reasoning in its header comment still holds. We add DOMPurify at the *consumer* boundary (preview rendering) where the threat model is "what if the server slips and emits unsafe HTML." Verified: tsc clean, vitest 1293/1293 pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -75,6 +75,7 @@
|
||||
"imapflow": "^1.3.3",
|
||||
"ioredis": "^5.10.1",
|
||||
"iso-3166-2": "^1.0.0",
|
||||
"isomorphic-dompurify": "^3.12.0",
|
||||
"jose": "^6.2.3",
|
||||
"libphonenumber-js": "^1.13.1",
|
||||
"lucide-react": "^1.14.0",
|
||||
|
||||
Reference in New Issue
Block a user