Is HaHa Wallet safe?

High risk

HaHa Wallet is high risk. We observed HaHa Wallet send visited hostnames to lookup.phishfort.com as you browse. The background worker listens for each HTTP/HTTPS navigation, derives the hostname, and GETs PhishFort's lookup API with it in the domain parameter.…

HaHa Technologies Inc.v1.8.1Chrome Web Store
75Risk
Who publishes it

HaHa Technologies Inc. - no other listings under this identity, 2 shared hostnames

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
HaHa Technologies Inc.
Declared legal entity
HaHa Technologies Inc.
Registered address
1401 Lavaca St, Ste 41143, Austin, TX 78701, US

Shared hosts - 2 hostnames

Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.

proxy.api.cx.metamask.io
Also called by 1 other listing: Dlicom - Crypto Wallet
nft.api.cx.metamask.io
Also called by 6 other listings, including Dlicom - Crypto Wallet, MetaMask

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

Publishers can request a review.

Findings

Visited hostnames sent to PhishFort on navigation

We observed HaHa Wallet send visited hostnames to lookup.phishfort.com as you browse.

The background worker listens for each HTTP/HTTPS navigation, derives the hostname, and GETs PhishFort's lookup API with it in the domain parameter.

Severity
High unwanted
Type
Unexpected
CWE
CWE-359
Source
Dynamic sandbox
What actually happens
You did this

You open an HTTP or HTTPS page.

The extension did this

The extension sends the visited site's hostname to a PhishFort lookup endpoint.

The request happens from the background service worker before any warning-page redirect decision.

Captured request
GEThttps://lookup.phishfort.com/api/lookup?domain=www.google.com

Dynamic analysis captured 60 matching GET requests; observed domain values included www.google.com and www.amazon.com.

Fields involved in the PhishFort lookup
  • Visited hostname
    www.google.com

    This shows which site you opened, even though the full page path is not included in the lookup request.

  • Browsing event
    Navigation to www.amazon.com

    Each request corresponds to a page navigation, so repeated requests form a record of sites you visited while the extension was active.

  • Lookup destination
    lookup.phishfort.com/api/lookup

    The hostname leaves your browser and reaches a third-party lookup service.

The code that does this

Navigation listener and PhishFort lookup request

Readable version
const t = new URL(e.url).hostname;if (F.has(t)) return;const n = await fetch(`https://lookup.phishfort.com/api/lookup?domain=${t}`);
External destination receiving visited hostnames
    • lookup.phishfort.com

    Receives the visited hostname in the domain query parameter and returns whether the extension should redirect to a warning page.

Signup flow fetches and sends public IP metadata

The extension fetches your public IP from api.ipify.org during registration, adding it as ip_address in the AWS Cognito SignUp ClientMetadata.

A separate helper fetches ipwho.is data for the MoonPay currency check, both using IP lookups.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-359
Source
Dynamic sandbox
What actually happens
You did this

You register for the wallet or use the currency-support feature.

These are user-initiated flows, not normal browsing triggers.

The extension did this

The extension fetches your public IP address and region context for those flows.

The registration helper passes ip_address in Cognito client metadata, and the MoonPay support check calls the country-code helper.

Fields used in registration and currency-support checks
  • Public IP address
    198.51.100.42

    This can identify the network you are using and can be linked to signup activity.

  • Country code
    US

    This gives the service coarse location context for currency availability decisions.

  • Region code
    CA

    This can narrow the location context further when the country has regional restrictions.

  • Client platform
    extension

    This labels the signup as coming from the browser extension.

Captured request
GEThttps://api.ipify.org?format=json

The helper expects JSON containing the public IP address; no request body is present for this GET request.

Captured request
GEThttps://ipwho.is/

The helper reads country_code and region_code from the JSON response; no request body is present for this GET request.

Captured request
POSThttps://cognito-idp.us-east-1.amazonaws.com/

The code sends AWS Cognito SignUp data with ClientMetadata; no captured request body was recorded for this claim.

Headers
Content-Type
application/x-amz-json-1.1
X-Amz-Target
AWSCognitoIdentityProviderService.SignUp
X-Amz-User-Agent
aws-amplify/0.1.x js
The code that does this

IP lookup helpers and Cognito registration metadata

Readable version

Readable Cognito request wrapper and register metadata

scripts/background.js
const u = (e, t) => (0, a.default)({  method: "POST",  headers: {    "Content-Type": "application/x-amz-json-1.1",    "X-Amz-Target": e,    "X-Amz-User-Agent": "aws-amplify/0.1.x js"  },  url: "https://cognito-idp.us-east-1.amazonaws.com/",  data: t});t.register = (e, t, n, r) => {  const a = {    os: "extension",    ip_address: n,    appCheckToken: r  };  return c.default.log("✅ clientMetadata", a), u("AWSCognitoIdentityProviderService.SignUp", {    ClientId: "heb0eptuhmis6p9ob6f8g3n",    Username: e,    Password: t,    UserAttributes: [{      Name: "email",      Value: e    }],    ClientMetadata: a  })}

Readable IP and country lookup helpers

scripts/background.js
t.getIPAddress = () => (0, a.default)({  method: "GET",  headers: {},  url: "https://api.ipify.org?format=json",  params: {}});t.getCountryCode = () => fetch("https://ipwho.is/").then((e => e.json())).then((e => ({  data: e})))

Readable MoonPay currency support check using country and region

scripts/background.js
async checkMoonPaySupportedCurrency(e, t, n = "buy") {  try {    const r = this.getPreferences().moonPayCurrencies;    if (!r || !Array.isArray(r)) return s.default.log("💰💰💰 MoonPay currencies not available"), null;    const a = r.find((n => n.metadata?.contractAddress?.toLowerCase() === e.toLowerCase() && n.metadata?.chainId === t));    if (!a) return s.default.log("💰💰💰 MoonPay currency not found", e, t), null;    if (a.isSuspended) return s.default.log("💰💰💰 MoonPay currency is suspended", a.name), null;    if ("sell" === n && !a.isSellSupported) return s.default.log("💰💰💰 MoonPay currency does not support sell", a.name), null;    const o = !1;    if (!(o ? a.supportsTestMode : a.supportsLiveMode)) return s.default.log("💰💰💰 MoonPay currency does not support current mode", a.name, o ? "test" : "live"), null;    let c = null,      u = null;    try {      const e = await (0, i.getCountryCode)();      c = e.data.country_code || null, u = e.data.region_code || null    } catch (e) {      s.default.error("💰💰💰 Error getting country code", e)    }    return "US" !== c || a.isSupportedInUS ? c && a.notAllowedCountries.includes(c) ? (s.default.log("💰💰💰 MoonPay currency not allowed in country", a.name, c), null) : "US" === c && u && a.notAllowedUSStates.includes(u) ? (s.default.log("💰💰💰 MoonPay currency not allowed in US state", a.name, u), null) : (s.default.log("💰💰💰 MoonPay currency is supported", a), a) : (s.default.log("💰💰💰 MoonPay currency not supported in US", a.name), null)  } catch (e) {    return s.default.error("💰💰💰 Error checking MoonPay supported currency", e), null  }}
External hosts named by the registration and currency paths
    • api.ipify.org

    Returns the public IP address used as registration metadata.

    • ipwho.is

    Returns country and region data used by the currency-support check.

    • cognito-idp.us-east-1.amazonaws.com

    AWS Cognito endpoint receiving the SignUp request with ClientMetadata.

Updated 30 September 2026andhndehpcjpmneneealacgnmealilal