fix: whitelist Google/OAuth domains in adblock, spoof Sec-CH-UA brand
Two-part fix for Google login "Возможно, этот браузер небезопасны" error:
1. The adblocker was eating Google integrity-check resources (gstatic,
google-analytics, googletagmanager — flagged by EasyPrivacy). Add @@
whitelist filters for Google, Yandex, Microsoft, Apple, Facebook,
GitHub, VK, Mail.ru ecosystems. Also switch from non-existent
addFilters() to updateFromDiff({added}) — previous TMDB whitelist was
silently failing in a then().catch() and never applied. Adblock cache
bumped to v3 so the new filters take effect.
2. Sec-CH-UA client-hints branding was leaking Electron app name as the
browser brand. Override sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform
headers via webRequest.onBeforeSendHeaders on all 3 sessions so
embedded-browser detectors see real-Chrome brand list.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
67
main.js
67
main.js
@@ -7,7 +7,7 @@ const { ElectronBlocker, adsAndTrackingLists } = require('@cliqz/adblocker-elect
|
|||||||
const { autoUpdater } = require('electron-updater');
|
const { autoUpdater } = require('electron-updater');
|
||||||
|
|
||||||
const CONFIG_PATH = path.join(os.homedir(), '.ESH-Media.json');
|
const CONFIG_PATH = path.join(os.homedir(), '.ESH-Media.json');
|
||||||
const BLOCKER_CACHE_PATH = path.join(os.homedir(), '.ESH-Media-adblock-v2.bin');
|
const BLOCKER_CACHE_PATH = path.join(os.homedir(), '.ESH-Media-adblock-v3.bin');
|
||||||
const DEFAULT_TRUSTED_DOMAINS = [
|
const DEFAULT_TRUSTED_DOMAINS = [
|
||||||
// Google ecosystem (OAuth)
|
// Google ecosystem (OAuth)
|
||||||
'google.com', 'accounts.google.com', 'googleapis.com', 'googleusercontent.com',
|
'google.com', 'accounts.google.com', 'googleapis.com', 'googleusercontent.com',
|
||||||
@@ -72,8 +72,26 @@ function getBlocker() {
|
|||||||
'https://easylist-downloads.adblockplus.org/ruadlist+easylist.txt', // RuAdList
|
'https://easylist-downloads.adblockplus.org/ruadlist+easylist.txt', // RuAdList
|
||||||
];
|
];
|
||||||
const b = await ElectronBlocker.fromLists(fetchFn, [...adsAndTrackingLists, ...russianLists]);
|
const b = await ElectronBlocker.fromLists(fetchFn, [...adsAndTrackingLists, ...russianLists]);
|
||||||
// Whitelist TMDB so the movie search API is not blocked
|
// Whitelist domains that need ALL requests passed through unfiltered.
|
||||||
b.addFilters(['@@||api.themoviedb.org^', '@@||image.tmdb.org^', '@@||themoviedb.org^']);
|
// Tracking-list false positives on these break critical functionality:
|
||||||
|
// • Google: OAuth/login integrity checks fail without gstatic + analytics endpoints
|
||||||
|
// → "Возможно, этот браузер или приложение небезопасны" error
|
||||||
|
// • Yandex/Mail/Microsoft/Apple: same OAuth-style integrity flows
|
||||||
|
// • TMDB: movie search API and poster CDN
|
||||||
|
const whitelist = [
|
||||||
|
'@@||api.themoviedb.org^', '@@||image.tmdb.org^', '@@||themoviedb.org^',
|
||||||
|
'@@||google.com^', '@@||googleapis.com^', '@@||googleusercontent.com^',
|
||||||
|
'@@||gstatic.com^', '@@||youtube.com^', '@@||ytimg.com^', '@@||googlevideo.com^',
|
||||||
|
'@@||google-analytics.com^', '@@||googletagmanager.com^',
|
||||||
|
'@@||yandex.ru^', '@@||yandex.com^', '@@||yastatic.net^', '@@||mc.yandex.ru^',
|
||||||
|
'@@||github.com^', '@@||githubassets.com^', '@@||githubusercontent.com^',
|
||||||
|
'@@||vk.com^', '@@||vk.ru^', '@@||vkuser.net^',
|
||||||
|
'@@||mail.ru^', '@@||my.mail.ru^', '@@||imgsmail.ru^',
|
||||||
|
'@@||microsoft.com^', '@@||microsoftonline.com^', '@@||live.com^', '@@||office.com^',
|
||||||
|
'@@||apple.com^', '@@||icloud.com^',
|
||||||
|
'@@||facebook.com^', '@@||fbcdn.net^',
|
||||||
|
];
|
||||||
|
b.updateFromDiff({ added: whitelist });
|
||||||
fs.writeFileSync(BLOCKER_CACHE_PATH, Buffer.from(b.serialize()));
|
fs.writeFileSync(BLOCKER_CACHE_PATH, Buffer.from(b.serialize()));
|
||||||
console.log('[adblock] filter lists downloaded and cached');
|
console.log('[adblock] filter lists downloaded and cached');
|
||||||
return b;
|
return b;
|
||||||
@@ -1172,20 +1190,37 @@ app.whenReady().then(async () => {
|
|||||||
app.userAgentFallback = cleanUserAgent;
|
app.userAgentFallback = cleanUserAgent;
|
||||||
session.defaultSession.setUserAgent(cleanUserAgent);
|
session.defaultSession.setUserAgent(cleanUserAgent);
|
||||||
|
|
||||||
// Add Referer to image requests so hotlink protection doesn't block them
|
// Chrome version from the cleaned UA — used for client hints below
|
||||||
session.defaultSession.webRequest.onBeforeSendHeaders(
|
const chromeVerMatch = cleanUserAgent.match(/Chrome\/(\d+)/);
|
||||||
{ urls: ['https://*/*', 'http://*/*'] },
|
const chromeMajor = chromeVerMatch ? chromeVerMatch[1] : '128';
|
||||||
(details, callback) => {
|
const secChUa = `"Not_A Brand";v="8", "Chromium";v="${chromeMajor}", "Google Chrome";v="${chromeMajor}"`;
|
||||||
const headers = details.requestHeaders;
|
|
||||||
if (details.resourceType === 'image' && !headers['Referer'] && !headers['referer']) {
|
const installRequestHooks = (sess) => {
|
||||||
try {
|
sess.webRequest.onBeforeSendHeaders(
|
||||||
const u = new URL(details.url);
|
{ urls: ['https://*/*', 'http://*/*'] },
|
||||||
headers['Referer'] = `${u.protocol}//${u.hostname}/`;
|
(details, callback) => {
|
||||||
} catch (_) {}
|
const headers = details.requestHeaders;
|
||||||
|
// Spoof Sec-CH-UA so embedded-browser detectors (Google login, etc.) see
|
||||||
|
// a real-Chrome brand list. Electron normally injects the app name as
|
||||||
|
// the brand which is how Google fingerprints us as "embedded/unsafe".
|
||||||
|
headers['sec-ch-ua'] = secChUa;
|
||||||
|
headers['sec-ch-ua-mobile'] = '?0';
|
||||||
|
headers['sec-ch-ua-platform'] = '"Windows"';
|
||||||
|
// Add Referer to image requests so hotlink protection doesn't block them
|
||||||
|
if (details.resourceType === 'image' && !headers['Referer'] && !headers['referer']) {
|
||||||
|
try {
|
||||||
|
const u = new URL(details.url);
|
||||||
|
headers['Referer'] = `${u.protocol}//${u.hostname}/`;
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
callback({ requestHeaders: headers });
|
||||||
}
|
}
|
||||||
callback({ requestHeaders: headers });
|
);
|
||||||
}
|
};
|
||||||
);
|
|
||||||
|
installRequestHooks(session.defaultSession);
|
||||||
|
installRequestHooks(getProxySession());
|
||||||
|
installRequestHooks(getDirectSession());
|
||||||
|
|
||||||
// Apply proxy from config before blocker tries to download filter lists
|
// Apply proxy from config before blocker tries to download filter lists
|
||||||
loadTrustedDomainsFromDisk();
|
loadTrustedDomainsFromDisk();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ESH-Media",
|
"name": "ESH-Media",
|
||||||
"version": "1.0.3",
|
"version": "1.0.4",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Reference in New Issue
Block a user