Is SERP Analyzer safe?

Medium risk

SERP Analyzer sends the hostname of every site you visit and your IP address to third-party servers on each page load.

On every completed page navigation to any http or https site, the extension automatically sends the visited hostname to data.tinycms.xyz to look up a 'domain owner' label, and separately sends the hostname, your browser language, and the site's server IP to clientapi.ipip.net (falling back to ipinfo.io) for geolocation. This happens for essentially every site you browse to, with no consent screen or opt-out toggle, and is not controlled by the extension's own 'Anonymously send identified urls' setting.

sbmzhcnv3.2.5Firefox Add-ons
45Risk
Who publishes it

sbmzhcn - no other listings under this identity, 8 shared hostnames

What this publisher told the store about itself, and the other listings that told it the same thing.

Shared hosts - 8 hostnames

Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.

break-day.com
Also called by 1 other listing: SERP Analyzer - Show domain owner & IP
data.tinycms.xyz
Also called by 1 other listing
leadscloud.github.io
Also called by 1 other listing: SERP Analyzer - Show domain owner & IP
sbmchina.com
Also called by 1 other listing: SERP Analyzer - Show domain owner & IP
sbmsolartech.com
Also called by 1 other listing: SERP Analyzer - Show domain owner & IP
zenithcrusher.com
Also called by 1 other listing
clientapi.ipip.net
Also called by 3 other listings
leancloud.cn
Also called by 3 other listings

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 FOUND

SERP Analyzer reports every site you visit to two outside lookup services

On every new site you visit, SERP Analyzer sends the hostname, your browser language and the site's server IP to a third-party domain lookup service and a Chinese IP-geolocation service, with no consent screen or opt-out toggle.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You navigate to a website and the page finishes loading.

Any http or https site qualifies except facebook.com, youtube.com, fbcdn.net, akamaihd.net, virtualearth.net and the Chrome Web Store.

The extension did this

The extension reports that site's hostname and server IP to two outside lookup services.

This runs automatically in the background; no click or popup is needed.

02EvidenceFIELD TABLE
What each lookup request carries
FieldValueWhy it matters
Hostname of the site you visited
shop.example.co.ukThe domain of the page you're on is sent to two outside services so they can look up who owns it and where it's hosted.
That site's server IP address
104.21.14.101The IP address behind the hostname, captured from the page's own network response, is forwarded for geolocation.
Your browser's UI language
en-USSent with the IP lookup even though geolocating a server IP doesn't need it.
03EvidenceCODE COMPARE
The code that does this

From navigation to two outbound requests, one hostname at a time

What it actually does
The navigation listenerserviceWorker.js:2198
chrome.tabs.onUpdated.addListener(function() {
  var e = p(d().mark((function e(t, r, n) {
    var o, a, c, i, s, u;
    return d().wrap((function(e) {
      for (;;) switch (e.prev = e.next) {
        case 0:
          if (n.url.startsWith("http")) {
            e.next = 4;
            break
          }
          chrome.action.disable(t), e.next = 18;
          break;
        case 4:
          if ("complete" != r.status) {
            e.next = 18;
            break
          }
          if (a = n.url) {
            e.next = 8;
            break
          }
          return e.abrupt("return");
        case 8:
          if (/^http(s)?:\/\//i.test(a)) {
            e.next = 10;
            break
          }
          return e.abrupt("return");
        case 10:
          return a = a.split("#")[0], c = new URL(a), i = c.hostname, s = null === (o = C.cache.hostnames) || void 0 === o ? void 0 : o[i], e.next = 15, C.resolve(i, s);
        case 15:
          return u = e.sent, e.next = 18, C.setIcon(a, u);
        case 18:
        case "end":
          return e.stop()
      }
    }), e)
  })));
  return function(t, r, n) {
    return e.apply(this, arguments)
  }
}())
Reporting the hostname to data.tinycms.xyzserviceWorker.js:1900
getDomainMetrics: function() {
  var e = arguments,
    t = this;
  return p(d().mark((function r() {
    var n, o, a, c, i, s, u;
    return d().wrap((function(r) {
      for (;;) switch (r.prev = r.next) {
        case 0:
          return n = e.length > 0 && void 0 !== e[0] ? e[0] : [], o = chrome.runtime.getManifest(), a = o.version, r.prev = 2, c = "https://data.tinycms.xyz/service/get-domain-metrics.php?version=".concat(a), r.next = 6, t.post(c, {
            domains: n,
            country: chrome.i18n.getUILanguage(),
            version: a,
            api_key: "",
            t: Date.now()
          }, P);
        case 6:
          return i = r.sent, r.next = 9, i.json();
        case 9:
          return s = r.sent, u = s.results, r.abrupt("return", u);
        case 15:
          r.prev = 15, r.t0 = r.catch(2);
        case 18:
        case "end":
          return r.stop()
      }
    }), r, null, [
      [2, 15]
    ])
  })))()
}
Reporting the site's IP to clientapi.ipip.net, falling back to ipinfo.ioserviceWorker.js:1850
get_ip_info: function(e, t) {
  var r = this;
  return p(d().mark((function n() {
    var o, a;
    return d().wrap((function(n) {
      for (;;) switch (n.prev = n.next) {
        case 0:
          return n.prev = 1, n.next = 4, r.get("https://clientapi.ipip.net/browser/chrome", {
            ip: e,
            l: navigator.language,
            domain: t
          });
        case 4:
          return o = n.sent, n.next = 7, o.json();
        case 7:
          if (0 === (a = n.sent).ret) {
            n.next = 17;
            break
          }
          return n.next = 11, fetch("https://ipinfo.io/".concat(e, "/json?token=6e7da5fe56e906"));
        case 11:
          return o = n.sent, n.next = 14, o.json();
        case 14:
          return a = n.sent, n.abrupt("return", {
            ret: 0,
            data: {
              ip: e,
              country_code: a.country,
              country: a.country,
              province: a.region,
              city: a.city,
              isp: a.org,
              asn: [],
              ports: []
            },
            dns: null
          });
        case 17:
          return n.abrupt("return", a);
        case 21:
          n.prev = 21, n.t0 = n.catch(1);
        case 24:
        case "end":
          return n.stop()
      }
    }), n, null, [
      [1, 21]
    ])
  })))()
}
04EvidenceTHIRD PARTY LIST
Where each visited hostname goes
  • data.tinycms.xyz

    Receives the visited hostname on an unbranded domain and returns a 'domain owner' label shown in the toolbar.

  • clientapi.ipip.net

    A Chinese IP-geolocation API. Receives the visited hostname, the site's server IP and your browser language.

  • ipinfo.io

    Fallback IP-geolocation lookup used when clientapi.ipip.net returns an error, called with a token hardcoded in the extension and shared by every install.

05EvidencePLAIN NOTE
The privacy toggle doesn't cover this

The one visible privacy control, 'Anonymously send identified urls to server', gates a separate feature, not the lookups above, which fire regardless. The only mitigation is a per-site disabled list in options.

06EvidencePLAIN NOTE
Observation

Static analysis finding. This behaviour was identified by reading the shipped extension code and has not yet been reproduced in a live run. The trigger conditions and the exact data sent are read from the code, not from an observed capture.

What it can do

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

    http://*/*

  • Read and change your data on every secure site you visit

    https://*/*

  • Run its own code inside the pages you visit

    scripting

  • Act on the current tab, but only after you click the extension

    activeTab

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

    tabs

  • Watch every request your browser makes

    webRequest

  • Store data in your browser

    storage

Where it sends data

Destinations our analysis observed SERP Analyzer 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.

  • ipinfo.iowidely used

    SERP Analyzer sends data to ipinfo.io. A widely used service: 45 other extensions we have analysed send data here.

  • data.tinycms.xyz

    SERP Analyzer sends data to data.tinycms.xyz. One other extension we have analysed sends data here.

  • clientapi.ipip.net

    SERP Analyzer sends data to clientapi.ipip.net. No other extension we have analysed sends data here.

Updated 30 September 2026amo-984911