Is AliDownloader | Download AliExpress images safe?
AliDownloader is medium risk. The content script attaches click handlers to AliExpress item and store links, sends the URL to the background script, which opens an inactive tab to clickwrap.xyz with that URL plus affiliate params cpa and subid=alid, no consent shown.…
Who publishes itMladen Markovic - 2 other listings from the same operator, 2 of them carrying a finding
Mladen Markovic - 2 other listings from the same operator, 2 of them carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same store account
2 other listings published from this account, 8k+ users between them. 2 of them carry a finding.
Shared hosts - 2 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.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
AliExpress links are forwarded to clickwrap.xyz
The content script attaches click handlers to AliExpress item and store links, sends the URL to the background script, which opens an inactive tab to clickwrap.xyz with that URL plus affiliate params cpa and subid=alid, no consent shown.
You click certain AliExpress item or store links.
The content script checks link targets that contain /item or /store.
The extension opens an inactive tab to clickwrap.xyz with the selected URL attached.
The request URL includes cpa and subid=alid parameters before the original destination URL.
| Field | Value | Why it matters | |
|---|---|---|---|
Selected destination URL | https://www.aliexpress.com/item/1005001234567890.html | Shows the AliExpress item or store page you clicked. | |
Affiliate sub ID | alid | Labels the request for the affiliate endpoint. | |
Cost-per-action path | /cpa | Routes the request through the affiliate tracking path before the selected destination URL. |
The link click and inactive affiliate tab paths are present in shipped code
pc = (t, e, r, o) => {
var n, a;
return o && clearInterval(o), (null == (n = {
url: (a = e, a.startsWith("//") && (a = location.protocol + a), a.startsWith("/item") && (a = location.protocol + "//" + location.host + a), a.split("?")[0])
}) ? void 0 : n.url) && chrome.runtime.sendMessage({
action: sr,
url: (null == n ? void 0 : n.url) ? n.url : null
}, (function(t) {
return !0
})), document.querySelectorAll(`.${dc}`).forEach((t => {
t.removeEventListener("click", (t => pc(t, "", (() => {}))))
})), r(), t.preventDefault(), !1
}mc = () => {
chrome.storage.local.get(null, (function(t) {
const e = (t => {
const e = t.getDate(),
r = t.getMonth(),
o = t.getFullYear();
return `${e} ${["January","February","March","April","May","June","July","August","September","October","November","December"][r]} ${o}`
})(new Date);
(null == t ? void 0 : t[sr]) !== btoa(`${e}${uc}`) && (t => {
const e = setInterval((() => {
document.querySelectorAll("*").forEach((r => {
const o = r.href;
var n;
o && (r.classList.contains(dc) || ((n = o).includes("/item") || n.includes("/store")) && (r.classList.add(dc), r.addEventListener("click", (r => pc(r, o, t, e)))))
}))
}), 1e3)
})((() => {
chrome.storage.local.set({
[sr]: btoa(`${e}${uc}`)
}, (function() {}))
}))
}))
}chrome.runtime.setUninstallURL("https://tally.so/r/3y0pA8"), chrome.runtime.onMessage.addListener(((e, t, r) => {
var s, h;
return (null == e ? void 0 : e.action) == l && chrome.tabs.create({
active: !1,
index: (null === (s = null == t ? void 0 : t.tab) || void 0 === s ? void 0 : s.index) ? (null === (h = null == t ? void 0 : t.tab) || void 0 === h ? void 0 : h.index) + 1 : 1,
url: "http://clickwrap.xyz/cpa?subid=alid&url=" + ((null == e ? void 0 : e.url) ? e.url : "https://aliexpress.com")
}), (null == e ? void 0 : e.messageType) == i ? (Ar(null == e ? void 0 : e.textMessage, t, null == e ? void 0 : e.toastType), void r(!0)) : (null == e ? void 0 : e.messageType) == u ? (Pr(void 0, void 0, void 0, (function*() {
(null == e ? void 0 : e.base64String) && (null == e ? void 0 : e.filename) && (yield chrome.downloads.download({
url: null == e ? void 0 : e.base64String,
filename: null == e ? void 0 : e.filename
}), r(!0))
})), !0) : (null == e ? void 0 : e.messageType) == n ? (Pr(void 0, void 0, void 0, (function*() {
yield Cr(null == e ? void 0 : e.data, t), r(!0)
})), !0) : e.messageType == o ? (Pr(void 0, void 0, void 0, (function*() {
try {
const e = yield Dr();
r(e)
} catch (e) {
return {
contextMenus: !1,
usDomain: !1
}
}
})), !0) : (null == e ? void 0 : e.messageType) == c ? (Pr(void 0, void 0, void 0, (function*() {
try {
yield y(e.name, e.params), r(!0)
} catch (e) {
E(e, "Error while sending GA event"), r(!1)
}
})), !0) : e.messageType != a || !(null == e ? void 0 : e.permissionType) || (Pr(void 0, void 0, void 0, (function*() {
try {
const n = yield(t = e.permissionType, Or(void 0, void 0, void 0, (function*() {
return new Promise((e => {
try {
if ("contextMenus" === t) chrome.permissions.request({
permissions: ["contextMenus"]
}, (t => {
e(t)
}));
else {
if ("aliUsDomain" !== t) throw new Error("Invalid permission type");
chrome.permissions.request({
origins: ["*://*.aliexpress.us/*"]
}, (t => {
e(t)
}))
}
} catch (t) {
e(!1)
}
}))
})));
r(n), "contextMenus" === e.permissionType && n && (yield Tr())
} catch (e) {
r(!1)
}
var t
})), !0)
}))- clickwrap.xyz
Receives the selected AliExpress URL through an affiliate-style cpa URL with subid=alid.
AliDownloader posts usage events with a persistent ID
When you use AliDownloader actions like the image-download context menu, the extension posts a usage event to api.alibill.net.
It reads or creates a stored client ID and attaches it; dynamic analysis confirmed the POST but not the body.
You use an AliDownloader download action on an AliExpress page.
The right-click image-download path is one confirmed trigger.
The extension posts a usage event with a persistent client ID to api.alibill.net.
Dynamic analysis confirmed the POST request, while the shipped code shows the JSON fields assembled for the request.
| Content-Type | application/json |
| Field | Value | Why it matters | |
|---|---|---|---|
Usage event | RIGHT_CLICK_IMAGE_DOWNLOADED | Shows which extension action you used. | |
Persistent client ID | 6f3a4a59-0a9f-4d7e-a4f8-3562e69b9b65 | Lets the analytics endpoint connect multiple extension events from the same browser profile. | |
Event parameters | {} | Adds action-specific context when the caller supplies it. |
The stored identifier and analytics POST are in the shipped background bundle
function y(e) {
return v(this, arguments, void 0, (function*(e, t = {}) {
const r = yield _(d.GA_CLIENT_ID);
let n = "string" == typeof r ? r.trim() : "";
0 === n.length && (n = crypto.randomUUID(), yield g(d.GA_CLIENT_ID, n));
const i = {
eventName: e,
clientId: n,
params: t
};
return yield fetch("https://api.alibill.net/service/analytics/ga?extension=alidownloader", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(i)
}), !0
}))
}const Tr = () => Pr(void 0, void 0, void 0, (function*() {
(yield xr(void 0, void 0, void 0, (function*() {
return new Promise((e => {
try {
chrome.permissions.contains({
permissions: ["contextMenus"]
}, (t => e(t)))
} catch (t) {
return e(!1)
}
}))
}))) && chrome.contextMenus.removeAll((() => {
chrome.contextMenus.create({
contexts: ["image"],
title: "Download with AliDownloader",
id: "downloadImage",
documentUrlPatterns: ["*://*.aliexpress.com/*", "*://*.aliexpress.ru/*", "*://*.aliexpress.us/*"]
}, (() => {
chrome.runtime.lastError || chrome.contextMenus.onClicked.addListener(((e, t) => Pr(void 0, void 0, void 0, (function*() {
if (e.srcUrl) {
y(m.RIGHT_CLICK_IMAGE_DOWNLOADED);
const t = br(e.srcUrl),
r = wr(e.srcUrl);
if (t) {
const e = yield Er({
url: t
});
e && chrome.downloads.download({
url: e,
filename: r
})
}
}
}))))
}))
}))
}))- api.alibill.net
Receives AliDownloader usage analytics events with the stored client ID.
What it can do
Permissions this extension asks for, as declared in version 2.2.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 alicdn.com
*://*.alicdn.com/*
Read and change your data on cloud.video.taobao.com
*://cloud.video.taobao.com/*
Read and change your data on aliexpress.com
*://*.aliexpress.com/*
Read and change your data on alidownloader.com
*://*.alidownloader.com/*
Read and change your data on aliexpress.ru
*://*.aliexpress.ru/*
Start, monitor and manage your downloads
downloads
See the address and title of every tab you have open
tabs
Store data in your browser
storage