mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-09-06 07:57:04 +08:00
feat: add setting to disable auto-loading external images in emails (#1092)
* feat: add setting to disable auto-loading external images in emails Adds a privacy setting (default off) that blocks remote images in email content until the user explicitly loads them per message. Blocked images are replaced with a placeholder; a banner allows one-click loading. Closes #1073 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(frontend): block remote content with DOMPurify and an allowlist policy Address review on the blocking logic. The first pass matched quoted `<img src="http...">` with a regex, which left unquoted src, srcset, `<source>`, CSS background-image, SVG `<image href>` and entity-encoded schemes fetching as usual, and replaced only `src` on an element that also carried `srcset` -- so the browser still had a remote candidate to prefer while the UI claimed the image was blocked. Two changes rather than a wider regex: Sanitising is delegated to DOMPurify, which is already a dependency. The hard part here is not enumerating attributes but surviving the parser: a hand-written pass over a DOMParser tree still missed that `<noscript>` is parsed as markup where scripting is off and as raw text where it is on, so a `</noscript>` smuggled into an attribute value reopens the document at render time and revives an `<img>` the cleaner never saw. Elements that fetch by themselves or change how relative URLs resolve -- base, meta, script, link, iframe, object, embed, noscript -- are dropped in this mode. `<style>` is kept so layout survives, with its url(), image-set() and @import references filtered. URL classification is an allowlist. Asking "does this look remote?" means enumerating every disguise -- backslash authorities, tab/newline/control characters the URL parser strips, CSS escapes, schemes with no slashes -- and losing to the first one not thought of. Asking "can I prove this is local?" fails closed instead: cid:, data:image/, blob: and relative paths are kept, everything else is blocked. Relative paths are only safe because `<base>` is removed, which is what stopped it re-pointing them at a tracker. The blocked URL is discarded rather than parked in a data-* attribute, so "the cleaned body contains no remote URL at all" is directly assertable; restoring images re-renders from the untouched source. Also: blob: is added to the allowed schemes -- DOMPurify's default list omits it, and email-parser rewrites cid: attachments into blob: URLs, so without it every inline image would be stripped along with the trackers. The policy lives in its own module with its own tests (30 attack vectors, 7 preservation cases); email-parser.js goes back to MIME parsing only. The per-mail override no longer initialises from the global setting, and the banner reports the blocked count as the PR description promised. Refs #1073 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
342fe22e4f
commit
e499211197
@@ -12,6 +12,7 @@
|
||||
|
||||
- feat: |Frontend| Add a "Full-width mailbox list view" toggle in Appearance settings. When enabled, the mailbox shows a full-width list of subjects and body previews by default; clicking a mail expands it into the two-pane split view, clicking the same mail again returns to the list view; in multi-select mode, clicking a mail updates both its checked state and the right-side preview while disabling same-mail collapse, and the split width still follows the "Left list width in two-column mailbox view" setting. Defaults to off, preserving the original two-pane behavior
|
||||
- feat: |Frontend| Add "Body Preview Lines" in Appearance settings for the full-width mailbox list view, allowing runtime control over the body-preview clamp. It defaults to 2 lines, and 0 disables previews
|
||||
- feat: |Frontend| Add an "Automatically load external images in mail body" toggle in Appearance settings. When disabled, the mail body (including fullscreen view) is run through DOMPurify and an allowlist policy: only references that can be *proven* local are kept (`cid:`, `data:image/`, `blob:` and same-origin relative paths), everything else is blocked. Elements that fetch on their own or change how relative URLs resolve — `base`, `meta`, `script`, `link`, `iframe`, `object`, `embed`, `noscript` — are removed in this mode, while `<style>` is kept with remote `url()`, `image-set()` and `@import` references substituted. A banner above the body reports how many resources were blocked and loads them for that mail on demand; defaults to on, preserving the previous behavior (issue #1073)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user