Is Ali Invoice FREE safe?

Medium risk

Ali Invoice FREE reroutes AliExpress product and store clicks through alitems.link affiliate tracking.

When you click AliExpress product or store links, the extension cancels the original navigation and opens an alitems.link affiliate URL containing the clicked AliExpress address. It also downloads configuration from app.aliinvoice.com that controls blocking and allow rules for AliExpress-related sites, and its AliExpress page UI fetches ad HTML from ads.dropshipping.store.

Dropshipping Storev0.1.3.4Chrome Web Store
51Risk
Who publishes it

MEDIA 019 - 4 other listings from the same operator, 3 of them carrying a finding

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

Publisher
Dropshipping Store
Declared legal entity
MEDIA 019
Registered address
JNA 1a, Negotin 19300, Serbia, Europe
Registered contact
Ivan Matic

Same store account

4 other listings published from this account, 20k+ users between them. 3 of them carry a finding.

Shared hosts - 1 hostname

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.

alitems.link
Also called by 2 other listings, including Ali Insider- AliExpress Product Research Tool

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

Publishers can request a review.

Findings

AliExpress clicks rerouted through alitems.link

The extension adds click handlers to AliExpress product/store links.

Clicking one sends the stripped destination from the content script to the service worker, which opens an alitems.link URL containing the destination you meant to visit.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-506
Source
Static analysis
What actually happens
You did this

You click an AliExpress product or store link.

The content script only attaches this handler when the saved daily reload marker is not already set for the current date.

The extension did this

The extension opens an alitems.link affiliate URL that includes the AliExpress page you clicked.

The original click handler returns false after sending the stripped destination URL to the service worker.

Fields in the affiliate navigation URL
  • Affiliate destination type
    d=c

    Identifies the outbound navigation as the extension's affiliate redirect path.

  • Referral code
    r=in

    Links the click to the referral code embedded in the extension's service worker.

  • Extension campaign code
    s=aif

    Marks this click as coming from the free Ali Invoice extension flow.

  • Clicked AliExpress page
    https://www.aliexpress.com/item/1005001234567890.html (illustrative)

    Shows the product or store page you intended to open before the affiliate redirect was used.

Captured request
GEThttps://alitems.link/a/?d=c&r=in&s=aif&u=https://www.aliexpress.com/item/1005001234567890.html

Affiliate redirect navigation opened by the service worker; no request body is used.

The code that does this

The content script forwards clicked AliExpress URLs and the service worker opens alitems.link

Readable version

Content-script click handler

js/aliexpress.js
function modifyUrl(url) {    return url.startsWith("//") && (url = location.protocol + url), url.startsWith("/item") && (url = location.protocol + "//" + location.host + url), url ? url.split("?")[0] : null}function doRefresh(url) {    return !!url.includes("/item") || !!url.includes("/store")}var sendMessageToBack = function (args) {        chrome.runtime.sendMessage({            action: "_ont",            url: args?.url ? args.url : null        }, (function (response) {            return !0        }))    },    attachListeners = function () {        intervalId = setInterval((function () {            $("*").toArray().forEach((item => {                $(item).attr("href") && ($(item).hasClass("alii-163511261sfa") || doRefresh($(item).attr("href")) && ($(item).addClass("alii-163511261sfa"), $(item).click((function (e) {                    return clearInterval(intervalId), sendMessageToBack({                        url: modifyUrl($(item).attr("href"))                    }), localStorage.setItem("reload", danasnji), detachAllListeners(), !1                }))))            }))        }))    },    detachAllListeners = function () {        $(".alii-163511261sfa").toArray().forEach((item => {            $(item).off("click")        }))    };rel_datum != danasnji && attachListeners();

Service-worker affiliate tab creation

js/background.js
console.log("Ali Invoice Free"), chrome.runtime.onMessage.addListener((function (request, sender, sendResponse) {    if (console.log("Request ", request), "_ont" == request?.action && (chrome.tabs.create({            active: !1,            index: sender?.tab?.index + 1,            url: "https://alitems.link/a/?d=c&r=in&s=aif&u=" + (request?.url ? request.url : "https://aliexpress.com")        }), proveri_p_k(!0), sendResponse(!0)), "SCRAPE_SINGLE_ORDER_DATA" == request?.messageType && chrome.tabs.create({            active: !1,            url: request?.url        }), "SCRAPE_SINGLE_LOGISTICS_DATA" == request?.messageType && request.options.hasOwnProperty("orderId") && chrome.storage.sync.get(null, (function (data) {            console.log(data), data.iL ? chrome.tabs.update({                url: "https://www.aliexpress.com/p/tracking/index.html?tradeOrderId=" + request.options.orderId + "&scrape-single=f"            }) : chrome.tabs.update({                url: chrome.runtime.getURL("../single-invoice.html")            })        })), "OPEN_SINGLE_INVOICE" == request?.messageType && request.options.hasOwnProperty("orderId") && chrome.tabs.update({            url: chrome.runtime.getURL("../single-invoice.html")        }), "CHECK_PERMISSIONS" === request.messageType) try {        return awaitForCheckPermissions().then((res => {            sendResponse(res)        })).catch((error => console.log("Error"))), !0    } catch (error) {        console.log("Error")    }}))
External destination used for the click reroute
    • alitems.link

    Receives the affiliate navigation URL, including the AliExpress product or store URL in the u query parameter.

Remote rules control AliExpress page blocking

The service worker posts to app.aliinvoice.com on install, update, and affiliate-click refresh.

The returned lk config is stored, decoded, and turned into dynamic main-frame block/allow rules for the extension's permitted AliExpress hosts.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-506
Source
Dynamic sandbox
What actually happens
You did this

The extension installs, updates, or refreshes its remote configuration.

The same refresh is also called after the affiliate-click service-worker path.

The extension did this

It downloads URL-rule configuration and applies main-frame block or allow decisions from that response.

Entries in the k array become block rules; entries in the l array become allow rules.

Captured request
POSThttps://app.aliinvoice.com/lk/

JSON rule configuration is parsed and stored under chrome.storage.sync key lk; no request body is recorded.

Headers
IDS
3
X-Extension-Request
chniojlpokhaobfkdihilpfafgoealpp
Remote configuration fields used as navigation rules
  • Extension identifier header
    chniojlpokhaobfkdihilpfafgoealpp

    Identifies which extension is asking the remote server for configuration.

  • Rule endpoint selector
    IDS: 3

    Selects the lk configuration path used for navigation-rule updates.

  • Block-list entry
    aliexpress.com/item (illustrative)

    Can tell the extension which matching AliExpress-related page URLs to block in the main frame.

  • Allow-list entry
    s.click.aliexpress.com (illustrative)

    Can tell the extension which matching AliExpress-related page URLs should be allowed instead.

The code that does this

Remote lk configuration is fetched, decoded, and installed as dynamic rules

Readable version

Install and update trigger configuration refresh

js/background.js
async function onInstall() {    var initStorage = {        sellersInfo: {},        nI: "5",        yN: ("YOUR COMPANY NAME", "YOUR COMPANY NAME"),        iC: !0,        yA: ("YOUR ADDRESS", "YOUR ADDRESS"),        yC: ("YOUR CITY, STATE, COUNTRY & ZIP", "YOUR CITY, STATE, COUNTRY & ZIP"),        yD: "Reg. number:</br>VAT number",        yR: "YOUR REGISTRATION NUMBER</br>YOUR VAT NUMBER",        iL: !0,        iS: !0,        sS: !0,        oD: !1,        vE: ("1", "1"),        cS: !1,        c1: "",        c2: "",        adtC: !1,        adtT: "",        adtV: "",        adtV2: "",        iG: "",        oN: "",        issaved: !1    };    chrome.storage.sync.set(initStorage, (function () {        chrome.tabs.create({            url: "chrome-extension://" + chrome.runtime.id + "/options.html"        })    })), await pp(), await lk(), proveri_p_k()}async function onUpdate() {    await pp(), await lk(), proveri_p_k()}

lk endpoint POST and storage write

js/background.js
async function lk() {    return new Promise(((resolve, reject) => {        fetch("https://app.aliinvoice.com/lk/", {            method: "POST",            headers: {                "X-Extension-Request": chrome.runtime.id,                IDS: "3"            }        }).then((function (response) {            return response.json()        })).then((function (mJ) {            mJ.d = Date.now(), chrome.storage.sync.set({                lk: mJ            }, (function () {                resolve(mJ)            }))        })).catch((function (error) {            console.log(error)        }))    }))}

Decoded k/l entries become dynamic main-frame rules

js/background.js
async function p_k() {    return new Promise(((resolve, reject) => {        chrome.storage.sync.get(null, (function (r) {            if (r.lk !== undefined) {                for (k = !!r.lk.k && r.lk.k, i = 0; i < k.length; i++) k[i] = dU(k[i]);                for (l = !!r.lk.l && r.lk.l, i = 0; i < l.length; i++) l[i] = dU(l[i]);                resolve({                    k: k,                    l: l                })            }        }))    }))}function updateRules() {    chrome.declarativeNetRequest.getDynamicRules((existingRules => {        const existingRuleIds = existingRules.map((rule => rule.id)),            k_newRuleIds = k.map(((_, index) => index + 1)),            k_index = k_newRuleIds.length,            l_newRuleIds = l.map(((_, z_index) => k_index + z_index + 1)),            allRuleIds = [...existingRuleIds, ...k_newRuleIds, ...l_newRuleIds],            uniqueRuleIds = [...new Set(allRuleIds)];        chrome.declarativeNetRequest.updateDynamicRules({            removeRuleIds: uniqueRuleIds,            addRules: [...k.map(((url, index) => ({                id: index + 1,                priority: 1,                action: {                    type: "block"                },                condition: {                    urlFilter: url,                    resourceTypes: ["main_frame"]                }            }))), ...l.map(((url, index) => ({                id: k.length + index + 1,                priority: 2,                action: {                    type: "allow"                },                condition: {                    urlFilter: url,                    resourceTypes: ["main_frame"]                }            })))]        })    }))}
Remote host that supplies rule configuration
    • app.aliinvoice.com

    Receives the extension configuration request and returns the lk rule configuration consumed by the service worker.

Every AliExpress page load pings a third-party ad server

The content script fetches ads.dropshipping.store/img/3.php on every AliExpress load, before you interact, blocking rendering until done.

Three requests were captured in one session, each a 200 with an ad snippet plus a country value.

Severity
Low unwanted
Type
Unexpected
CWE
CWE-359
Source
Dynamic sandbox
What actually happens
You did this

You open an AliExpress order, product, or store page.

Any URL matching *.aliexpress.com, *.aliexpress.ru, or *.aliexpress.us loads the extension's content script.

The extension did this

The content script makes a synchronous GET request to a third-party ad server before the page finishes loading.

The request goes to ads.dropshipping.store and blocks script execution until the ad server responds.

Captured request
GEThttps://ads.dropshipping.store/img/3.php

HTTP 200, 776-byte HTML response containing an ad snippet and a server-side geolocation comment (observed as `<!-- country=GB -->` in our test session, derived from the request's source IP, no location data is sent by the extension).

The code that does this

The content script fetches and renders third-party ad content on every matched page load

Readable version

Synchronous ad fetch at module load

js/components/interface.js
var moja_reklama = $.ajax({    type: "GET",    url: "https://ads.dropshipping.store/img/3.php",    cache: !0,    dataType: "html",    async: !1,    success: function (data) {        vratime = data    },    error: function (err) {        vratime = "", console.log("error:", err.statusText)    }}).responseText;

Ad response inserted into the extension's UI panel

js/components/interface.js
newMethodInterface = () => '<div class="me-ui-box" style="display:flex; padding: 15px; background: #fff; font-size: 12px; margin-bottom: 15px;"><div style="width:60%;display:inline-block;">' + moja_reklama + '</div>...'
Third-party host contacted on every matched page load
    • ads.dropshipping.store

    Receives a GET on every AliExpress page load and returns HTML ad content rendered into the extension's UI; the request discloses the user's source IP to this host.

What it can do

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

    *://*.aliexpress.com/*

  • Read and change your data on aliexpress.ru

    *://*.aliexpress.ru/*

  • Read and change your data on aliexpress.us

    *://*.aliexpress.us/*

  • Read and change your data on dropshipping.store

    *://*.dropshipping.store/*

  • Read and change your data on aliinvoice.com

    *://*.aliinvoice.com/*

  • Store data in your browser

    storage

declarativeNetRequestWithHostAccess

Where it sends data

Destinations our analysis observed Ali Invoice FREE 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.

  • alitems.link

    Ali Invoice FREE sends data to alitems.link. 4 other extensions we have analysed send data here.

  • app.aliinvoice.com

    Ali Invoice FREE sends data to app.aliinvoice.com. One other extension we have analysed sends data here.

  • ads.dropshipping.store

    Ali Invoice FREE sends data to ads.dropshipping.store. No other extension we have analysed sends data here.

Updated 30 September 2026chniojlpokhaobfkdihilpfafgoealpp