From 9ec56ac62a10979f54c056064223073b2e070773 Mon Sep 17 00:00:00 2001 From: Fabian Freund Date: Fri, 26 Sep 2025 15:36:36 +0200 Subject: [PATCH] tor ip leak protection --- .../services/proxy_settings_replication.dart | 8 +- .../src/background/BackgroundMain.ts | 107 ++++++++++-------- .../container_proxy/src/background/index.ts | 25 ++-- 3 files changed, 75 insertions(+), 65 deletions(-) diff --git a/app/lib/features/geckoview/features/browser/domain/services/proxy_settings_replication.dart b/app/lib/features/geckoview/features/browser/domain/services/proxy_settings_replication.dart index 7836f90d..c6e43c89 100644 --- a/app/lib/features/geckoview/features/browser/domain/services/proxy_settings_replication.dart +++ b/app/lib/features/geckoview/features/browser/domain/services/proxy_settings_replication.dart @@ -38,11 +38,9 @@ class ProxySettingsReplication extends _$ProxySettingsReplication { fireImmediately: true, torProxyServiceProvider.select((data) => data.value), (previous, next) async { - if (next != null) { - await ref - .read(torProxyRepositoryProvider.notifier) - .setProxyPort(next); - } + await ref + .read(torProxyRepositoryProvider.notifier) + .setProxyPort(next ?? -1); }, onError: (error, stackTrace) { logger.e( diff --git a/packages/flutter_mozilla_components/javascript/container_proxy/src/background/BackgroundMain.ts b/packages/flutter_mozilla_components/javascript/container_proxy/src/background/BackgroundMain.ts index df033ad9..4765e127 100644 --- a/packages/flutter_mozilla_components/javascript/container_proxy/src/background/BackgroundMain.ts +++ b/packages/flutter_mozilla_components/javascript/container_proxy/src/background/BackgroundMain.ts @@ -31,6 +31,7 @@ export default class BackgroundMain { this.store = store } + /* initializeAuthListener(cookieStoreId: string, proxy: HttpProxySettings | HttpsProxySettings): void { const listener: (details: _OnAuthRequiredDetails) => BlockingResponse = (details) => { if (!details.isProxy) return {} @@ -55,65 +56,71 @@ export default class BackgroundMain { ['blocking'] ) } +*/ async onRequest(requestDetails: Pick<_OnRequestDetails, 'cookieStoreId' | 'url' | 'tabId'>): Promise { - if (requestDetails.tabId > -1) { - const tab = (await browser.tabs.get(requestDetails.tabId)) + const tab = (requestDetails.tabId > -1) ? (await browser.tabs.get(requestDetails.tabId)) : null - if (this.store.hasGeneralRelation() || - tab.cookieStoreId?.startsWith(containerIdentifier) === true || - tab.cookieStoreId === privateIdentifier - ) { - try { - let cookieStoreId: string + if (this.store.hasGeneralRelation() || + tab === null || + tab.cookieStoreId?.startsWith(containerIdentifier) === true || + tab.cookieStoreId === privateIdentifier + ) { + try { + let cookieStoreId: string - if (tab.cookieStoreId?.startsWith(containerIdentifier) === true) { - cookieStoreId = tab.cookieStoreId.substring(containerIdentifier.length) - } else if (tab.cookieStoreId === privateIdentifier) { - // Handle private tabs - use 'private' as identifier - cookieStoreId = 'private' - } else { - cookieStoreId = 'general' - } + if (tab?.cookieStoreId?.startsWith(containerIdentifier) === true) { + cookieStoreId = tab.cookieStoreId.substring(containerIdentifier.length) + } else if (tab?.cookieStoreId === privateIdentifier) { + // Handle private tabs - use 'private' as identifier + cookieStoreId = 'private' + } else { + cookieStoreId = 'general' + } - const proxies = this.store.getProxiesForContainer(cookieStoreId) + let proxies = this.store.getProxiesForContainer(cookieStoreId) + if ((proxies?.length ?? 0) == 0 && tab === null) { + //When no tab is specified and general relation doesnt exist, we get all proxies to avoid leakage + proxies = this.store.getAllProxies() - if (proxies === null) { + if (proxies.length == 0) { return doNotProxy } - - if (proxies.length > 0) { - proxies.forEach(p => { - if (p.type === ProxyType.Http || p.type === ProxyType.Https) { - this.initializeAuthListener(cookieStoreId, p) - } - }) - - const result: ProxyInfo[] = proxies.filter((p: ProxySettings) => { - try { - const documentUrl = new URL(requestDetails.url) - const isLocalhost = localhosts.has(documentUrl.hostname) - if (isLocalhost && p.doNotProxyLocal) { - return false - } - } catch (e) { - console.error(e) - } - - return true - }).map(p => p.asProxyInfo()) - - if (result.length === 0) { - return [emergencyBreak] - } - return result - } - - return [emergencyBreak] - } catch (e: unknown) { - console.error(`Error in onRequest listener: ${e as string}`) - return [emergencyBreak] + } else if (proxies === null) { + return doNotProxy } + + if (proxies.length > 0) { + // proxies.forEach(p => { + // if (p.type === ProxyType.Http || p.type === ProxyType.Https) { + // this.initializeAuthListener(cookieStoreId, p) + // } + // }) + + const result: ProxyInfo[] = proxies.filter((p: ProxySettings) => { + try { + const documentUrl = new URL(requestDetails.url) + const isLocalhost = localhosts.has(documentUrl.hostname) + if (isLocalhost && p.doNotProxyLocal) { + return false + } + } catch (e) { + console.error(e) + } + + return true + }).map(p => p.asProxyInfo()) + + if (result.length === 0) { + return [emergencyBreak] + } + return result + } + + return [emergencyBreak] + } catch (e: unknown) { + console.error(`Error in onRequest listener: ${e as string}`) + return [emergencyBreak] } } diff --git a/packages/flutter_mozilla_components/javascript/container_proxy/src/background/index.ts b/packages/flutter_mozilla_components/javascript/container_proxy/src/background/index.ts index 1acf1c37..c9517680 100644 --- a/packages/flutter_mozilla_components/javascript/container_proxy/src/background/index.ts +++ b/packages/flutter_mozilla_components/javascript/container_proxy/src/background/index.ts @@ -17,16 +17,21 @@ port.onMessage.addListener((raw: unknown): void => { const message = raw as Message; switch (message.action) { case "setProxyPort": - store.putProxy(new Socks5ProxySettings({ - id: 'tor', - type: 'socks', - host: '127.0.0.1', - port: message.args, - doNotProxyLocal: true, - title: 'Tor', - proxyDNS: true, - })) - console.log('put tor port ' + message.args) + if (message.args > -1) { + store.putProxy(new Socks5ProxySettings({ + id: 'tor', + type: 'socks', + host: '127.0.0.1', + port: message.args, + doNotProxyLocal: true, + title: 'Tor', + proxyDNS: true, + })) + console.log('put tor port ' + message.args) + } else { + store.deleteProxyById('tor') + console.log('remove tor port') + } break case "addContainerProxy":