Merge branch 'main' of github.com:hackademix/noscript into ctx

This commit is contained in:
hackademix 2022-02-13 17:05:14 +01:00
commit 963f728658
8 changed files with 66 additions and 37 deletions

View File

@ -736,7 +736,7 @@
"description": "" "description": ""
}, },
"cap_unchecked_css": { "cap_unchecked_css": {
"message": "jedes CSS", "message": "ungeprüfte CSS",
"description": "" "description": ""
}, },
"cap_other": { "cap_other": {

View File

@ -661,7 +661,7 @@ var RequestGuard = (() => {
policy.navigationURL = url; policy.navigationURL = url;
let debugStatement = ns.local.debug ? ` let debugStatement = ns.local.debug ? `
let mark = Date.now() + ":" + Math.random(); let mark = Date.now() + ":" + Math.random();
console.debug("domPolicy", domPolicy, document.readyState, mark);` : ''; console.debug("domPolicy", domPolicy, document.readyState, location.href, mark, window.ns);` : '';
return ` return `
let domPolicy = ${JSON.stringify(policy)}; let domPolicy = ${JSON.stringify(policy)};
let {ns} = window; let {ns} = window;
@ -669,9 +669,7 @@ var RequestGuard = (() => {
ns.domPolicy = domPolicy; ns.domPolicy = domPolicy;
if (ns.setup) { if (ns.setup) {
if (ns.syncSetup) ns.syncSetup(domPolicy); if (ns.syncSetup) ns.syncSetup(domPolicy);
else if (!ns.pendingSyncFetchPolicy) { else ns.setup(domPolicy);
ns.setup(domPolicy);
}
} ; } ;
} else { } else {
window.ns = {domPolicy} window.ns = {domPolicy}

View File

@ -212,7 +212,7 @@
function onSyncMessage(msg, sender) { function onSyncMessage(msg, sender) {
switch(msg.id) { switch(msg.id) {
case "fetchPolicy": case "fetchChildPolicy":
return messageHandler.fetchChildPolicy(msg, sender); return messageHandler.fetchChildPolicy(msg, sender);
break; break;
} }

View File

@ -23,7 +23,7 @@
let listenersMap = new Map(); let listenersMap = new Map();
let backlog = new Set(); let backlog = new Set();
var ns = { let ns = {
debug: true, // DEV_ONLY debug: true, // DEV_ONLY
get embeddingDocument() { get embeddingDocument() {
delete this.embeddingDocument; delete this.embeddingDocument;
@ -72,6 +72,14 @@
} }
} }
if (this.syncFetchPolicy) {
// extra hops to ensure that scripts don't run when CSP has not been set through HTTP headers
this.syncFetchPolicy();
return;
}
this.pendingSyncFetchPolicy = true;
if (!sync) { if (!sync) {
queueMicrotask(() => this.fetchPolicy(true)); queueMicrotask(() => this.fetchPolicy(true));
return; return;
@ -86,24 +94,46 @@
debug("Fetching policy for actual URL %s (was %s)", url, document.URL); debug("Fetching policy for actual URL %s (was %s)", url, document.URL);
} }
if (this.syncFetchPolicy) { if (!this.syncFetchPolicy) {
// extra hops to ensure that scripts don't run when CSP has not been set through HTTP headers
this.syncFetchPolicy(); let msg = {id: "fetchChildPolicy", url};
} else {
let msg = {id: "fetchPolicy", url}; let asyncFetch = (async () => {
if (document.readyState === "complete") { let policy = null;
// no point fetching synchronously, since the document is already loaded (hot extension update?) for (let attempts = 10; !(policy || this.policy) && attempts-- > 0;) {
(async () => this.setup(await browser.runtime.sendMessage(msg)))(); try {
} else { debug(`Retrieving policy asynchronously (${attempts} attempts left).`);
debug(`Synchronously fetching policy for ${url}.`); policy = await Messages.send(msg.id, msg) || this.domPolicy;
this.setup(browser.runtime.sendSyncMessage(msg)); debug("Asynchronous policy", policy);
} catch (e) {
error(e, "(Asynchronous policy fetch)");
} }
} }
this.setup(policy);
});
debug(`Synchronously fetching policy for ${url}.`);
let policy = null;
let attempts = 100;
let refetch = () => {
policy = browser.runtime.sendSyncMessage(msg) || this.domPolicy;
if (policy) {
this.setup(policy);
} else if (attempts-- > 0) {
debug(`Couldn't retrieve policy synchronously (${attempts} attempts left).`);
if (asyncFetch) {
asyncFetch();
asyncFetch = null;
}
queueMicrotask(refetch);
}
};
refetch();
}
}, },
setup(policy) { setup(policy) {
if (this.policy) return false; if (this.policy) return false;
debug("%s, %s, fetched %o", document.URL, document.readyState, policy); debug("%s, %s, fetched %o", document.URL, document.readyState, policy, new Error().stack); // DEV_ONLY
if (!policy) { if (!policy) {
policy = {permissions: {capabilities: []}, localFallback: true}; policy = {permissions: {capabilities: []}, localFallback: true};
} }

View File

@ -22,6 +22,9 @@
(window.ns || (window.ns = {})).syncFetchPolicy = function() { (window.ns || (window.ns = {})).syncFetchPolicy = function() {
ns.pendingSyncFetchPolicy = false;
ns.syncFetchPolicy = () => {};
let url = document.URL; let url = document.URL;
// Here we've got no CSP header yet (file: or ftp: URL), we need one // Here we've got no CSP header yet (file: or ftp: URL), we need one
@ -32,18 +35,17 @@
if (window.wrappedJSObject) { if (window.wrappedJSObject) {
if (top === window) { if (top === window) {
let persistentPolicy = null;
ns.syncSetup = policy => { ns.syncSetup = policy => {
if (!ns.setup(policy)) return; if (persistentPolicy) return;
if (top === window && window.wrappedJSObject) { ns.setup(policy);
let persistentPolicy = JSON.stringify(policy); persistentPolicy = JSON.stringify(policy);
Object.freeze(persistentPolicy); Object.freeze(persistentPolicy);
try { try {
Object.defineProperty(window.wrappedJSObject, "_noScriptPolicy", {value: cloneInto(persistentPolicy, window)}); Object.defineProperty(window.wrappedJSObject, "_noScriptPolicy", {value: cloneInto(persistentPolicy, window)});
} catch(e) { } catch(e) {
error(e); error(e);
} }
}
ns.syncSetup = () => {};
}; };
} else try { } else try {
if (top.wrappedJSObject._noScriptPolicy) { if (top.wrappedJSObject._noScriptPolicy) {
@ -239,6 +241,5 @@
}; };
if (ns.pendingSyncFetchPolicy) { if (ns.pendingSyncFetchPolicy) {
ns.pendingSyncFetchPolicy = false;
ns.syncFetchPolicy(); ns.syncFetchPolicy();
} }

View File

@ -8,7 +8,7 @@
"strict_min_version": "59.0" "strict_min_version": "59.0"
} }
}, },
"version": "11.2.19", "version": "11.2.25",
"description": "__MSG_Description__", "description": "__MSG_Description__",
"incognito": "spanning", "incognito": "spanning",

@ -1 +1 @@
Subproject commit fa49ecb52140aa80db30a7fa834f6358acc94a13 Subproject commit 7a302d1d181f7d9ef2bbee716c6c850df8cefdad

View File

@ -20,10 +20,10 @@
ns.on("capabilities", event => { ns.on("capabilities", event => {
if (ns.allows("script")) { if (ns.allows("script")) {
let name = ns.getWindowName(); let dangerousRx = /[<"'\`(=:]/g;
if (/[<"'\`(=:]/.test(name)) { if (/[<"'\`(=:]/.test(window.name)) {
console.log(`NoScript XSS filter sanitizing suspicious window.name "%s" on %s`, name, document.URL); console.log(`NoScript XSS filter sanitizing suspicious window.name "%s" on %s`, window.name, document.URL);
window.name = window.name.substring(0, window.name.length - name.length); window.name = window.name.replace(dangerousRx, '');
} }
} }
}); });