From eceae7187a6f0e9510bc1165f6977256b87f490f Mon Sep 17 00:00:00 2001 From: hackademix Date: Sun, 1 Jul 2018 01:01:23 +0200 Subject: Initial commit starting at version 10.1.8.3rc4. --- src/content/PlaceHolder.js | 150 ++++++++++++++++++++++++++++++++++++++++ src/content/content.css | 71 +++++++++++++++++++ src/content/content.js | 107 ++++++++++++++++++++++++++++ src/content/media.js | 59 ++++++++++++++++ src/content/onScriptDisabled.js | 74 ++++++++++++++++++++ src/content/webglHook.js | 31 +++++++++ 6 files changed, 492 insertions(+) create mode 100644 src/content/PlaceHolder.js create mode 100644 src/content/content.css create mode 100644 src/content/content.js create mode 100644 src/content/media.js create mode 100644 src/content/onScriptDisabled.js create mode 100644 src/content/webglHook.js (limited to 'src/content') diff --git a/src/content/PlaceHolder.js b/src/content/PlaceHolder.js new file mode 100644 index 0000000..37c0198 --- /dev/null +++ b/src/content/PlaceHolder.js @@ -0,0 +1,150 @@ +var PlaceHolder = (() => { + const HANDLERS = new Map(); + + class Handler { + constructor(type, selector) { + this.type = type; + this.selector = selector; + this.placeHolders = new Map(); + HANDLERS.set(type, this); + } + filter(element, request) { + let url = request.initialUrl || request.url; + return "data" in element ? element.data === url : element.src === url; + } + } + + new Handler("frame", "iframe"); + new Handler("object", "object, embed"); + new Handler("media", "video, audio"); + + function cloneStyle(src, dest, + props = ["width", "height", "position", "*", "margin*"]) { + var suffixes = ["Top", "Right", "Bottom", "Left"]; + for (let i = props.length; i-- > 0;) { + let p = props[i]; + if (p.endsWith("*")) { + let prefix = p.substring(0, p.length - 1); + props.splice(i, 1, ... + (suffixes.map(prefix ? (suffix => prefix + suffix) : + suffix => suffix.toLowerCase()))); + } + }; + + let srcStyle = window.getComputedStyle(src, null); + let destStyle = dest.style; + for (let p of props) { + destStyle[p] = srcStyle[p]; + } + destStyle.display = srcStyle.display !== "block" ? "inline-block" : "block"; + } + + class PlaceHolder { + + static create(policyType, request) { + return new PlaceHolder(policyType, request); + } + static canReplace(policyType) { + return HANDLERS.has(policyType); + } + + static listen() { + PlaceHolder.listen = () => {}; + window.addEventListener("click", ev => { + if (ev.button === 0) { + let replacement = ev.target.closest("a.__NoScript_PlaceHolder__"); + let ph = replacement && ev.isTrusted && replacement._placeHolderObj; + if (ph) { + ev.preventDefault(); + ev.stopPropagation(); + if (ev.target.value === "close") { + ph.close(replacement); + } else { + ph.enable(replacement); + } + } + } + }, true, false); + } + + constructor(policyType, request) { + this.policyType = policyType; + this.request = request; + this.replacements = new Set(); + this.handler = HANDLERS.get(policyType); + if (this.handler) { + [...document.querySelectorAll(this.handler.selector)] + .filter(element => this.handler.filter(element, request)) + .forEach(element => this.replace(element)); + }; + if (this.replacements.size) PlaceHolder.listen(); + } + + replace(element) { + let { + url + } = this.request; + this.origin = new URL(url).origin; + let TYPE = `<${this.policyType.toUpperCase()}>`; + + let replacement = document.createElement("a"); + replacement.className = "__NoScript_PlaceHolder__"; + cloneStyle(element, replacement); + replacement.style.backgroundImage = `url(${ICON_URL})`; + replacement.href = url; + replacement.title = `${TYPE}@${url}`; + + let inner = replacement.appendChild(document.createElement("span")); + inner.className = replacement.className; + + let button = inner.appendChild(document.createElement("button")); + button.className = replacement.className; + button.setAttribute("aria-label", button.title = _("Close")); + button.value = "close"; + button.textContent = "🗙"; + + let description = inner.appendChild(document.createElement("span")); + description.textContent = `${TYPE}@${this.origin}`; + + replacement._placeHolderObj = this; + replacement._placeHolderElement = element; + this.replacements.add(replacement); + + if (element.parentNode) element.parentNode.replaceChild(replacement, element); + else document.body.appendChild(replacement); + } + + async enable(replacement) { + debug("Enabling %o", this.request, this.policyType); + let ok = await browser.runtime.sendMessage({ + type: "enable", + url: this.request.url, + policyType: this.policyType, + documentUrl: document.URL + }); + debug("Received response", ok); + if (!ok) return; + if (this.request.embeddingDocument) { + window.location.reload(); + return; + } + try { + var element = replacement._placeHolderElement; + replacement.parentNode.replaceChild(element, replacement); + this.replacements.delete(replacement); + } catch (e) { + error(e, "While replacing"); + } + } + + close(replacement) { + replacement.classList.add("closing"); + this.replacements.delete(replacement); + window.setTimeout(() => replacement.parentNode.removeChild(replacement), 500); + } + } + + const ICON_URL = "data:image/png;base64,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"; + + return PlaceHolder; +})(); diff --git a/src/content/content.css b/src/content/content.css new file mode 100644 index 0000000..015fb2d --- /dev/null +++ b/src/content/content.css @@ -0,0 +1,71 @@ +a.__NoScript_PlaceHolder__ { + outline: 2px solid #048; + color: #048; + text-decoration: none; + text-align: center; + background: rgba(255,250,200, .7) no-repeat center; + background-size: 256px; + visibility: visible !important; + cursor: pointer; + opacity: 0.8; + transition: 1s all; +} + +a.__NoScript_PlaceHolder__:hover { + opacity: 1; + text-decoration: underline; + background-size: 128px; + background-position: top left; +} + +a.__NoScript_PlaceHolder__.closing { + transition: .4s all; + opacity: 0; + transform: scale(0, 0); +} + +a.__NoScript_PlaceHolder__ > span { + display: flex !important; + flex-direction: row; + justify-content: space-around; + align-items: center; + position: relative; + padding: 0; + margin: 0; + width: 100%; + height: 100%; +} + +.__NoScript_PlaceHolder__ button { + appearance: none; + -moz-appearance: none; + border: none; + position: absolute; + top: 0; + right: 0; + display: block; + color: #800; + font-size: 16px; + font-family: sans-serif; + padding: 0 4px; + margin: 0; + background: none; + transition: .2s all; +} +.__NoScript_PlaceHolder__ button:hover { + + color: white; + text-shadow: -2px 0 2px red, 2px 0 2px red; +} + +.__NoScript_PlaceHolder__ > span > span { + display: block; + font-size: 18px; + background: rgba(255, 250, 200, .5); + border-radius: 8px; + padding: 8px; + margin: 0; + font-family: sans-serif; + overflow-wrap: break-word; + word-break: break-all; +} diff --git a/src/content/content.js b/src/content/content.js new file mode 100644 index 0000000..5ba5076 --- /dev/null +++ b/src/content/content.js @@ -0,0 +1,107 @@ +'use strict'; + + // debug = () => {}; // XPI_ONLY + +var _ = browser.i18n.getMessage; + +var canScript = true; + +var embeddingDocument = false; + +var seen = { + _map: new Map(), + _list: null, + record(event) { + let key = event.request.key; + if (this._map.has(key)) return; + this._map.set(key, event); + this._list = null; + }, + get list() { + return this._list || (this._list = [...this._map.values()]); + } +} + +var handlers = { + + seen(event) { + let {allowed, policyType, request, ownFrame} = event; + if (window.top === window) { + seen.record(event); + } + if (ownFrame) { + init(); + if (!allowed && PlaceHolder.canReplace(policyType)) { + request.embeddingDocument = embeddingDocument; + PlaceHolder.create(policyType, request); + } + } + }, + + collect(event) { + let list = seen.list; + debug("COLLECT", list); + return list; + } +}; + +browser.runtime.onMessage.addListener(async event => { + if (event.type in handlers) { + debug("Received message", event); + return handlers[event.type](event); + } +}); + +if (document.readyState !== "complete") { + let pageshown = e => { + removeEventListener("pageshow", pageshown); + init(); + }; + addEventListener("pageshow", pageshown); +} else init(); + +let notifyPage = () => { + if (document.readyState === "complete") { + browser.runtime.sendMessage({type: "pageshow", seen, canScript}); + return true; + } + return false; +} + + +async function init() { + try { + canScript = await browser.runtime.sendMessage({type: "canScript"}); + init = () => {}; + debug("canScript:", canScript); + } catch (e) { + // background script not initialized yet? + setTimeout(() => init(), 100); + return; + } + + if (!canScript) onScriptDisabled(); + seen.record({ + request: { + key: "noscript-probe", + url: document.URL, + documentUrl: document.URL, + type: window === window.top ? "main_frame" : "script", + }, + allowed: canScript + } + ); + + debug(`Loading NoScript in document %s, scripting=%s, content type %s readyState %s`, + document.URL, canScript, document.contentType, document.readyState); + + if (/application|video|audio/.test(document.contentType)) { + debug("Embedding document detected"); + embeddingDocument = true; + window.addEventListener("pageshow", e => { + debug("Active content still in document %s: %o", document.url, document.querySelectorAll("embed,object,video,audio")); + }, true); + // document.write(""); + } + notifyPage() || addEventListener("pageshow", notifyPage); +}; diff --git a/src/content/media.js b/src/content/media.js new file mode 100644 index 0000000..22bf014 --- /dev/null +++ b/src/content/media.js @@ -0,0 +1,59 @@ +console.log("Media Hook", document.documentElement.innerHTML); +try { + (() => { + let unpatched = new Map(); + function patch(obj, methodName, replacement) { + let methods = unpatched.get(obj) || {}; + methods[methodName] = obj[methodName]; + exportFunction(replacement, obj, {defineAs: methodName}); + unpatched.set(obj, methods); + } + patch(window.console, "log", function(s, ...args) { + unpatched.get(window.console).log.call(`PATCHED ${s}`, ...args); + }); + let urlMap = new WeakMap(); + patch(window.URL, "createObjectURL", function(o, ...args) { + let url = unpatched.get(window.URL).createObjectURL.call(this, o, ...args); + if (o instanceof MediaSource) { + let urls = urlMap.get(o); + if (!urls) urlMap.set(o, urls = new Set()); + urls.add(url); + } + return url; + }); + + patch(window.MediaSource.prototype, "addSourceBuffer", function(mime, ...args) { + let ms = this; + let urls = urlMap.get(ms); + let me = Array.from(document.querySelectorAll("video,audio")) + .find(e => e.srcObject === ms || urls && urls.has(e.src)); + let exposedMime = `${mime} (MSE)`; + + let request = { + id: "noscript-media", + type: "media", + url: document.URL, + documentUrl: document.URL, + embeddingDocument: true, + }; + seen.record({policyType: "media", request, allowed: false}); + notifyPage(); + + if (window.mediaBlocker) { + try { + let ph = PlaceHolder.create("media", request); + ph.replace(me); + PlaceHolder.listen(); + } catch (e) { + error(e); + } + throw new Error(`${exposedMime} blocked by NoScript`); + } + + return unpatched.get(window.MediaSource.prototype).addSourceBuffer.call(ms, mime, ...args); + }); + + })(); +} catch (e) { + error(e, "Cannot patch MediaSource"); +} diff --git a/src/content/onScriptDisabled.js b/src/content/onScriptDisabled.js new file mode 100644 index 0000000..e6c754a --- /dev/null +++ b/src/content/onScriptDisabled.js @@ -0,0 +1,74 @@ +function onScriptDisabled() { + for (let noscript of document.querySelectorAll("noscript")) { + // force show NOSCRIPT elements content + let replacement = document.createElement("div"); + replacement.innerHTML = noscript.innerHTML; + noscript.parentNode.replaceChild(replacement, noscript); + // emulate meta-refresh + let meta = replacement.querySelector('meta[http-equiv="refresh"]'); + if (meta) { + let content = meta.getAttribute("content"); + if (content) { + let [secs, url] = content.split(/\s*;\s*url\s*=\s*/i); + if (url) { + try { + let urlObj = new URL(url); + if (!/^https?:/.test(urlObj.protocol)) { + continue; + } + } catch (e) { + } + window.setTimeout(() => location.href = url, (parseInt(secs) || 0) * 1000); + } + } + } + } + + { + let eraser = { + tapped: null, + delKey: false, + }; + + addEventListener("pagehide", ev => { + eraser.tapped = null; + eraser.delKey = false; + }, false); + + addEventListener("keyup", ev => { + let el = eraser.tapped; + if (el && ev.keyCode === 46) { + eraser.tapped = null; + eraser.delKey = true; + let doc = el.ownerDocument; + let w = doc.defaultView; + if (w.getSelection().isCollapsed) { + let root = doc.body || doc.documentElement; + let posRx = /^(?:absolute|fixed)$/; + do { + if (posRx.test(w.getComputedStyle(el, '').position)) { + (eraser.tapped = el.parentNode).removeChild(el); + break; + } + } while ((el = el.parentNode) && el != root); + } + } + }, true); + + addEventListener("mousedown", ev => { + if (ev.button === 0) { + eraser.tapped = ev.target; + eraser.delKey = false; + } + }, true); + + addEventListener("mouseup", ev => { + if (eraser.delKey) { + eraser.delKey = false; + ev.preventDefault(); + ev.stopPropagation(); + } + eraser.tapped = null; + }, true); + } +} diff --git a/src/content/webglHook.js b/src/content/webglHook.js new file mode 100644 index 0000000..ba0d769 --- /dev/null +++ b/src/content/webglHook.js @@ -0,0 +1,31 @@ +console.log("WebGL Hook", document.documentElement.innerHTML); +try { + let proto = HTMLCanvasElement.prototype; + let getContext = proto.getContext; + exportFunction(function(type, ...rest) { + if (type && type.toLowerCase().includes("webgl")) { + let request = { + id: "noscript-webgl", + type: "webgl", + url: document.URL, + documentUrl: document.URL, + embeddingDocument: true, + }; + seen.record({policyType: "webgl", request, allowed: false}); + try { + let ph = PlaceHolder.create("webgl", request); + ph.replace(this); + PlaceHolder.listen(); + } catch (e) { + error(e); + } + notifyPage(); + return {}; + } + return getContext.call(this, type, ...rest); + }, proto, {defineAs: "getContext"}); +} catch (e) { + console.error(e); +} + +null; -- cgit v1.2.3