From b73b590964151edaf24c37911e319588ad64a1e5 Mon Sep 17 00:00:00 2001 From: hackademix Date: Mon, 28 Sep 2020 23:21:33 +0200 Subject: [PATCH] Better cross-browser media handling. --- build.sh | 6 +++--- src/content/content.js | 6 ++++-- src/content/embeddingDocument.js | 4 +++- src/content/media.js | 4 ++-- src/lib/CSP.js | 3 +++ 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/build.sh b/build.sh index de4051c..b9c73e5 100644 --- a/build.sh +++ b/build.sh @@ -19,7 +19,7 @@ strip_rc_ver() { VER=$(grep '"version":' "$MANIFEST_IN" | sed -re 's/.*": "(.*?)".*/\1/') if [ "$1" == "tag" ]; then echo "Tagging at $VER" - git tag -a "$VER" + git tag -a "$VER" git push origin "$VER" exit 0 fi @@ -140,9 +140,9 @@ ln -fs $XPI.xpi "$BASE/latest.xpi" # create chromium pre-release rm -rf "$CHROMIUM" strip_rc_ver "$MANIFEST_OUT" -# skip "application" manifest key +# skip "application" manifest key and embeddingDocument.js (grep -B1000 '"name": "NoScript"' "$MANIFEST_OUT"; \ - grep -A2000 '"version":' "$MANIFEST_OUT") > "$MANIFEST_OUT".tmp && \ + grep -A2000 '"version":' "$MANIFEST_OUT" | grep -v 'content/embeddingDocument.js') > "$MANIFEST_OUT".tmp && \ mv "$MANIFEST_OUT.tmp" "$MANIFEST_OUT" mv "$BUILD" "$CHROMIUM" web-ext $CHROMIUM_BUILD_OPTS --source-dir="$CHROMIUM" --artifacts-dir="$WEBEXT_OUT" $COMMON_BUILD_OPTS diff --git a/src/content/content.js b/src/content/content.js index f631ac1..7c49c1a 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -113,12 +113,14 @@ window.addEventListener("pageshow", notifyPage); let violations = new Set(); window.addEventListener("securitypolicyviolation", e => { if (!e.isTrusted) return; - let {violatedDirective} = e; + let {violatedDirective, originalPolicy} = e; if (violatedDirective === `script-src 'none'`) onScriptDisabled(); let type = violatedDirective.split("-", 1)[0]; // e.g. script-src 'none' => script let url = e.blockedURI; - if (/^data\b/.test(url) && !document.querySelector("video,audio")) return; + if (type === "media" && /^data\b/.test(url) && (!CSP.isMediaBlocker(originalPolicy) || + ns.embeddingDocument || !document.querySelector("video,audio"))) + return; if (!(url && url.includes(":"))) { url = document.URL; } diff --git a/src/content/embeddingDocument.js b/src/content/embeddingDocument.js index d565fc5..7439258 100644 --- a/src/content/embeddingDocument.js +++ b/src/content/embeddingDocument.js @@ -1,4 +1,5 @@ if (ns.embeddingDocument) { + let replace = () => { for (let policyType of ["object", "media"]) { let request = { @@ -23,8 +24,9 @@ if (ns.embeddingDocument) { } } }; + ns.on("capabilities", () => { - if (!document.body.firstChild) { // we've been called early + if (!(document.body && document.body.firstChild)) { // we've been called early setTimeout(replace, 0); let types = { // Reminder: order is important because media matches also for diff --git a/src/content/media.js b/src/content/media.js index bb45aae..a75ccef 100644 --- a/src/content/media.js +++ b/src/content/media.js @@ -35,8 +35,8 @@ if ("MediaSource" in window) { } let processedURIs = new Set(); addEventListener("securitypolicyviolation", e => { - let {blockedURI, violatedDirective} = e; - if (!(e.isTrusted && violatedDirective.startsWith("media-src"))) return; + let {blockedURI, violatedDirective, originalPolicy} = e; + if (!(e.isTrusted && violatedDirective === "media-src" && CSP.isMediaBlocker(originalPolicy))) return; if (mediaBlocker === undefined && /^data\b/.test(blockedURI)) { // Firefox 81 reports just "data" debug("mediaBlocker set via CSP listener.") mediaBlocker = true; diff --git a/src/lib/CSP.js b/src/lib/CSP.js index ad0afa2..74cb7e9 100644 --- a/src/lib/CSP.js +++ b/src/lib/CSP.js @@ -1,6 +1,9 @@ "use strict"; class CSP { + static isMediaBlocker(csp) { + return /(?:^| )media-src (?:'none'|http)(?:;|$)/.test(csp); + } build(...directives) { return directives.join(';');