Project

General

Profile

Download (2.55 KB) Statistics
| Branch: | Tag: | Revision:

haketilo / background / policy_injector.js @ 7ee7889a

1
/**
2
 * Myext injecting policy to page using webRequest
3
 *
4
 * Copyright (C) 2021 Wojtek Kosior
5
 *
6
 * This code is dual-licensed under:
7
 * - Asshole license 1.0,
8
 * - GPLv3 or (at your option) any later version
9
 *
10
 * "dual-licensed" means you can choose the license you prefer.
11
 *
12
 * This code is released under a permissive license because I disapprove of
13
 * copyright and wouldn't be willing to sue a violator. Despite not putting
14
 * this code under copyleft (which is also kind of copyright), I do not want
15
 * it to be made proprietary. Hence, the permissive alternative to GPL is the
16
 * Asshole license 1.0 that allows me to call you an asshole if you use it.
17
 * This means you're legally ok regardless of how you utilize this code but if
18
 * you make it into something nonfree, you're an asshole.
19
 *
20
 * You should have received a copy of both GPLv3 and Asshole license 1.0
21
 * together with this code. If not, please see:
22
 * - https://www.gnu.org/licenses/gpl-3.0.en.html
23
 * - https://koszko.org/asshole-license.txt
24
 */
25

    
26
"use strict";
27

    
28
(() => {
29
    const TYPE_PREFIX = window.TYPE_PREFIX;
30
    const get_storage = window.get_storage;
31
    const browser = window.browser;
32
    const is_chrome = window.is_chrome;
33
    const gen_unique = window.gen_unique;
34
    const url_item = window.url_item;
35
    const get_query_best = window.get_query_best;
36

    
37
    var storage;
38
    var query_best;
39

    
40
    let csp_header_names = {
41
	"content-security-policy" : true,
42
	"x-webkit-csp" : true,
43
	"x-content-security-policy" : true
44
    };
45

    
46
    function is_noncsp_header(header)
47
    {
48
	return !csp_header_names[header.name.toLowerCase()];
49
    }
50

    
51
    function inject(details)
52
    {
53
	let url = url_item(details.url);
54

    
55
	let [pattern, settings] = query_best(url);
56

    
57
	if (settings !== undefined && settings.allow) {
58
	    console.log("allowing", url);
59
	    return {cancel : false};
60
	}
61

    
62
	let nonce = gen_unique(url).substring(1);
63
	let headers = details.responseHeaders.filter(is_noncsp_header);
64
	headers.push({
65
	    name : "content-security-policy",
66
	    value : `script-src 'nonce-${nonce}'; script-src-elem 'nonce-${nonce}';`
67
	});
68

    
69
	console.log("modified headers", url, headers);
70

    
71
	return {responseHeaders: headers};
72
    }
73

    
74
    async function start() {
75
	storage = await get_storage();
76
	query_best = await get_query_best();
77

    
78
	let extra_opts = ["blocking", "responseHeaders"];
79
	if (is_chrome)
80
	    extra_opts.push("extraHeaders");
81

    
82
	browser.webRequest.onHeadersReceived.addListener(
83
	    inject,
84
	    {
85
		urls: ["<all_urls>"],
86
		types: ["main_frame", "sub_frame"]
87
	    },
88
	    extra_opts
89
	);
90
    }
91

    
92
    window.start_policy_injector = start;
93
})();
(5-5/10)