Is Twitter Exporter safe?
We analyzed Twitter Exporter version 0.8.63's actual code and gave it a 52/100 trust score. Twitter Exporter is useful for X exports but has unusually…
Bottom line
Twitter Exporter is useful for X exports but has unusually powerful access to cookies, private messages, chat keys, and account data, plus developer analytics.
What it can access
It can read X cookies and private account content, including messages, and store/export it; this is powerful but broadly fits an X data-export tool. [Q1][Q2][Q3][Q14]
Security weaknesses
Sensitive cookies and chat keys are handled by a minified extension, while request-header changes and downloaded X code increase misuse and review risk. [Q7][Q10][Q18]
Signs of misuse
It sends daily usage data and paid-device details to its developer, including a persistent ID and fingerprint, beyond the core export. [Q6][Q13]
Code findings
What access does this extension ask for, and does that access make sense for what it claims to do?
It requests cookies and host access for x.com, services.x.com, and ton.x.com, plus scripting, activeTab, storage, alarms, idle, notifications, and declarativeNetRequest. These permissions support authenticated background exports of extensive X account data.
Declares all permissions, X host access, service worker, popup, and options page. — manifest.json:3
Which websites can it run on, and can it read or change what appears on those pages?
For an XChat export, it injects packaged inject.js into the active X tab. That script reads X's origin-private chat backup database and returns the newest private chat key; it does not edit forms or page content.
getPrivateKey executes /inject.js in the active tab on request. — background.js:20
Reads backups/chat_<user>.db and selects keypair-private material from dm_key_material. — inject.js:2
Can it see sensitive information you type, such as passwords, payment details, messages, or form entries?
It can retrieve a wide range of data from the signed-in X account through private GraphQL and REST services, including tweets, lists, bookmarks, likes, blocks, mutes, DMs, Grok chats, and XChat conversations.
Implements per-task clients for account, tweet, list, DM, XChat, Grok, block, mute, and bookmark exports. — background.js:3
Offers the corresponding export types in the task UI. — chunks/options-DChWN8xk.js:52-72
Can it access private browser data such as cookies, signed-in sessions, browsing history, bookmarks, or downloads?
Tasks, collected records, media blobs, progress cursors, plan state, analytics settings, and identifiers are persisted locally in IndexedDB or extension storage. XChat task state can include private-key and conversation-key material.
Task, media, and record DAOs persist export state and downloaded content; activation and analytics use key-value storage. — background.js:3
Can it access anything else on your device, such as files, location, camera, microphone, clipboard, or installed applications?
It reads sensitive private account content and XChat cryptographic material. It does not capture arbitrary website forms, keystrokes, passwords, screenshots, camera, or microphone.
Extracts the newest XChat private key from X's local chat database. — inject.js:2
Decrypts and converts encrypted chat messages and media for export. — background.js:3
Does it send information outside your browser? If so, what information is sent, where does it go, and why?
Account export data is sent to X's own services as needed and saved locally. The developer receives a daily analytics ping containing install ID, extension ID/version, and language; paid activation/checks send the activation code, random fingerprint, and device information.
Builds authenticated requests to X endpoints and stores returned data locally. — background.js:1-3
Analytics posts installId, extensionId, version, and language to api.extport.dev. — background.js:20
Licensing posts code, extensionId, fingerprint, and deviceInfo to api.extport.dev. — background.js:3
Does it download or run code, settings, or instructions supplied by a remote server?
It downloads X's current home page and JavaScript bundles to extract bearer tokens, GraphQL query IDs, and transaction metadata needed for X's changing private services. It also receives license decisions from its vendor.
Fetches x.com/home plus main and ondemand bundles and extracts tokens, resources, and query metadata. — background.js:1
Activation/check endpoints return the paid plan and expiry. — background.js:3
Can it take actions without a clear user request, such as opening pages, redirecting searches, downloading files, or sending requests?
User selection creates export tasks, but alarms, idle-state listeners, recovery logic, recurring tasks, and a background queue allow work to continue or resume without the popup remaining open. A daily analytics ping also runs on install/startup.
Creates a 30-second alarm, recovers/resumes tasks, supports recurring jobs, and attaches analytics on startup/install. — background.js:20
Can it change important browser settings, including your proxy, search engine, homepage, privacy settings, or other extensions?
No evidence of this behavior was found in the reviewed package.
No browser-setting, proxy, management, or downloads permissions are declared. — manifest.json:3
Is any important behavior difficult to inspect because the code is hidden, heavily obfuscated, dynamically generated, or supplied by third parties?
Most application code is minified into very large bundles, and embedded SQLite, libsodium, CSV, UI, and browser-compatibility libraries make review difficult. Security-sensitive flows were still identifiable, but the package is not readily auditable by a typical user.
Lists several 0.8-0.9 MB minified JavaScript bundles and an embedded WASM database runtime. — inventory.json:complete file
Does it use eval(), new Function(), or string-based timers to turn text into executable code?
No evidence of this behavior was found in the reviewed package.
CSP permits self scripts and packaged WebAssembly only. — manifest.json:3
Bundled CSV library builds a worker Blob from its packaged function. — chunks/options-DChWN8xk.js:62
Does it track the websites, pages, searches, or links you visit?
No evidence of this behavior was found in the reviewed package.
Queries the current active tab URL and maps supported X paths to export actions. — chunks/popup-BMIh0dOe.js:1
Tracks active-tab activation and URL updates to switch the toolbar action. — background.js:20
Does it create a persistent ID or browser fingerprint to recognize you?
Analytics creates a random persistent install ID and sends it once per day with extension/version and browser language. License state uses a separate random fingerprint plus browser/device details.
createAnalyticsPinger stores crypto.randomUUID() as installId and posts it daily. — background.js:20
Activation persists and transmits a random fingerprint with deviceInfo. — background.js:3
Does it send cookies, session details, authentication data, or page contents elsewhere?
It reads all cookies for x.com and uses the ct0 CSRF token, guest ID, language, X's bearer token, and generated transaction headers to make requests as the signed-in account. It also retrieves the XChat private key for encrypted chat export.
chrome.cookies.getAll reads x.com cookies; request construction uses ct0 and guest_id with X authorization headers. — background.js:1
Reads XChat private-key material from X's local database. — inject.js:2
Does it record typing, form entries, clipboard contents, or screenshots?
It can access highly sensitive personal content: bookmarks, likes, social graph, blocked and muted accounts, muted keywords, private DMs, Grok conversations, and decrypted XChat messages/media. This is expected for its export feature but creates severe exposure if abused.
Implements collection, decryption, normalization, and storage of the listed private data classes. — background.js:3
Can a website or remote server send commands that make the extension take actions?
No evidence of this behavior was found in the reviewed package.
Extracts current X API metadata from downloaded home/main/ondemand resources. — background.js:1
Vendor activation/check responses set tier and expiry. — background.js:3
Does it alter links, referral codes, advertisements, shopping carts, or search results?
No evidence of this behavior was found in the reviewed package.
Contains fixed Stripe links for Basic and Pro plans. — chunks/options-DChWN8xk.js:52
Does it redirect or modify web traffic, request headers, downloads, or proxy settings?
A declarativeNetRequest rule sets Origin and Referer to https://x.com/ for extension-initiated XMLHttpRequests to x.com and ton.x.com. This helps the exporter imitate X's first-party client but does not intercept or modify unrelated page traffic.
Installs one dynamic modifyHeaders rule scoped to the extension's own requests and X domains. — background.js:20
Can it communicate with software on the computer or services running on localhost?
No evidence of this behavior was found in the reviewed package.
No nativeMessaging or localhost access is declared. — manifest.json:3
Does it decode, decrypt, or unpack hidden data and then execute or inject it?
No evidence of this behavior was found in the reviewed package.
Remote bundle helpers fetch text and apply parsing routines before building fixed request objects. — background.js:1
Can ordinary websites access privileged extension features through messaging or exposed files?
No evidence of this behavior was found in the reviewed package.
Requests getPrivateKey only for x.com/i/chat exports. — chunks/popup-BMIh0dOe.js:1
Handles internal getPrivateKey and injects /inject.js into the active tab. — background.js:20
Does suspicious behavior activate only for certain users, websites, dates, or remote settings?
No evidence of this behavior was found in the reviewed package.
Task runner branches on plan limits, account identity, rate limits, task type, and recurrence. — background.js:3
Does it perform hidden resource-intensive work, such as cryptocurrency mining?
No evidence of this behavior was found in the reviewed package.
Background queue downloads pages/media, persists progress, retries, recovers stuck tasks, and schedules recurring jobs. — background.js:3, 20
Does it change form fields or where a form sends its information?
No evidence of this behavior was found in the reviewed package.
Visible export buttons open the extension options page for the selected X URL. — chunks/popup-BMIh0dOe.js:1
Export action creates a Blob/local download; upgrade action opens a fixed store URL. — chunks/options-DChWN8xk.js:55, 72