From 11d24abea01fdb1c7070a2940dfda6e43cfe0c2c Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Mon, 23 Mar 2020 13:31:43 -0400 Subject: [PATCH] Move proxy-detection code to Firefox-specific code Related commit: - https://github.com/uBlockOrigin/uBlock-issues/issues/911 The motivation is to avoid executing code which is unnecessary on platforms not supporting the browser.dns API. --- platform/firefox/vapi-webrequest.js | 46 ++++++++++++++++++++++++++--- src/js/storage.js | 28 +++++++----------- src/js/traffic.js | 11 ------- 3 files changed, 52 insertions(+), 33 deletions(-) diff --git a/platform/firefox/vapi-webrequest.js b/platform/firefox/vapi-webrequest.js index 08083b0bf..a7c14c24c 100644 --- a/platform/firefox/vapi-webrequest.js +++ b/platform/firefox/vapi-webrequest.js @@ -49,6 +49,27 @@ const reAsciiHostname = /^https?:\/\/[0-9a-z_.:@-]+[/?#]/; const parsedURL = new URL('about:blank'); + // Canonical name-uncloaking feature. + let cnameUncloak = browser.dns instanceof Object; + let cnameUncloakProxied = false; + + // https://github.com/uBlockOrigin/uBlock-issues/issues/911 + // We detect here whether network requests are proxied, and if so, + // de-aliasing of hostnames will be disabled to avoid possible + // DNS leaks. + const proxyDetector = function(details) { + if ( details.proxyInfo instanceof Object ) { + cnameUncloak = false; + proxyDetectorTryCount = 0; + } + if ( proxyDetectorTryCount === 0 ) { + browser.webRequest.onHeadersReceived.removeListener(proxyDetector); + return; + } + proxyDetectorTryCount -= 1; + }; + let proxyDetectorTryCount = 0; + // Related issues: // - https://github.com/gorhill/uBlock/issues/1327 // - https://github.com/uBlockOrigin/uBlock-issues/issues/128 @@ -68,13 +89,15 @@ this.cnameMaxTTL = 120; this.cnameReplayFullURL = false; this.cnameFlushTime = Date.now() + this.cnameMaxTTL * 60000; - this.cnameUncloak = browser.dns instanceof Object; } setOptions(options) { super.setOptions(options); if ( 'cnameUncloak' in options ) { - this.cnameUncloak = browser.dns instanceof Object && - options.cnameUncloak !== false; + cnameUncloak = browser.dns instanceof Object && + options.cnameUncloak !== false; + } + if ( 'cnameUncloakProxied' in options ) { + cnameUncloakProxied = options.cnameUncloakProxied === true; } if ( 'cnameIgnoreList' in options ) { this.cnameIgnoreList = @@ -100,6 +123,21 @@ } this.cnames.clear(); this.cnames.set('', ''); this.cnameFlushTime = Date.now() + this.cnameMaxTTL * 60000; + // https://github.com/uBlockOrigin/uBlock-issues/issues/911 + // Install/remove proxy detector. + const wrohr = browser.webRequest.onHeadersReceived; + if ( cnameUncloak === false || cnameUncloakProxied ) { + if ( wrohr.hasListener(proxyDetector) ) { + wrohr.removeListener(proxyDetector); + } + } else if ( wrohr.hasListener(proxyDetector) === false ) { + wrohr.addListener( + proxyDetector, + { urls: [ '*://*/*' ] }, + [ 'blocking' ] + ); + } + proxyDetectorTryCount = 32; } normalizeDetails(details) { if ( mustPunycode && !reAsciiHostname.test(details.url) ) { @@ -226,7 +264,7 @@ } onBeforeSuspendableRequest(details) { const r = super.onBeforeSuspendableRequest(details); - if ( this.cnameUncloak === false ) { return r; } + if ( cnameUncloak === false ) { return r; } if ( r !== undefined ) { if ( r.cancel === true || diff --git a/src/js/storage.js b/src/js/storage.js index bdaa9dfbf..48d767648 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -133,26 +133,18 @@ }; self.addEventListener('hiddenSettingsChanged', ( ) => { - self.log.verbosity = µBlock.hiddenSettings.consoleLogLevel; + const µbhs = µBlock.hiddenSettings; + self.log.verbosity = µbhs.consoleLogLevel; vAPI.net.setOptions({ - cnameIgnoreList: µBlock.hiddenSettings.cnameIgnoreList, - cnameIgnore1stParty: µBlock.hiddenSettings.cnameIgnore1stParty, - cnameIgnoreExceptions: µBlock.hiddenSettings.cnameIgnoreExceptions, - cnameIgnoreRootDocument: µBlock.hiddenSettings.cnameIgnoreRootDocument, - cnameMaxTTL: µBlock.hiddenSettings.cnameMaxTTL, - cnameReplayFullURL: µBlock.hiddenSettings.cnameReplayFullURL, - cnameUncloak: µBlock.hiddenSettings.cnameUncloak, + cnameIgnoreList: µbhs.cnameIgnoreList, + cnameIgnore1stParty: µbhs.cnameIgnore1stParty, + cnameIgnoreExceptions: µbhs.cnameIgnoreExceptions, + cnameIgnoreRootDocument: µbhs.cnameIgnoreRootDocument, + cnameMaxTTL: µbhs.cnameMaxTTL, + cnameReplayFullURL: µbhs.cnameReplayFullURL, + cnameUncloak: µbhs.cnameUncloak, + cnameUncloakProxied: µbhs.cnameUncloakProxied, }); - // https://github.com/uBlockOrigin/uBlock-issues/issues/911 - // See uBO's onHeadersReceived() listener. - if ( - µBlock.hiddenSettings.cnameUncloak === false || - µBlock.hiddenSettings.cnameUncloakProxied === true - ) { - µBlock.proxyDNS = false; - } else { - µBlock.proxyDNS = undefined; - } }); /******************************************************************************/ diff --git a/src/js/traffic.js b/src/js/traffic.js index ae2f0fb9a..bf4455a67 100644 --- a/src/js/traffic.js +++ b/src/js/traffic.js @@ -441,17 +441,6 @@ const onHeadersReceived = function(details) { const isRootDoc = requestType === 'main_frame'; const isDoc = isRootDoc || requestType === 'sub_frame'; - // https://github.com/uBlockOrigin/uBlock-issues/issues/911 - // We detect here whether network requests are proxied, and if so, - // de-aliasing of hostnames will be disabled to avoid possible - // DNS leaks. - if ( isRootDoc && µb.proxyDNS === undefined ) { - µb.proxyDNS = details.proxyInfo instanceof Object; - if ( µb.proxyDNS ) { - vAPI.net.setOptions({ cnameUncloak: false }); - } - } - let pageStore = µb.pageStoreFromTabId(fctxt.tabId); if ( pageStore === null ) { if ( isRootDoc === false ) { return; }