From c9c9e1171b808af7f6aeb3c4c61ae1969a1b7959 Mon Sep 17 00:00:00 2001 From: eshmeshek Date: Sat, 16 May 2026 22:01:26 +0300 Subject: [PATCH] fix(1.0.6): strip Trusted Types CSP on YouTube/Google to unbreak adblocker YouTube response sends Content-Security-Policy: require-trusted-types-for 'script' which blocks the cliqz adblocker's inline-script injection used to neutralize YT's anti-adblock detection (52 "HTMLScriptElement was directly modified and will not be executed" console errors). Strip require-trusted-types-for and trusted-types directives from CSP and CSP-Report-Only headers for youtube.com / youtu.be / google.com / gmail.com (and subdomains) via onHeadersReceived on all 3 sessions. Other CSP directives stay intact so site-level security boundaries hold. Co-Authored-By: Claude Opus 4.7 (1M context) --- main.js | 34 ++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/main.js b/main.js index 148242c..e210174 100644 --- a/main.js +++ b/main.js @@ -1228,6 +1228,40 @@ app.whenReady().then(async () => { } ); + // Strip Trusted Types directives from CSP for sites that enforce them + // (YouTube, Gmail, etc.). The cliqz adblocker injects inline scriptlets to + // neutralize anti-adblock tricks; those injections use plain script.text + // assignment which TT blocks → "An HTMLScriptElement was directly modified + // and will not be executed" (52+ console errors on YouTube). Without TT + // the adblocker's scripts run and YouTube works normally. + const TT_STRIP_HOSTS = [ + 'youtube.com', 'youtu.be', 'youtubekids.com', + 'google.com', 'gmail.com', 'mail.google.com', + ]; + const stripTrustedTypes = (sess) => { + sess.webRequest.onHeadersReceived( + { urls: ['https://*/*'] }, + (details, callback) => { + let host = ''; + try { host = new URL(details.url).hostname; } catch {} + const match = TT_STRIP_HOSTS.some(d => host === d || host.endsWith('.' + d)); + const headers = details.responseHeaders; + if (!match || !headers) return callback({}); + for (const k of Object.keys(headers)) { + if (/^content-security-policy(-report-only)?$/i.test(k)) { + headers[k] = headers[k].map(v => v + .replace(/require-trusted-types-for[^;]*;?\s*/gi, '') + .replace(/trusted-types[^;]*;?\s*/gi, '')); + } + } + callback({ responseHeaders: headers }); + } + ); + }; + stripTrustedTypes(session.defaultSession); + stripTrustedTypes(getProxySession()); + stripTrustedTypes(getDirectSession()); + // Apply proxy from config before blocker tries to download filter lists loadTrustedDomainsFromDisk(); try { diff --git a/package.json b/package.json index 703328c..bf93a78 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ESH-Media", - "version": "1.0.5", + "version": "1.0.6", "private": true, "main": "main.js", "scripts": {