diff --git a/platform/mv3/extension/js/popup.js b/platform/mv3/extension/js/popup.js index 1633425c7..31ee7b39e 100644 --- a/platform/mv3/extension/js/popup.js +++ b/platform/mv3/extension/js/popup.js @@ -310,7 +310,7 @@ async function init() { const { rules, filters, css } = details; let ruleCount = rules.plain + rules.regex; if ( popupPanelData.hasOmnipotence ) { - ruleCount += rules.removeparam + rules.redirect + rules.csp; + ruleCount += rules.removeparam + rules.redirect + rules.modifyHeaders; } let specificCount = 0; if ( typeof css.specific === 'number' ) { diff --git a/platform/mv3/extension/js/ruleset-manager.js b/platform/mv3/extension/js/ruleset-manager.js index fd25320b8..8e3b7e1c0 100644 --- a/platform/mv3/extension/js/ruleset-manager.js +++ b/platform/mv3/extension/js/ruleset-manager.js @@ -38,8 +38,8 @@ const REMOVEPARAMS_REALM_START = REGEXES_REALM_END; const REMOVEPARAMS_REALM_END = REMOVEPARAMS_REALM_START + RULE_REALM_SIZE; const REDIRECT_REALM_START = REMOVEPARAMS_REALM_END; const REDIRECT_REALM_END = REDIRECT_REALM_START + RULE_REALM_SIZE; -const CSP_REALM_START = REDIRECT_REALM_END; -const CSP_REALM_END = CSP_REALM_START + RULE_REALM_SIZE; +const MODIFYHEADERS_REALM_START = REDIRECT_REALM_END; +const MODIFYHEADERS_REALM_END = MODIFYHEADERS_REALM_START + RULE_REALM_SIZE; const TRUSTED_DIRECTIVE_BASE_RULE_ID = 8000000; /******************************************************************************/ @@ -326,7 +326,7 @@ async function updateRedirectRules() { /******************************************************************************/ -async function updateCspRules() { +async function updateModifyHeadersRules() { const [ hasOmnipotence, rulesetDetails, @@ -337,36 +337,36 @@ async function updateCspRules() { getDynamicRules(), ]); - // Fetch csp rules for all enabled rulesets + // Fetch modifyHeaders rules for all enabled rulesets const toFetch = []; for ( const details of rulesetDetails ) { - if ( details.rules.csp === 0 ) { continue; } - toFetch.push(fetchJSON(`/rulesets/csp/${details.id}`)); + if ( details.rules.modifyHeaders === 0 ) { continue; } + toFetch.push(fetchJSON(`/rulesets/modify-headers/${details.id}`)); } - const cspRulesets = await Promise.all(toFetch); + const rulesets = await Promise.all(toFetch); // Redirect rules can only be enforced with omnipotence const newRules = []; if ( hasOmnipotence ) { - let cspRuleId = CSP_REALM_START; - for ( const rules of cspRulesets ) { + let ruleId = MODIFYHEADERS_REALM_START; + for ( const rules of rulesets ) { if ( Array.isArray(rules) === false ) { continue; } for ( const rule of rules ) { - rule.id = cspRuleId++; + rule.id = ruleId++; newRules.push(rule); } } } - // Add csp rules to dynamic ruleset without affecting rules - // outside csp rules realm. + // Add modifyHeaders rules to dynamic ruleset without affecting rules + // outside modifyHeaders realm. const newRuleMap = new Map(newRules.map(rule => [ rule.id, rule ])); const addRules = []; const removeRuleIds = []; for ( const oldRule of dynamicRuleMap.values() ) { - if ( oldRule.id < CSP_REALM_START ) { continue; } - if ( oldRule.id >= CSP_REALM_END ) { continue; } + if ( oldRule.id < MODIFYHEADERS_REALM_START ) { continue; } + if ( oldRule.id >= MODIFYHEADERS_REALM_END ) { continue; } const newRule = newRuleMap.get(oldRule.id); if ( newRule === undefined ) { removeRuleIds.push(oldRule.id); @@ -387,10 +387,10 @@ async function updateCspRules() { if ( addRules.length === 0 && removeRuleIds.length === 0 ) { return; } if ( removeRuleIds.length !== 0 ) { - ubolLog(`Remove ${removeRuleIds.length} DNR csp rules`); + ubolLog(`Remove ${removeRuleIds.length} DNR modifyHeaders rules`); } if ( addRules.length !== 0 ) { - ubolLog(`Add ${addRules.length} DNR csp rules`); + ubolLog(`Add ${addRules.length} DNR modifyHeaders rules`); } return dnr.updateDynamicRules({ addRules, removeRuleIds }); @@ -405,7 +405,7 @@ async function updateDynamicRules() { updateRegexRules(), updateRemoveparamRules(), updateRedirectRules(), - updateCspRules(), + updateModifyHeadersRules(), ]); } diff --git a/platform/mv3/extension/js/settings.js b/platform/mv3/extension/js/settings.js index d0111791d..3afb1f79b 100644 --- a/platform/mv3/extension/js/settings.js +++ b/platform/mv3/extension/js/settings.js @@ -46,7 +46,7 @@ function rulesetStats(rulesetId) { const { rules, filters } = rulesetDetails; let ruleCount = rules.plain + rules.regex; if ( hasOmnipotence ) { - ruleCount += rules.removeparam + rules.redirect + rules.csp; + ruleCount += rules.removeparam + rules.redirect + rules.modifyHeaders; } const filterCount = filters.accepted; return { ruleCount, filterCount }; diff --git a/platform/mv3/make-rulesets.js b/platform/mv3/make-rulesets.js index 4c1f27959..15db7d9f5 100644 --- a/platform/mv3/make-rulesets.js +++ b/platform/mv3/make-rulesets.js @@ -228,7 +228,7 @@ const isRedirect = rule => rule.action.type === 'redirect' && rule.action.redirect.extensionPath !== undefined; -const isCsp = rule => +const isModifyHeaders = rule => rule.action !== undefined && rule.action.type === 'modifyHeaders'; @@ -240,7 +240,7 @@ const isRemoveparam = rule => const isGood = rule => isUnsupported(rule) === false && isRedirect(rule) === false && - isCsp(rule) === false && + isModifyHeaders(rule) === false && isRemoveparam(rule) === false; /******************************************************************************/ @@ -298,11 +298,11 @@ async function processNetworkFilters(assetDetails, network) { ); log(`\tremoveparams= (accepted/discarded): ${removeparamsGood.length}/${removeparamsBad.length}`); - const csps = rules.filter(rule => + const modifyHeaders = rules.filter(rule => isUnsupported(rule) === false && - isCsp(rule) + isModifyHeaders(rule) ); - log(`\tcsp=: ${csps.length}`); + log(`\tmodifyHeaders=: ${modifyHeaders.length}`); const bad = rules.filter(rule => isUnsupported(rule) @@ -336,10 +336,10 @@ async function processNetworkFilters(assetDetails, network) { ); } - if ( csps.length !== 0 ) { + if ( modifyHeaders.length !== 0 ) { writeFile( - `${rulesetDir}/csp/${assetDetails.id}.json`, - `${JSON.stringify(csps, replacer, 1)}\n` + `${rulesetDir}/modify-headers/${assetDetails.id}.json`, + `${JSON.stringify(modifyHeaders, replacer, 1)}\n` ); } @@ -351,7 +351,7 @@ async function processNetworkFilters(assetDetails, network) { regex: regexes.length, removeparam: removeparamsGood.length, redirect: redirects.length, - csp: csps.length, + modifyHeaders: modifyHeaders.length, }; } @@ -966,7 +966,7 @@ async function rulesetFromURLs(assetDetails) { regex: netStats.regex, removeparam: netStats.removeparam, redirect: netStats.redirect, - csp: netStats.csp, + modifyHeaders: netStats.modifyHeaders, discarded: netStats.discarded, rejected: netStats.rejected, }, diff --git a/src/js/static-net-filtering.js b/src/js/static-net-filtering.js index 578480a0b..cc4438c20 100644 --- a/src/js/static-net-filtering.js +++ b/src/js/static-net-filtering.js @@ -4441,6 +4441,17 @@ FilterContainer.prototype.dnrFromCompiled = function(op, context, ...args) { dnrAddRuleError(rule, 'Unsupported modifier exception'); } break; + case 'permissions': + rule.action.type = 'modifyHeaders'; + rule.action.responseHeaders = [{ + header: 'permissions-policy', + operation: 'append', + value: rule.__modifierValue.split('|').join(', '), + }]; + if ( rule.__modifierAction === AllowAction ) { + dnrAddRuleError(rule, 'Unsupported modifier exception'); + } + break; case 'redirect-rule': { let priority = rule.priority || 1; let token = rule.__modifierValue;