mirror of
https://github.com/vale981/tridactyl
synced 2025-03-04 17:11:40 -05:00
Improve CSP clobbering (commit lost last time)
- Get csp setting asynchronously - Case insensitively match content-security-policy header value - Parse csp correctly - Simplify code (When I rebased last time I lost the content of this commit somehow...)
This commit is contained in:
parent
d28fc7f0f6
commit
8f67be2d17
4 changed files with 75 additions and 42 deletions
6
package-lock.json
generated
6
package-lock.json
generated
|
@ -2011,6 +2011,10 @@
|
||||||
"integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
|
"integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"csp-serdes": {
|
||||||
|
"version": "github:cmcaine/csp-serdes#6c6fe34dbd138855e5c26f331b094e9a75358a64",
|
||||||
|
"from": "github:cmcaine/csp-serdes"
|
||||||
|
},
|
||||||
"css": {
|
"css": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz",
|
||||||
|
@ -9376,7 +9380,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"web-ext-types": {
|
"web-ext-types": {
|
||||||
"version": "github:kelseasy/web-ext-types#5f6e888318984c185413f8943d2616915e2af88f",
|
"version": "github:kelseasy/web-ext-types#53d82dcea599d34a23b5f4aa6a9c616613c7adc2",
|
||||||
"from": "github:kelseasy/web-ext-types",
|
"from": "github:kelseasy/web-ext-types",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/css": "0.0.31",
|
"@types/css": "0.0.31",
|
||||||
"@types/nearley": "^2.11.0",
|
"@types/nearley": "^2.11.0",
|
||||||
|
"csp-serdes": "github:cmcaine/csp-serdes",
|
||||||
"css": "^2.2.1",
|
"css": "^2.2.1",
|
||||||
"fuse.js": "^3.2.0",
|
"fuse.js": "^3.2.0",
|
||||||
"mark.js": "^8.11.1",
|
"mark.js": "^8.11.1",
|
||||||
|
|
|
@ -55,28 +55,35 @@ import * as webext from "./lib/webext"
|
||||||
l: prom => prom.then(console.log).catch(console.error),
|
l: prom => prom.then(console.log).catch(console.error),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// {{{ Clobber CSP
|
||||||
|
|
||||||
// This should be removed once https://bugzilla.mozilla.org/show_bug.cgi?id=1267027 is fixed
|
// This should be removed once https://bugzilla.mozilla.org/show_bug.cgi?id=1267027 is fixed
|
||||||
let cspListener
|
function addCSPListener() {
|
||||||
if (config.get("csp") == "clobber") {
|
browser.webRequest.onHeadersReceived.addListener(
|
||||||
cspListener = browser.webRequest.onHeadersReceived.addListener(
|
request.clobberCSP,
|
||||||
request.addurltocsp,
|
|
||||||
{ urls: ["<all_urls>"], types: ["main_frame"] },
|
{ urls: ["<all_urls>"], types: ["main_frame"] },
|
||||||
["blocking", "responseHeaders"],
|
["blocking", "responseHeaders"],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeCSPListener() {
|
||||||
|
browser.webRequest.onHeadersReceived.removeListener(request.clobberCSP)
|
||||||
|
}
|
||||||
|
|
||||||
|
config.getAsync("csp").then(csp => csp === "clobber" && addCSPListener())
|
||||||
|
|
||||||
browser.storage.onChanged.addListener((changes, areaname) => {
|
browser.storage.onChanged.addListener((changes, areaname) => {
|
||||||
if (config.get("csp") == "clobber") {
|
if ("userconfig" in changes) {
|
||||||
cspListener = browser.webRequest.onHeadersReceived.addListener(
|
if (changes.userconfig.newValue.csp === "clobber") {
|
||||||
request.addurltocsp,
|
addCSPListener()
|
||||||
{ urls: ["<all_urls>"], types: ["main_frame"] },
|
} else {
|
||||||
["blocking", "responseHeaders"],
|
removeCSPListener()
|
||||||
)
|
}
|
||||||
} else {
|
|
||||||
// This doesn't work. :(
|
|
||||||
// browser.webRequest.onHeadersReceived.removeListener(cspListener)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
// Prevent Tridactyl from being updated while it is running in the hope of fixing #290
|
// Prevent Tridactyl from being updated while it is running in the hope of fixing #290
|
||||||
browser.runtime.onUpdateAvailable.addListener(_ => {})
|
browser.runtime.onUpdateAvailable.addListener(_ => {})
|
||||||
|
|
||||||
|
|
|
@ -1,32 +1,53 @@
|
||||||
import * as config from "./config"
|
import * as config from "./config"
|
||||||
|
import * as csp from "csp-serdes"
|
||||||
|
|
||||||
export function addurltocsp(response) {
|
class DefaultMap extends Map {
|
||||||
let headers = response["responseHeaders"]
|
constructor(private defaultFactory, ...args) {
|
||||||
let cspind = headers.findIndex(
|
super(...args)
|
||||||
header => header.name == "Content-Security-Policy",
|
}
|
||||||
)
|
|
||||||
// if it's found
|
get(key) {
|
||||||
if (cspind > -1) {
|
let ans = super.get(key)
|
||||||
// Split the csp header up so we can manage it individually.
|
if (ans === undefined) {
|
||||||
let csparr = [headers[cspind]["value"].split("; ")][0]
|
ans = this.defaultFactory(key)
|
||||||
|
super.set(key, ans)
|
||||||
for (let i = 0; i < csparr.length; i++) {
|
}
|
||||||
// Add 'unsafe-inline' as a directive since we use it
|
return ans
|
||||||
if (csparr[i].indexOf("style-src") > -1) {
|
}
|
||||||
if (csparr[i].indexOf("'self'") > -1) {
|
}
|
||||||
csparr[i] = csparr[i].replace(
|
|
||||||
"'self'",
|
/**
|
||||||
"'self' 'unsafe-inline'",
|
* Reduce CSP safety to permit tridactyl to run correctly
|
||||||
)
|
*
|
||||||
}
|
* style-src needs 'unsafe-inline' (hinting styles) and 'self' (mode indicator hiding)
|
||||||
}
|
* script-src needs 'unsafe-eval' (event hijacking)
|
||||||
// Remove the element if it's a sandbox directive
|
* - but that's pretty dangerous, so maybe we shouldn't just clobber it?
|
||||||
if (csparr[i] === "sandbox") {
|
* sandbox must not be set
|
||||||
csparr.splice(i, 1)
|
*
|
||||||
}
|
* This only needs to happen because of a Firefox bug and we should stop doing
|
||||||
}
|
* it when they fix the bug.
|
||||||
// Join the header up after clobberin'
|
*/
|
||||||
headers[cspind]["value"] = csparr.join("; ")
|
export function clobberCSP(response) {
|
||||||
|
const headers = response["responseHeaders"]
|
||||||
|
const cspHeader = headers.find(
|
||||||
|
header => header.name.toLowerCase() === "content-security-policy",
|
||||||
|
)
|
||||||
|
|
||||||
|
if (cspHeader !== undefined) {
|
||||||
|
const policy = new DefaultMap(
|
||||||
|
() => new Set(),
|
||||||
|
csp.parse(cspHeader.value),
|
||||||
|
)
|
||||||
|
policy.delete("sandbox")
|
||||||
|
policy
|
||||||
|
.get("style-src")
|
||||||
|
.add("'unsafe-inline'")
|
||||||
|
.add("'self'")
|
||||||
|
// policy.get("script-src").add("'unsafe-eval'")
|
||||||
|
// Replace old CSP
|
||||||
|
cspHeader.value = csp.serialize(policy)
|
||||||
|
return { responseHeaders: headers }
|
||||||
|
} else {
|
||||||
|
return {}
|
||||||
}
|
}
|
||||||
return { responseHeaders: headers }
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue