diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..1cfa9cf --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,5 @@ +## 2024-06-30 - Replace dangerouslySetInnerHTML with Sandboxed iframe for Untrusted HTML + +**Vulnerability:** Used `dangerouslySetInnerHTML` to render dynamic, untrusted email HTML within a React component. +**Learning:** Even when using a library like `DOMPurify` to sanitize HTML, rendering it directly into the main application document using `dangerouslySetInnerHTML` carries inherent risk. If the sanitizer fails to catch a novel exploit, is misconfigured, or if the sanitization rules change over time, the application is completely exposed to XSS, which can lead to session hijacking and unauthorized actions within the primary app context. +**Prevention:** For untrusted or dynamic HTML (like email previews), always use a sandboxed `iframe` with the `srcDoc` attribute to create an isolated browsing context. Apply `sandbox="allow-popups allow-popups-to-escape-sandbox"` to permit expected interactions (like clicking links) while omitting `allow-scripts` and `allow-same-origin`. Because the iframe is isolated, external CSS (like Tailwind classes) won't apply to its contents; any necessary styling must be explicitly injected via an inline ` + + + ${sanitizedEmailHtml} + + + `; + }, [sanitizedEmailHtml]); const pdfHref = report ? `/api/runtime/organizations/${orgSlug}/accounts/${accountId}/ppp-savings/pdf?year=${report.year}` : null; @@ -232,8 +255,13 @@ export function PppSavingsPanel({ orgSlug, accountId }: PppSavingsPanelProps) { )} -
-
+
+