Is Ali Lens with Product Search By Image safe?

Medium risk

Ali Lens records the URL, title, and time spent on every site you visit and sends it to fulhar.com.

A content script that runs on every page you visit (not just AliExpress) records the page URL, title, referrer, and visible time, tagging each event with a persistent per-install ID and sending it in batches to fulhar.com. Tracking is on by default and is only disclosed in a collapsed accordion inside the extension's side panel. Separately, on any non-Amazon site, the extension rewrites Amazon product links so clicks route through fulhar.com first, which attaches the developer's own affiliate tag before forwarding you to the product page.

readyandmakesv3.0.7Chrome Web Store
45Risk

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

Ali Lens tracks every website you visit, not just AliExpress, and sends it out

Code analysis shows the extension records the full URL, title and referrer of every page you visit, not only AliExpress, and sends it to fulhar.com tagged with a persistent per-install id.

Tracking is on by default.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You load any page in your browser, not just an AliExpress page.

The tracker's manifest match pattern is http://*/* and https://*/*, so it runs on every top-level site you visit.

The extension did this

The extension records the page's full URL, title and referrer, then the background worker batches and sends it to fulhar.com.

This runs on every http or https page while tracking defaults to on; switching it off requires opening a collapsed section of the side panel.

02EvidenceFIELD TABLE
What each page-view event carries
FieldValueWhy it matters
Full page address
https://news.example.com/account/settings?token=9f2a1cThe exact page you're on, including anything after ? or # such as search terms or account ids in the URL.
Page title
Online Banking - Account SummaryThe <title> of the page, giving readable context about what you were doing there.
Referrer
https://www.google.com/search?q=mortgage+refinance+ratesThe page you came from, which can reveal a search query or another site you were just on.
How long you looked at the page
184000Time the page was actually visible to you, not just open in a background tab.
Persistent install id
6e2b6f2a-7a41-4c9d-9c2e-0a6b8d2f5e11A random id created when you installed the extension, sent with every event so your visits across every site can be tied together over time.
Browser language and time zone
en-US, America/ChicagoYour browser's language setting and time zone, added to every event.
03EvidenceCODE COMPARE
The code that does this

This code ships human-readable, with no minification or obfuscation to reverse

What it actually does
tracker.js: builds and sends a page-view event on every http/https pagetracker.js
function send(final) {
    if (!view) return;
    // Fold in whatever visible time has run since the last accounting, so the
    // number sent is correct whether the page is visible or not right now.
    var visible = view.visibleMs;
    if (view.visibleSince) visible += Date.now() - view.visibleSince;

    var event = {
      event_id: view.id,
      url: view.url,
      title: (document.title || '').slice(0, 512),
      referrer: view.referrer,
      session_id: view.session,
      started_at: new Date(view.startedAt).toISOString(),
      duration_ms: Math.round(visible),
      timezone: timezone(),
      language: (navigator.language || '').slice(0, 32),
    };
    if (final) event.ended_at = new Date().toISOString();

    try {
      // The worker may be asleep; waking it can fail while the tab is being
      // torn down, and a lost page view is not worth an error in the console
      // of somebody else's site.
      chrome.runtime.sendMessage({ type: 'ap-track', event: event, final: !!final },
        function () { void chrome.runtime.lastError; });
    } catch (e) {}
  }
tracker-bg.js: batches events and POSTs them tagged with a persistent visitor idtracker-bg.js
async function apTrackFlush() {
  if (apTrackSending) return;
  await apTrackLoadQueue();
  if (!apTrackQueue.length) return;

  const settings = await apTrackSettings();
  if (!settings.enabled) {
    apTrackQueue = [];
    await apTrackSaveQueue();
    return;
  }

  apTrackSending = true;
  const batch = apTrackQueue.slice(0, AP_TRACK_BATCH_MAX).map(function (e) {
    return Object.assign(
      { visitor_id: settings.visitorId, source: 'extension' }, e,
      { meta: Object.assign({ app: AP_TRACK_APP }, e.meta) });
  });

  let sent = false;
  try {
    const res = await fetch(settings.endpoint + 'track/batch/', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ events: batch }),
    });
    sent = res.status < 500;
  } catch (e) {
    sent = false;
  }
  apTrackSending = false;

  if (sent) {
    const done = new Set(batch.map(function (e) { return e.event_id; }));
    apTrackQueue = apTrackQueue.filter(function (e) { return !done.has(e.event_id); });
    await apTrackSaveQueue();
    if (apTrackQueue.length) apTrackScheduleFlush();
    return;
  }

  await apTrackSaveQueue();
  try { chrome.alarms.create(AP_TRACK_RETRY_ALARM, { delayInMinutes: 1 }); } catch (e) {}
}
04EvidenceTHIRD PARTY LIST
Where the data ends up
  • fulhar.com

    Receives the batched page-view events, tagged with an app id the source comments say is shared with the vendor's 1688 extension on the same backend.

05EvidenceARTIFACT
Check if you're affected

Reads this install's own tracking state directly from chrome.storage.local: whether tracking is on, the persistent visitor id, and any page views queued to be sent.

RequiresChrome or Edge with Ali Lens installedDeveloper mode enabled in chrome://extensions
check-tracking-state.js · js
chrome.storage.local.get(
  ['apTrackingEnabled', 'apVisitorId', 'apTrackQueue', 'apLifeQueue'],
  (store) => {
    console.log('Tracking enabled:', store.apTrackingEnabled !== false);
    console.log('Persistent visitor id:', store.apVisitorId);
    console.log('Queued page views waiting to send:', store.apTrackQueue);
    console.log('Queued lifecycle events waiting to send:', store.apLifeQueue);
  }
);
How to run it
  1. 1
    Open chrome://extensions and enable Developer mode.
  2. 2
    Find Ali Lens, click "service worker" to open its DevTools.
  3. 3
    Paste this script into the Console and press Enter.
  4. 4
    Read the three logged values.
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.

Data recipients

fulhar.com
Updated 20 September 2026gpplenaolkhneojcnohhekpekencapao