From 692577bbde5e8110855c022ec913324dfddce9ae Mon Sep 17 00:00:00 2001 From: jahoti Date: Fri, 16 Jul 2021 00:00:00 +0000 Subject: Use URL-based policy smuggling Increase the power of URL-based smuggling by making it (effectively) compulsory in all cases and adapting a structure. While the details still need to be worked out, the potential for future expansion is there. --- background/policy_injector.js | 52 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) (limited to 'background') diff --git a/background/policy_injector.js b/background/policy_injector.js index eb67963..9e8ed61 100644 --- a/background/policy_injector.js +++ b/background/policy_injector.js @@ -2,6 +2,7 @@ * Myext injecting policy to page using webRequest * * Copyright (C) 2021 Wojtek Kosior + * Copyright (C) 2021 jahoti * Redistribution terms are gathered in the `copyright' file. */ @@ -12,7 +13,9 @@ * IMPORT browser * IMPORT is_chrome * IMPORT gen_unique + * IMPORT gen_nonce * IMPORT url_item + * IMPORT url_extract_policy * IMPORT get_query_best * IMPORT csp_rule * IMPORTS_END @@ -39,18 +42,46 @@ function is_our_header(header, rule) return header.value === rule } -function inject(details) +function url_inject(details) { - const url = url_item(details.url); + const targets = url_extract_policy(details.url); + if (targets.policy) { + return; + } else if (targets.signed) { + /* Redirect; update policy */ + targets.target = targets.target2; + delete targets.target2 + } + + let redirect_url = targets.base_url + targets.sig; + let [pattern, settings] = query_best(targets.base_url); + if (!pattern) + /* Defaults */ + settings = {}; + + const policy = {allow: settings.allow, nonce: gen_nonce()}; + + redirect_url += encodeURIComponent(JSON.stringify(policy)); + if (targets.target) + redirect_url += targets.target; + if (targets.target2) + redirect_url += targets.target2; + + return {redirectUrl: redirect_url}; +} - const [pattern, settings] = query_best(url); +function inject(details) +{ + const targets = url_extract_policy(details.url); + if (!targets.policy) + /* Block unsigned requests */ + return {cancel: true}; - const nonce = gen_unique(url); - const rule = csp_rule(nonce); + const rule = csp_rule(targets.policy.nonce); var headers; - if (settings !== undefined && settings.allow) { + if (targets.policy.allow) { /* * Chrome doesn't have the buggy behavior of repeatedly injecting a * header we injected once. Firefox does and we have to remove it there. @@ -80,6 +111,15 @@ async function start_policy_injector() if (is_chrome) extra_opts.push("extraHeaders"); + browser.webRequest.onBeforeRequest.addListener( + url_inject, + { + urls: [""], + types: ["main_frame", "sub_frame"] + }, + ["blocking"] + ); + browser.webRequest.onHeadersReceived.addListener( inject, { -- cgit v1.2.3