fix(security): Tracking-Pixel-Blocker lässt Backslash-Varianten von https:// durch

EXTERNAL_URL_RE verlangte zwei Forward-Slashes, aber der WHATWG-URL-Parser
akzeptiert für http(s) auch Backslash als Authority-Slash: "https:/\/evil.com"
und "https:\\evil.com" lösen im Browser identisch zu "https://evil.com" auf,
wurden vom PROJ-76-Fix aber nicht erkannt. Ein Tracking-Pixel mit dieser
Schreibweise hätte trotz aktivierter Blockierung geladen und dem Absender
eine Lesebestätigung samt IP verraten.

Gefunden durch Security-Review der heutigen Session-Commits.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019j28kGcaJAhBnrYX34hGdt
This commit is contained in:
sysops
2026-08-05 21:45:20 +02:00
co-authored by Claude Sonnet 5
parent edf6f430df
commit 5c3d38ae65
+5 -1
View File
@@ -81,7 +81,11 @@ function triggerDownload(blob: Blob, filename: string) {
// pixel") to the sender. Covers src=, srcset=, background=, <link href=> and // pixel") to the sender. Covers src=, srcset=, background=, <link href=> and
// CSS url() in <style> blocks / style= attributes. data:- and cid:-URIs stay // CSS url() in <style> blocks / style= attributes. data:- and cid:-URIs stay
// untouched so inline/archived content keeps rendering. // untouched so inline/archived content keeps rendering.
const EXTERNAL_URL_RE = /^\s*(?:https?:)?\/\//i; // Matches http(s): schemes and protocol-relative URLs. WHATWG's URL parser
// treats backslashes as authority slashes for special schemes too, so
// "https:/\/evil.com" and "https:\\evil.com" resolve exactly like
// "https://evil.com" in a real browser and must be caught as well.
const EXTERNAL_URL_RE = /^\s*(?:https?\s*:|[/\\]\s*[/\\])/i;
// Tags whose src= attribute triggers a network request. // Tags whose src= attribute triggers a network request.
const SRC_TAGS = new Set(["img", "video", "audio", "source"]); const SRC_TAGS = new Set(["img", "video", "audio", "source"]);