Revision 5b419aed
Added by jahoti about 2 years ago
| background/policy_injector.js | ||
|---|---|---|
| 19 | 19 |
* IMPORT url_extract_target |
| 20 | 20 |
* IMPORT sign_policy |
| 21 | 21 |
* IMPORT get_query_best |
| 22 |
* IMPORT parse_csp
|
|
| 22 |
* IMPORT sanitize_csp_header
|
|
| 23 | 23 |
* IMPORTS_END |
| 24 | 24 |
*/ |
| 25 | 25 |
|
| ... | ... | |
| 79 | 79 |
}; |
| 80 | 80 |
} |
| 81 | 81 |
|
| 82 |
function process_csp_header(header, rule, block) |
|
| 83 |
{
|
|
| 84 |
const csp = parse_csp(header.value); |
|
| 85 |
|
|
| 86 |
|
|
| 87 |
if (block) {
|
|
| 88 |
/* No snitching */ |
|
| 89 |
delete csp['report-to']; |
|
| 90 |
delete csp['report-uri']; |
|
| 91 |
|
|
| 92 |
delete csp['script-src']; |
|
| 93 |
delete csp['script-src-elem']; |
|
| 94 |
|
|
| 95 |
csp['script-src-attr'] = ["'none'"]; |
|
| 96 |
csp['prefetch-src'] = ["'none'"]; |
|
| 97 |
} |
|
| 98 |
|
|
| 99 |
if ('script-src' in csp)
|
|
| 100 |
csp['script-src'].push(rule); |
|
| 101 |
else |
|
| 102 |
csp['script-src'] = [rule]; |
|
| 103 |
|
|
| 104 |
if ('script-src-elem' in csp)
|
|
| 105 |
csp['script-src-elem'].push(rule); |
|
| 106 |
else |
|
| 107 |
csp['script-src-elem'] = [rule]; |
|
| 108 |
|
|
| 109 |
const new_policy = Object.entries(csp).map( |
|
| 110 |
i => `${i[0]} ${i[1].join(' ')};`
|
|
| 111 |
); |
|
| 112 |
|
|
| 113 |
return {name: header.name, value: new_policy.join('')};
|
|
| 114 |
} |
|
| 115 |
|
|
| 116 | 82 |
function headers_inject(details) |
| 117 | 83 |
{
|
| 118 | 84 |
const targets = url_extract_target(details.url); |
| ... | ... | |
| 157 | 123 |
|
| 158 | 124 |
orig_csp_headers = csp_headers = null; |
| 159 | 125 |
for (const header of data) |
| 160 |
headers.push(process_csp_header(header, rule, block));
|
|
| 126 |
headers.push(sanitize_csp_header(header, rule, block));
|
|
| 161 | 127 |
} |
| 162 | 128 |
} else if (is_chrome || !orig_csp_headers) {
|
| 163 |
csp_headers.push(process_csp_header(header, rule, block));
|
|
| 129 |
csp_headers.push(sanitize_csp_header(header, rule, block));
|
|
| 164 | 130 |
if (is_mozilla) |
| 165 | 131 |
orig_csp_headers.push(header); |
| 166 | 132 |
} |
| common/misc.js | ||
|---|---|---|
| 173 | 173 |
return directives; |
| 174 | 174 |
} |
| 175 | 175 |
|
| 176 |
/* Make CSP headers do our bidding, not interfere */ |
|
| 177 |
function sanitize_csp_header(header, rule, block) |
|
| 178 |
{
|
|
| 179 |
const csp = parse_csp(header.value); |
|
| 180 |
|
|
| 181 |
if (block) {
|
|
| 182 |
/* No snitching */ |
|
| 183 |
delete csp['report-to']; |
|
| 184 |
delete csp['report-uri']; |
|
| 185 |
|
|
| 186 |
delete csp['script-src']; |
|
| 187 |
delete csp['script-src-elem']; |
|
| 188 |
|
|
| 189 |
csp['script-src-attr'] = ["'none'"]; |
|
| 190 |
csp['prefetch-src'] = ["'none'"]; |
|
| 191 |
} |
|
| 192 |
|
|
| 193 |
if ('script-src' in csp)
|
|
| 194 |
csp['script-src'].push(rule); |
|
| 195 |
else |
|
| 196 |
csp['script-src'] = [rule]; |
|
| 197 |
|
|
| 198 |
if ('script-src-elem' in csp)
|
|
| 199 |
csp['script-src-elem'].push(rule); |
|
| 200 |
else |
|
| 201 |
csp['script-src-elem'] = [rule]; |
|
| 202 |
|
|
| 203 |
const new_policy = Object.entries(csp).map( |
|
| 204 |
i => `${i[0]} ${i[1].join(' ')};`
|
|
| 205 |
); |
|
| 206 |
|
|
| 207 |
return {name: header.name, value: new_policy.join('')};
|
|
| 208 |
} |
|
| 209 |
|
|
| 176 | 210 |
/* |
| 177 | 211 |
* EXPORTS_START |
| 178 | 212 |
* EXPORT gen_nonce |
| ... | ... | |
| 184 | 218 |
* EXPORT nice_name |
| 185 | 219 |
* EXPORT open_in_settings |
| 186 | 220 |
* EXPORT is_privileged_url |
| 187 |
* EXPORT parse_csp
|
|
| 221 |
* EXPORT sanitize_csp_header
|
|
| 188 | 222 |
* EXPORTS_END |
| 189 | 223 |
*/ |
| content/main.js | ||
|---|---|---|
| 19 | 19 |
* IMPORT is_chrome |
| 20 | 20 |
* IMPORT is_mozilla |
| 21 | 21 |
* IMPORT start_activity_info_server |
| 22 |
* IMPORT sanitize_csp_header |
|
| 22 | 23 |
* IMPORTS_END |
| 23 | 24 |
*/ |
| 24 | 25 |
|
| ... | ... | |
| 65 | 66 |
block_script(node); |
| 66 | 67 |
return; |
| 67 | 68 |
} |
| 69 |
|
|
| 70 |
else if (node.tagName === 'META' && |
|
| 71 |
node.getAttribute('http-equiv') === 'content-security-policy') {
|
|
| 72 |
|
|
| 73 |
node.content = sanitize_csp_header( |
|
| 74 |
{value: node.content},
|
|
| 75 |
`'nonce-${nonce}'`,
|
|
| 76 |
!policy.allow |
|
| 77 |
).value; |
|
| 78 |
return; |
|
| 79 |
} |
|
| 68 | 80 |
|
| 69 | 81 |
sanitize_attributes(node); |
| 70 | 82 |
|
| ... | ... | |
| 114 | 126 |
if (!policy.allow) {
|
| 115 | 127 |
block_nodes_recursively(document.documentElement); |
| 116 | 128 |
|
| 117 |
if (is_chrome) {
|
|
| 118 |
var observer = new MutationObserver(handle_mutation); |
|
| 119 |
observer.observe(document.documentElement, {
|
|
| 120 |
attributes: true, |
|
| 121 |
childList: true, |
|
| 122 |
subtree: true |
|
| 123 |
}); |
|
| 124 |
} |
|
| 129 |
/* Now needed on Mozilla as well to sanitize CSP header */ |
|
| 130 |
var observer = new MutationObserver(handle_mutation); |
|
| 131 |
observer.observe(document.documentElement, {
|
|
| 132 |
attributes: true, |
|
| 133 |
childList: true, |
|
| 134 |
subtree: true |
|
| 135 |
}); |
|
| 125 | 136 |
|
| 126 | 137 |
if (is_mozilla) |
| 127 | 138 |
addEventListener('beforescriptexecute', mozilla_suppress_scripts, true);
|
Also available in: Unified diff
[UNTESTED- will test] Add filtering for http-equiv CSP headers