Add support to strict-block from ipaddress= option

As discussed with filter list maintainers.
This commit is contained in:
Raymond Hill 2025-08-28 11:13:43 -04:00
parent 31cd8b3983
commit 6327aae56c
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
2 changed files with 53 additions and 53 deletions

View file

@ -178,8 +178,11 @@ vAPI.webextFlavor = {
soup.add('native_css_has');
}
const extensionOrigin = browser.runtime.getURL('');
// Order of tests is important
if ( browser.runtime.getURL('').startsWith('moz-extension://') ) {
flavor.isGecko = extensionOrigin.startsWith('moz-extension://');
if ( flavor.isGecko ) {
soup.add('firefox')
.add('user_stylesheet')
.add('html_filtering');

View file

@ -39,20 +39,8 @@ import µb from './background.js';
/******************************************************************************/
// Platform-specific behavior.
// https://github.com/uBlockOrigin/uBlock-issues/issues/42
// https://bugzilla.mozilla.org/show_bug.cgi?id=1376932
// Add proper version number detection once issue is fixed in Firefox.
let dontCacheResponseHeaders =
vAPI.webextFlavor.soup.has('firefox');
// The real actual webextFlavor value may not be set in stone, so listen
// for possible future changes.
window.addEventListener('webextFlavor', function() {
dontCacheResponseHeaders =
vAPI.webextFlavor.soup.has('firefox');
}, { once: true });
// For platform-specific behavior.
const isGecko = vAPI.webextFlavor.isGecko;
/******************************************************************************/
@ -64,7 +52,7 @@ const patchLocalRedirectURL = url => url.charCodeAt(0) === 0x2F /* '/' */
// Intercept and filter web requests.
const onBeforeRequest = function(details) {
function onBeforeRequest(details) {
const fctxt = µb.filteringContext.fromWebrequestDetails(details);
// Special handling for root document.
@ -248,7 +236,7 @@ const onBeforeRootFrameRequest = function(fctxt) {
);
return { cancel: true };
};
}
/******************************************************************************/
@ -278,7 +266,7 @@ const onBeforeRootFrameRequest = function(fctxt) {
// | 2 | rg | rg | rs | rs |
// --------+--------+--------+--------+--------+--------+
const shouldStrictBlock = function(fctxt, loggerEnabled) {
function shouldStrictBlock(fctxt, loggerEnabled) {
const snfe = staticNetFilteringEngine;
// Explicit filtering: `document` option
@ -338,7 +326,7 @@ const shouldStrictBlock = function(fctxt, loggerEnabled) {
// | 2 | - | - | - | x |
// --------+--------+--------+--------+--------+--------+
return { result: rs, logData: lds };
};
}
/******************************************************************************/
@ -348,7 +336,7 @@ const shouldStrictBlock = function(fctxt, loggerEnabled) {
// Do not strict-block if the filter pattern does not contain at least one
// token character.
const validateStrictBlock = function(fctxt, logData) {
function validateStrictBlock(fctxt, logData) {
if ( typeof logData.regex !== 'string' ) { return false; }
if ( typeof logData.raw === 'string' && /\w/.test(logData.raw) === false ) {
return false;
@ -370,13 +358,13 @@ const validateStrictBlock = function(fctxt, logData) {
const end = match.index + match[0].length - hnpos - hnlen;
return end === 0 || end === 1 ||
end === 2 && url.charCodeAt(hnpos + hnlen) === 0x2E /* '.' */;
};
}
/******************************************************************************/
// Intercept and filter behind-the-scene requests.
const onBeforeBehindTheSceneRequest = function(fctxt) {
function onBeforeBehindTheSceneRequest(fctxt) {
const pageStore = µb.pageStoreFromTabId(fctxt.tabId);
if ( pageStore === null ) { return; }
@ -436,7 +424,7 @@ const onBeforeBehindTheSceneRequest = function(fctxt) {
if ( result === 1 ) {
return { cancel: true };
}
};
}
// https://github.com/uBlockOrigin/uBlock-issues/issues/1204
// Report the tabless network requests to all page stores matching the
@ -491,7 +479,7 @@ const onBeforeBehindTheSceneRequest = function(fctxt) {
// - HTML filtering (requires ability to modify response body)
// - CSP injection
const onHeadersReceived = function(details) {
function onHeadersReceived(details) {
const fctxt = µb.filteringContext.fromWebrequestDetails(details);
const isRootDoc = fctxt.itype === fctxt.MAIN_FRAME;
@ -503,6 +491,12 @@ const onHeadersReceived = function(details) {
}
if ( pageStore.getNetFilteringSwitch(fctxt) === false ) { return; }
// To enforce strict-blocking with ipaddress option
if ( isRootDoc && fctxt.ipaddress ) {
const r = onBeforeRootFrameRequest(fctxt);
if ( r ) { return ( r ); }
}
if ( (fctxt.itype & foilLargeMediaElement.TYPE_BITS) !== 0 ) {
const result = foilLargeMediaElement(details, fctxt, pageStore);
if ( result !== undefined ) { return result; }
@ -589,7 +583,7 @@ const onHeadersReceived = function(details) {
// https://github.com/uBlockOrigin/uBlock-issues/issues/229
// Use `no-cache` instead of `no-cache, no-store, must-revalidate`, this
// allows Firefox's offline mode to work as expected.
if ( modifiedHeaders && dontCacheResponseHeaders ) {
if ( modifiedHeaders && isGecko ) {
const cacheControl = µb.hiddenSettings.cacheControlForFirefox1376932;
if ( cacheControl !== 'unset' ) {
let i = headerIndexFromName('cache-control', responseHeaders);
@ -605,7 +599,7 @@ const onHeadersReceived = function(details) {
if ( modifiedHeaders ) {
return { responseHeaders };
}
};
}
const reMediaContentTypes = /^(?:audio|image|video)\/|(?:\/ogg)$/;
@ -1011,7 +1005,7 @@ const bodyFilterer = (( ) => {
/******************************************************************************/
const injectCSP = function(fctxt, pageStore, responseHeaders) {
function injectCSP(fctxt, pageStore, responseHeaders) {
const cspSubsets = [];
const requestType = fctxt.type;
@ -1138,11 +1132,11 @@ const injectCSP = function(fctxt, pageStore, responseHeaders) {
});
return true;
};
}
/******************************************************************************/
const injectPP = function(fctxt, pageStore, responseHeaders) {
function injectPP(fctxt, pageStore, responseHeaders) {
const permissions = [];
const directives = staticNetFilteringEngine.matchAndFetchModifiers(fctxt, 'permissions');
if ( directives !== undefined ) {
@ -1168,7 +1162,7 @@ const injectPP = function(fctxt, pageStore, responseHeaders) {
});
return true;
};
}
/******************************************************************************/
@ -1179,7 +1173,7 @@ const injectPP = function(fctxt, pageStore, responseHeaders) {
// cache. This works only when the webext API supports the `fromCache`
// property (Firefox).
const foilLargeMediaElement = function(details, fctxt, pageStore) {
function foilLargeMediaElement(details, fctxt, pageStore) {
if ( details.fromCache === true ) { return; }
onDemandHeaders.setHeaders(details.responseHeaders);
@ -1195,7 +1189,7 @@ const foilLargeMediaElement = function(details, fctxt, pageStore) {
}
return { cancel: true };
};
}
foilLargeMediaElement.TYPE_BITS = fc.IMAGE | fc.MEDIA | fc.XMLHTTPREQUEST;
@ -1280,6 +1274,23 @@ const strictBlockBypasser = {
/******************************************************************************/
function onResponseStarted(details) {
if ( details.tabId === -1 ) { return; }
const pageStore = µb.pageStoreFromTabId(details.tabId);
if ( pageStore === null ) { return; }
if ( pageStore.getNetFilteringSwitch() === false ) { return; }
// To enforce strict-blocking with ipaddress option
if ( isGecko === false && details.type === 'main_frame' ) {
const fctxt = µb.filteringContext.fromWebrequestDetails(details);
const r = onBeforeRootFrameRequest(fctxt);
if ( r?.cancel ) { return; }
}
details.ancestors = pageStore.getFrameAncestorDetails(details.frameId);
scriptletFilteringEngine.injectNow(details);
}
/******************************************************************************/
// https://github.com/uBlockOrigin/uBlock-issues/issues/2350
// Added scriptlet injection attempt at onResponseStarted time as per
// https://github.com/AdguardTeam/AdguardBrowserExtension/issues/1029 and
@ -1296,27 +1307,13 @@ const webRequest = {
return ( ) => {
vAPI.net.setSuspendableListener(onBeforeRequest);
vAPI.net.addListener(
'onHeadersReceived',
onHeadersReceived,
{ urls: [ 'http://*/*', 'https://*/*' ] },
[ 'blocking', 'responseHeaders' ]
);
vAPI.net.addListener(
'onResponseStarted',
details => {
if ( details.tabId === -1 ) { return; }
const pageStore = µb.pageStoreFromTabId(details.tabId);
if ( pageStore === null ) { return; }
if ( pageStore.getNetFilteringSwitch() === false ) { return; }
details.ancestors = pageStore.getFrameAncestorDetails(details.frameId);
scriptletFilteringEngine.injectNow(details);
},
{
types: [ 'main_frame', 'sub_frame' ],
urls: [ 'http://*/*', 'https://*/*' ]
}
);
vAPI.net.addListener('onHeadersReceived', onHeadersReceived, {
urls: [ 'http://*/*', 'https://*/*' ]
}, [ 'blocking', 'responseHeaders' ]);
vAPI.net.addListener('onResponseStarted', onResponseStarted, {
types: [ 'main_frame', 'sub_frame' ],
urls: [ 'http://*/*', 'https://*/*' ]
});
vAPI.defer.once({ sec: µb.hiddenSettings.toolbarWarningTimeout }).then(( ) => {
if ( vAPI.net.hasUnprocessedRequest() === false ) { return; }
vAPI.net.removeUnprocessedRequest();