[mv3] Properly distinguish trust level when compiling scriptlets

Since in uBOL filter lists from various sources are combined into
a single list, there must be a way to turn on/off trust level
inside the resulting combined filter list so as to be able to
validate the trust level of filters requiring trust.

This commit adds new parser directives understood only by MV3
compiler to turn on/off trust flag internally.
This commit is contained in:
Raymond Hill 2023-06-23 08:27:07 -04:00
parent ea4afc0610
commit 7ba85472d7
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
3 changed files with 28 additions and 6 deletions

View file

@ -27,7 +27,7 @@ import fs from 'fs/promises';
import https from 'https';
import path from 'path';
import process from 'process';
import { createHash } from 'crypto';
import { createHash, randomBytes } from 'crypto';
import redirectResourcesMap from './js/redirect-resources.js';
import { dnrRulesetFromRawLists } from './js/static-dnr-filtering.js';
import * as sfp from './js/static-filtering-parser.js';
@ -182,6 +182,9 @@ async function fetchAsset(assetDetails) {
continue;
}
fetchedURLs.add(part.url);
if ( part.url.startsWith('https://ublockorigin.github.io/uAssets/filters/') ) {
newParts.push(`!#trusted on ${assetDetails.secret}`);
}
newParts.push(
fetchList(part.url, cacheDir).then(details => {
const { url } = details;
@ -198,6 +201,7 @@ async function fetchAsset(assetDetails) {
return { url, content: '' };
})
);
newParts.push(`!#trusted off ${assetDetails.secret}`);
}
parts = await Promise.all(newParts);
parts = sfp.utils.preparser.expandIncludes(parts, env);
@ -808,7 +812,7 @@ async function processScriptletFilters(assetDetails, mapin) {
makeScriptlet.init();
for ( const details of mapin.values() ) {
makeScriptlet.compile(details, assetDetails.isTrusted);
makeScriptlet.compile(details);
}
const stats = await makeScriptlet.commit(
assetDetails.id,
@ -851,7 +855,7 @@ async function rulesetFromURLs(assetDetails) {
const results = await dnrRulesetFromRawLists(
[ { name: assetDetails.id, text: assetDetails.text } ],
{ env, extensionPaths }
{ env, extensionPaths, secret: assetDetails.secret }
);
const netStats = await processNetworkFilters(
@ -975,6 +979,10 @@ async function main() {
JSON.parse(text)
);
// This will be used to sign our inserted `!#trusted on` directives
const secret = createHash('sha256').update(randomBytes(16)).digest('hex').slice(0,16);
log(`Secret: ${secret}`);
// Assemble all default lists as the default ruleset
const contentURLs = [
'https://ublockorigin.github.io/uAssets/filters/filters.min.txt',
@ -991,9 +999,9 @@ async function main() {
id: 'default',
name: 'Ads, trackers, miners, and more' ,
enabled: true,
secret,
urls: contentURLs,
homeURL: 'https://github.com/uBlockOrigin/uAssets',
isTrusted: true,
});
// Regional rulesets
@ -1063,6 +1071,7 @@ async function main() {
name: 'EasyList/uBO Cookie Notices',
group: 'annoyances',
enabled: false,
secret,
urls: [
'https://ublockorigin.github.io/uAssets/thirdparties/easylist-cookies.txt',
'https://ublockorigin.github.io/uAssets/filters/annoyances-cookies.txt',
@ -1074,6 +1083,7 @@ async function main() {
name: 'AdGuard/uBO Overlays',
group: 'annoyances',
enabled: false,
secret,
urls: [
'https://filters.adtidy.org/extension/ublock/filters/19.txt',
'https://ublockorigin.github.io/uAssets/filters/annoyances-others.txt',

View file

@ -78,7 +78,7 @@ export function reset() {
/******************************************************************************/
export function compile(details, isTrusted) {
export function compile(details) {
if ( details.args[0].endsWith('.js') === false ) {
details.args[0] += '.js';
}
@ -88,7 +88,7 @@ export function compile(details, isTrusted) {
const scriptletToken = details.args[0];
const resourceEntry = resourceDetails.get(scriptletToken);
if ( resourceEntry === undefined ) { return; }
if ( resourceEntry.requiresTrust && isTrusted !== true ) {
if ( resourceEntry.requiresTrust && details.isTrusted !== true ) {
console.log(`Rejecting ${scriptletToken}: source is not trusted`);
return;
}

View file

@ -122,6 +122,9 @@ function addExtendedToDNR(context, parser) {
let details = context.scriptletFilters.get(argsToken);
if ( details === undefined ) {
context.scriptletFilters.set(argsToken, details = { args });
if ( context.isTrusted ) {
details.isTrusted = true;
}
}
if ( not ) {
if ( details.excludeMatches === undefined ) {
@ -247,6 +250,15 @@ function addToDNR(context, list) {
parser.parse(line);
if ( parser.isComment() ) {
if ( line === `!#trusted on ${context.secret}` ) {
context.isTrusted = true;
} else if ( line === `!#trusted off ${context.secret}` ) {
context.isTrusted = false;
}
continue;
}
if ( parser.isFilter() === false ) { continue; }
if ( parser.hasError() ) { continue; }