Skip User-Agent spoofing on Google auth domains to fix login rejection

Google's login detects UA mismatches and blocks sign-in as "insecure."
Skip UA/Accept-Language header modification and JS navigator.userAgent
override on accounts.google.com and accounts.youtube.com. All other
fingerprint vectors (canvas, WebGL, screen, etc.) remain active.
This commit is contained in:
sal
2026-03-01 16:13:18 -06:00
parent 159cbdf5ed
commit 930814015b
2 changed files with 40 additions and 5 deletions

View File

@@ -444,12 +444,21 @@ function formatAcceptLanguage(languages) {
}).join(","); }).join(",");
} }
// Auth domains where UA spoofing breaks login flows
const AUTH_BYPASS_DOMAINS = ["accounts.google.com", "accounts.youtube.com"];
browser.webRequest.onBeforeSendHeaders.addListener( browser.webRequest.onBeforeSendHeaders.addListener(
function(details) { function(details) {
// cookieStoreId is available in Firefox 77+ webRequest details // cookieStoreId is available in Firefox 77+ webRequest details
const profile = containerProfiles[details.cookieStoreId]; const profile = containerProfiles[details.cookieStoreId];
if (!profile) return {}; if (!profile) return {};
// Skip UA spoofing on auth domains so login isn't rejected
try {
const host = new URL(details.url).hostname;
if (AUTH_BYPASS_DOMAINS.includes(host)) return {};
} catch(e) {}
const headers = details.requestHeaders; const headers = details.requestHeaders;
// Map platform to Client Hints platform name // Map platform to Client Hints platform name
const platformMap = { const platformMap = {

View File

@@ -170,6 +170,16 @@
// ========================================================================= // =========================================================================
if (vectorEnabled("navigator")) { if (vectorEnabled("navigator")) {
// Auth domains where UA spoofing breaks login — return real values there
const AUTH_BYPASS_DOMAINS = ["accounts.google.com", "accounts.youtube.com"];
const UA_PROPS = new Set(["userAgent", "appVersion", "oscpu"]);
// Capture real values before any overrides
const realNav = {};
for (const p of UA_PROPS) {
try { realNav[p] = window.navigator[p]; } catch(e) {}
}
const navOverrides = { const navOverrides = {
hardwareConcurrency: CONFIG.nav.hardwareConcurrency, hardwareConcurrency: CONFIG.nav.hardwareConcurrency,
platform: CONFIG.nav.platform, platform: CONFIG.nav.platform,
@@ -182,6 +192,21 @@
for (const [prop, value] of Object.entries(navOverrides)) { for (const [prop, value] of Object.entries(navOverrides)) {
if (value !== undefined) { if (value !== undefined) {
if (UA_PROPS.has(prop)) {
// UA-related props: return real value on auth domains
const realValue = realNav[prop];
Object.defineProperty(pageWindow.Navigator.prototype, prop, {
get: exportFunction(function() {
try {
const h = pageWindow.location.hostname;
if (AUTH_BYPASS_DOMAINS.indexOf(h) !== -1) return realValue;
} catch(e) {}
return value;
}, pageWindow),
configurable: true,
enumerable: true
});
} else {
Object.defineProperty(pageWindow.Navigator.prototype, prop, { Object.defineProperty(pageWindow.Navigator.prototype, prop, {
get: exportFunction(function() { return value; }, pageWindow), get: exportFunction(function() { return value; }, pageWindow),
configurable: true, configurable: true,
@@ -189,6 +214,7 @@
}); });
} }
} }
}
const frozenLangs = CONFIG.nav.languages; const frozenLangs = CONFIG.nav.languages;
Object.defineProperty(pageWindow.Navigator.prototype, "languages", { Object.defineProperty(pageWindow.Navigator.prototype, "languages", {