aboutsummaryrefslogtreecommitdiff
path: root/background/policy_injector.js
diff options
context:
space:
mode:
Diffstat (limited to 'background/policy_injector.js')
-rw-r--r--background/policy_injector.js149
1 files changed, 54 insertions, 95 deletions
diff --git a/background/policy_injector.js b/background/policy_injector.js
index f58fb71..9725e99 100644
--- a/background/policy_injector.js
+++ b/background/policy_injector.js
@@ -16,36 +16,32 @@
* IMPORT gen_unique
* IMPORT gen_nonce
* IMPORT is_privileged_url
+ * IMPORT url_item
* IMPORT url_extract_target
* IMPORT sign_policy
- * IMPORT get_query_best
- * IMPORT parse_csp
+ * IMPORT query_best
+ * IMPORT sanitize_csp_header
* IMPORTS_END
*/
var storage;
-var query_best;
-
-const csp_header_names = {
- "content-security-policy" : true,
- "x-webkit-csp" : true,
- "x-content-security-policy" : true
-};
-
-const unwanted_csp_directives = {
- "report-to" : true,
- "report-uri" : true,
- "script-src" : true,
- "script-src-elem" : true,
- "prefetch-src": true
-};
-const report_only = "content-security-policy-report-only";
+const csp_header_names = new Set([
+ "content-security-policy",
+ "x-webkit-csp",
+ "x-content-security-policy"
+]);
+
+/* TODO: variable no longer in use; remove if not needed */
+const unwanted_csp_directives = new Set([
+ "report-to",
+ "report-uri",
+ "script-src",
+ "script-src-elem",
+ "prefetch-src"
+]);
-function not_csp_header(header)
-{
- return !csp_header_names[header.name.toLowerCase()];
-}
+const report_only = "content-security-policy-report-only";
function url_inject(details)
{
@@ -60,7 +56,7 @@ function url_inject(details)
if (targets.policy)
targets.target = "";
- let [pattern, settings] = query_best(targets.base_url);
+ let [pattern, settings] = query_best(storage, targets.base_url);
/* Defaults */
if (!pattern)
settings = {};
@@ -83,38 +79,6 @@ function url_inject(details)
};
}
-function process_csp_header(header, rule, block)
-{
- const csp = parse_csp(header.value);
-
- /* No snitching */
- delete csp['report-to'];
- delete csp['report-uri'];
-
- if (block) {
- delete csp['script-src'];
- delete csp['script-src-elem'];
- csp['script-src-attr'] = ["'none'"];
- csp['prefetch-src'] = ["'none'"];
- }
-
- if ('script-src' in csp)
- csp['script-src'].push(rule);
- else
- csp['script-src'] = [rule];
-
- if ('script-src-elem' in csp)
- csp['script-src-elem'].push(rule);
- else
- csp['script-src-elem'] = [rule];
-
- const new_policy = Object.entries(csp).map(
- i => i[0] + ' ' + i[1].join(' ') + ';'
- );
-
- return {name: header.name, value: new_policy.join('')}
-}
-
function headers_inject(details)
{
const targets = url_extract_target(details.url);
@@ -128,48 +92,44 @@ function headers_inject(details)
const rule = `'nonce-${targets.policy.nonce}'`;
const block = !targets.policy.allow;
-
- for (let header of details.responseHeaders) {
- if (not_csp_header(header)) {
- /* Retain all non-snitching headers */
- if (header.name.toLowerCase() !== report_only) {
- headers.push(header);
-
- /* If these are the original CSP headers, use them instead */
- /* Test based on url_extract_target() in misc.js */
- if (is_mozilla && header.name === "x-orig-csp") {
- let index = header.value.indexOf('%5B');
- if (index === -1)
- continue;
-
- let sig = header.value.substring(0, index);
- let data = header.value.substring(index);
- if (sig !== sign_policy(data, 0))
- continue;
-
- /* Confirmed- it's the originals, smuggled in! */
- try {
- data = JSON.parse(decodeURIComponent(data));
- } catch (e) {
- /* This should not be reached -
- it's our self-produced valid JSON. */
- console.log("Unexpected internal error - invalid JSON smuggled!", e);
- }
-
- orig_csp_headers = csp_headers = null;
- for (let header of data)
- headers.push(process_csp_header(header, rule, block));
+
+ for (const header of details.responseHeaders) {
+ if (!csp_header_names.has(header)) {
+ /* Remove headers that only snitch on us */
+ if (header.name.toLowerCase() === report_only && block)
+ continue;
+ headers.push(header);
+
+ /* If these are the original CSP headers, use them instead */
+ /* Test based on url_extract_target() in misc.js */
+ if (is_mozilla && header.name === "x-orig-csp") {
+ let index = header.value.indexOf('%5B');
+ if (index === -1)
+ continue;
+
+ let sig = header.value.substring(0, index);
+ let data = header.value.substring(index);
+ if (sig !== sign_policy(data, 0))
+ continue;
+
+ /* Confirmed- it's the originals, smuggled in! */
+ try {
+ data = JSON.parse(decodeURIComponent(data));
+ } catch (e) {
+ /* This should not be reached -
+ it's our self-produced valid JSON. */
+ console.log("Unexpected internal error - invalid JSON smuggled!", e);
}
- }
- continue;
+ orig_csp_headers = csp_headers = null;
+ for (const header of data)
+ headers.push(sanitize_csp_header(header, rule, block));
+ }
+ } else if (is_chrome || !orig_csp_headers) {
+ csp_headers.push(sanitize_csp_header(header, rule, block));
+ if (is_mozilla)
+ orig_csp_headers.push(header);
}
- if (is_mozilla && !orig_csp_headers)
- continue;
-
- csp_headers.push(process_csp_header(header, rule, block));
- if (is_mozilla)
- orig_csp_headers.push(header);
}
if (orig_csp_headers) {
@@ -202,7 +162,6 @@ function headers_inject(details)
async function start_policy_injector()
{
storage = await get_storage();
- query_best = await get_query_best();
let extra_opts = ["blocking", "responseHeaders"];
if (is_chrome)