Project

General

Profile

« Previous | Next » 

Revision 6b53d6c8

Added by koszko about 2 years ago

use StreamFilter under Mozilla to prevent csp tags from blocking our injected scripts

View differences:

background/policy_injector.js
8 8

  
9 9
/*
10 10
 * IMPORTS_START
11
 * IMPORT get_storage
12
 * IMPORT browser
13
 * IMPORT is_chrome
14
 * IMPORT gen_nonce
15
 * IMPORT is_privileged_url
16 11
 * IMPORT sign_data
17 12
 * IMPORT extract_signed
18
 * IMPORT query_best
19 13
 * IMPORT sanitize_csp_header
20 14
 * IMPORT csp_rule
21 15
 * IMPORT is_csp_header_name
22 16
 * IMPORTS_END
23 17
 */
24 18

  
25
var storage;
26

  
27
function headers_inject(details)
19
function inject_csp_headers(details, headers, policy)
28 20
{
29 21
    const url = details.url;
30
    if (is_privileged_url(url))
31
	return;
32

  
33
    const [pattern, settings] = query_best(storage, url);
34
    const allow = !!(settings && settings.allow);
35
    const nonce = gen_nonce();
36 22

  
37 23
    let orig_csp_headers;
38 24
    let old_signature;
39 25
    let hachette_header;
40
    let headers = details.responseHeaders;
41 26

  
42 27
    for (const header of headers.filter(h => h.name === "x-hachette")) {
43 28
	const match = /^([^%])(%.*)$/.exec(header.value);
......
50 35

  
51 36
	/* Confirmed- it's the originals, smuggled in! */
52 37
	orig_csp_headers = old_data.csp_headers;
53
	old_signature = old_data.policy_signature;
38
	old_signature = old_data.policy_sig;
54 39

  
55 40
	hachette_header = header;
56 41
	break;
......
65 50
	headers.filter(h => is_csp_header_name(h.name));
66 51

  
67 52
    /* When blocking remove report-only CSP headers that snitch on us. */
68
    headers = headers.filter(h => !is_csp_header_name(h.name, !allow));
53
    headers = headers.filter(h => !is_csp_header_name(h.name, !policy.allow));
69 54

  
70 55
    if (old_signature)
71 56
	headers = headers.filter(h => h.name.search(old_signature) === -1);
72 57

  
73
    const policy_object = {allow, nonce, url};
74
    const sanitizer = h => sanitize_csp_header(h, policy_object);
58
    const sanitizer = h => sanitize_csp_header(h, policy);
75 59
    headers.push(...orig_csp_headers.map(sanitizer));
76 60

  
77
    const policy = encodeURIComponent(JSON.stringify(policy_object));
78
    const policy_signature = sign_data(policy, new Date());
61
    const policy_str = encodeURIComponent(JSON.stringify(policy));
62
    const policy_sig = sign_data(policy_str, new Date());
79 63
    const later_30sec = new Date(new Date().getTime() + 30000).toGMTString();
80 64
    headers.push({
81 65
	name: "Set-Cookie",
82
	value: `hachette-${policy_signature}=${policy}; Expires=${later_30sec};`
66
	value: `hachette-${policy_sig}=${policy_str}; Expires=${later_30sec};`
83 67
    });
84 68

  
85 69
    /*
......
87 71
     * These are signed with a time of 0, as it's not clear there is a limit on
88 72
     * how long Firefox might retain headers in the cache.
89 73
     */
90
    let hachette_data = {csp_headers: orig_csp_headers, policy_signature, url};
74
    let hachette_data = {csp_headers: orig_csp_headers, policy_sig, url};
91 75
    hachette_data = encodeURIComponent(JSON.stringify(hachette_data));
92 76
    hachette_header.value = sign_data(hachette_data, 0) + hachette_data;
93 77

  
94 78
    /* To ensure there is a CSP header if required */
95
    if (!allow)
96
	headers.push({name: "content-security-policy", value: csp_rule(nonce)});
79
    if (!policy.allow)
80
	headers.push({
81
	    name: "content-security-policy",
82
	    value: csp_rule(policy.nonce)
83
	});
97 84

  
98
    return {responseHeaders: headers};
99
}
100

  
101
async function start_policy_injector()
102
{
103
    storage = await get_storage();
104

  
105
    let extra_opts = ["blocking", "responseHeaders"];
106
    if (is_chrome)
107
	extra_opts.push("extraHeaders");
108

  
109
    browser.webRequest.onHeadersReceived.addListener(
110
	headers_inject,
111
	{
112
	    urls: ["<all_urls>"],
113
	    types: ["main_frame", "sub_frame"]
114
	},
115
	extra_opts
116
    );
85
    return headers;
117 86
}
118 87

  
119 88
/*
120 89
 * EXPORTS_START
121
 * EXPORT start_policy_injector
90
 * EXPORT inject_csp_headers
122 91
 * EXPORTS_END
123 92
 */

Also available in: Unified diff