The email reader folds quoted history into <details> summaries via `_foldSummary()` (static/js/emailLibrary/signatureFold.js), which builds a sender/date "meta" chip into the summary HTML and assigns it to innerHTML. The server-side thread parser (`_extract_quote_meta`, src/email_thread_parser.py) strips tags but then un-escapes HTML entities and preserves `<...>` patterns, and that raw meta reaches `_foldSummary` unescaped via `_renderTurnsFromServer` (`t.meta`) — so an inbound email whose quoted attribution contains `From: <img src=x onerror=...>` runs script when the victim merely opens the message (stored XSS). Make `_foldSummary` the single escaping chokepoint: escape `primary` and `subMeta` with the module's existing `_esc`. The client-side `_extractQuoteMeta` previously pre-escaped its output, and every consumer of it routes through `_foldSummary`, so drop that now-redundant escaping to avoid double-encoding (e.g. "Ben & Jerry" -> "Ben &amp; Jerry"). Verified (jsdom): server-raw and client-extracted malicious metas yield 0 live elements and 0 event-handler attributes; benign "Ben & Jerry" renders single-escaped. Co-authored-by: Claude <noreply@anthropic.com>
14 KiB
14 KiB