Wallet-drainer approvals
Seed-phrase harvest pages
Support impersonation
Fake airdrop claims
Exchanges · Wallets · Custodians

When settlement cannot be reversed, the only spending that counts is the spending before the signature

A cloned exchange login, a recovery-phrase form, an approval prompt dressed as a token claim — each one converts into an on-chain transfer that no support queue can unwind. This page is about putting a DNS-verified list of currently-live phishing hostnames in front of the handful of moments where a user is about to type, paste or sign.

390,000+DNS-verified phishing domains, every one currently resolving
24 hoursFull rebuild cadence, with an added and removed changelog
Under 50 msTypical lookup, fast enough to sit inside a paste handler
One directionWhat a signed transfer does, and what a blocklist tries to precede
Scroll
Centralised exchanges
Self-custody wallets
Qualified custodians
Browser extensions
Community & support channels
dApp directories
Home / Use Cases / Cryptocurrency
Settlement

Irreversibility does not make the loss bigger. It moves the whole budget to the left of it.

Every control an organisation buys sits somewhere on a timeline running from “nothing has happened yet” to “we are writing to the customer.” On-chain finality deletes most of that timeline.

Provisional settlement

A card issuer has a mechanism waiting for it

There is a scheme rulebook, a dispute window, a merchant with a bank account, and an intermediary whose job is to move the money back. The apparatus exists because the underlying settlement stays provisional for days or weeks after the customer taps. Detection that arrives late still recovers something, so it is entirely rational for a card business to spend heavily on analytics that run after authorisation.

Final settlement

A transfer included in a block has no equivalent

There is no counterparty holding the funds who can be compelled to return them, no reversal primitive in the protocol, and no window in which the decision can be revisited. The assets are where the attacker put them, and the next thing that happens is that they move again. Analytics that run after the fact recover nothing at all.

The practical consequence is not that crypto firms need more security spending than a bank; it is that the spending has a different shape. Post-incident tooling that would be a sound investment for a payment processor buys you almost nothing here beyond an accurate account of what you lost. What retains value is anything that intervenes in the seconds before a credential is typed or a transaction is signed — and, crucially, anything cheap enough to evaluate in the path of every user rather than only the ones a risk model has already flagged. A hostname lookup returning in tens of milliseconds meets both conditions. It is the sort of control you can afford to run on every link in every support ticket instead of on a sample. Custodial and non-custodial platforms feel that differently, and should design differently as a result.

Custodial

A centralised exchange still owns a window

A stolen credential is not yet a loss, because the withdrawal is an internal state change the exchange controls, and it can be queued, delayed, re-authenticated or refused. That window is the exchange's most valuable asset during an incident, and much of what follows on this page is about widening it.

Non-custodial

A self-custody wallet has no window at all

The approval is the settlement. Between the user's click and the irreversible outcome there is no queue, no review and nobody to call, which is why wallet vendors end up putting the check in the least glamorous place available — the navigation event itself.

And then there is the part that is nobody's fault and cannot be trained away. This ecosystem asks ordinary people to hold a mental model containing private keys, recovery phrases, contract addresses, spending allowances, chain identifiers and bridge intermediaries, and it presents all of them through interfaces built by different teams with different conventions. A user who has never performed a legitimate wallet migration has no baseline against which to judge a fake one. A user who has approved a token spend twice in six months cannot tell an unlimited allowance from a bounded one by looking at it. Attackers do not need to defeat anyone's judgement; they only need to occupy the large territory where no judgement has been formed yet.

Blocking at the hostname is a deliberately modest answer to that. It does not attempt to interpret the transaction, score the contract, or decide whether the user meant it. It answers one narrow, factual question — is this host on a list of domains confirmed to be live phishing infrastructure — at a point where the answer is still actionable. The narrowness is the feature. It is what lets the same verdict be reused by the support desk, the mobile app, the extension and the resolver without any of them first having to agree on a risk policy.

Attack shapes

Nine hostname-bearing lures, and what each one is actually asking for

They differ in staging and in what they take, but every one of them needs a user to arrive at a hostname the attacker registered. That is the shared choke point.

01

The cloned exchange login

A pixel-accurate copy of a well-known sign-in page served from a look-alike host. The better ones proxy the real site live, so the second factor the victim types is relayed inside its validity window and the resulting session is genuine.

Takes: the session
02

The recovery-phrase form

A page asking for twelve or twenty-four words, framed as validation, restoration or a security check. No legitimate service ever needs them, which is exactly why the page has to look official enough to override that rule.

Takes: the wallet
03

The drainer approval flow

A connect button, a friendly prompt, and a signature request granting a contract broad spending rights over tokens already held. Nothing is phished at all; the victim authorises the transfer and the sweep follows within seconds.

Takes: balances
04

The airdrop and claim page

Free allocation, early access, retroactive reward. The lure supplies urgency and the wallet connection supplies the loss. Domains are minted around whichever term is trending that week, which makes them short-lived and numerous rather than clever.

Takes: balances
05

Support impersonation

Someone posts a problem in a public channel and gets a helpful reply within minutes from an account whose handle differs by one character. The conversation moves to a direct message and ends at a verification portal the real desk has never heard of.

Takes: credentials
06

Presale and token-sale domains

A whole fake fundraise: a site, a countdown, a deposit address, sometimes a cloned paper. Here the hostname is not imitating an existing brand, it is manufacturing a new one, which makes look-alike matching useless and verified observation the only signal.

Takes: deposits
07

Extension impersonation

A wallet add-on with the right name and icon, distributed from a download page the attacker controls or promoted through paid placement. The install itself is the compromise; every later interaction happens inside software that is already hostile.

Takes: everything
08

Look-alike registration

Mixed-script characters that render identically, a hyphen inserted, a familiar brand pushed down into a subdomain of something else, or the same word under a top-level domain the real company has never used. Cheap, endlessly repeatable, and effective on a phone.

Takes: attention
09

The migration notice

Mail or an in-app banner announcing that accounts or wallets are moving to a new system and must be re-verified by a date. It works because platforms genuinely do migrate, and because the notice arrives through a channel the user already trusts.

Takes: credentials

Reading down the column of what each one takes is more useful than reading the descriptions. Three of the nine take a credential, which means an exchange with a functioning withdrawal review still has a chance to intervene. Three take a signature, which means nobody has a chance to intervene once it is given. The remaining three take a deposit or the whole device and belong to a different response process entirely. A control sitting at the hostname helps with all nine for the same price, because all nine begin with a navigation.

Placement

The check belongs wherever a hostname reaches a user from outside your product

Most teams' first instinct is to put a phishing check on their own login page, which is the one place it does nothing. By the time somebody is looking at your login form they have already resolved your domain correctly. The value of a known-bad lookup is realised at the moments when a hostname you did not author is on its way towards a user, and in a crypto product there turn out to be more of those than anyone expects.

Support tickets, the largest and the most neglected

An agent handling a stuck deposit receives a screenshot, a block-explorer link, and quite often the phishing page the customer visited three hours ago, pasted in as evidence. The agent is under handling-time pressure and clicks it. Screening every URL in every inbound ticket — before the agent's console renders it as a link — costs one credit per unique hostname and protects the staff account with the widest permissions in the company. The same reasoning drives the helpdesk integration pattern.

In-app notices and templated email

Any surface where operations staff can compose a message containing a link is a surface where a compromised internal account can distribute one, and the announcement channel of an exchange is a high-value place to do that. Running composed content through a batch check at publish time is less a fraud control than an editorial one: it stops your own product from becoming the delivery mechanism.

Anything user-submitted that another user will see

Forum posts, profile fields, project listings, community-maintained dApp directories, comment threads under market pages. This surface behaves much like an online marketplace and it degrades the same way: content outlives the moderator who approved it, domains lapse and get re-registered, and a listing that was legitimate in March is hostile by August. A periodic re-screen of stored URLs matters as much as the check at submission.

One hostname, four gates

09:12 — support ticket: the customer pastes the URL they were sent. It is screened server-side before the console renders it, so the agent sees a warning banner rather than a live link.
09:14 — community post: the same host is posted in a public channel by a fresh account. The submission check rejects it; no moderator had to be awake.
09:31 — wallet extension: a user navigates there directly from a message. The extension resolves the verdict locally from the daily feed and refuses to expose the injected provider.
09:47 — withdrawal review: the same host appears in the session history behind a first-time destination. The request is queued for step-up rather than auto-approved.

Four teams, four systems, one verdict — and none of them had to agree on a risk policy to use it.

What the list is

A picture of what is live, not an archive of everything ever reported

The verification standard is the part that matters for a product where a stale entry costs latency and a missing entry costs a wallet.

390,000+Phishing domains confirmed to be resolving in DNS right now
DailyFull rebuild, with a changelog of every domain added and removed
<50 msTypical single-lookup latency on the check endpoint
100Domains per batch request, one lookup each
Active DNS record required Dead domains dropped, not retained Full database as CSV Added and removed diff Database-stats endpoint Server-side keys only
The paste moment

The withdrawal-address field is a different problem, and worth being precise about

A hostname check does not validate an address. Knowing exactly where it helps in that flow is what keeps the control honest.

Stage one — the address field

Where the check does nothing, and must not pretend otherwise

Ask a room of exchange engineers where a phishing check belongs and somebody will say the withdrawal screen. They are half right, and the half that is wrong causes real harm if it ships. A destination address is a string on a chain; it has no hostname, no DNS record and no relationship to any domain list. Nothing in a known-bad domain database can tell you that the address a user pasted belongs to an attacker, and any interface implying otherwise is teaching people to trust a green tick that means nothing. A product that shows a “verified safe” state next to an address field on the strength of a domain lookup has built itself a liability.

Stage two — the session behind it

What the lookup can do is describe the journey

The interesting question at withdrawal time is not whether the address is bad, it is how the user came to have it. A first-time destination entered within minutes of a session containing a referrer or an in-app navigation to a host on the list is a very different request from a first-time destination typed on a quiet Sunday from a device enrolled two years ago. Neither is proof. Both are inputs to a decision the exchange already makes about whether to hold, delay, step up or let through — and this input has the useful property of being cheap enough to compute on every withdrawal rather than on a scored subset.

Stage three — the clipboard swap

Upstream evidence, never transaction validation

The same logic applies to the clipboard-substitution family, where malware on the endpoint swaps a copied address for the attacker's. A domain check cannot see that swap. It can frequently see the campaign that delivered the malware, because the download almost always came from somewhere. This is the general shape of the honest claim: the list is upstream evidence about how a user got into trouble, not a verdict on the transaction they are about to make. Presented that way it strengthens a risk engine. Presented as transaction validation it misleads, and the first time something slips through, users will conclude the whole control was theatre.

Stage four — the whitelist label

A quieter field nobody watches

There is a second place in the withdrawal flow worth wiring: the whitelist. Many platforms let users register named destinations, and some let them attach a memo, a label or a reference URL. Those free-text fields are indexed, sometimes displayed back to support staff, and occasionally used by an attacker who has taken over an account to make a fraudulent destination look institutional. Screening hostnames found there costs almost nothing and closes a path nobody watches.

Stage five — the address-book import

One batch call inside an importer you already have

Users move between products and paste in lists; custody platforms and treasury tools accept counterparty uploads that frequently include a website column. Running that column through the batch endpoint at import time — a hundred hostnames per request, one lookup each — is a short addition to an importer that already exists, and it catches the case where somebody is onboarding a counterparty who was compromised months ago. Teams building this alongside a wider watch programme usually pair it with the approach described on the brand protection page.

Integration

Two endpoints, one feed, and a rule about where the key lives

Everything on this page is built from a single-domain check, a hundred-domain batch, and a daily CSV of the whole database.

One hostname, one credit, one interactive answer

The single check is GET /api/v1/check?domain=<host>&apikey=<key>, and it is what you call from an interactive path — a support console rendering a ticket, a submission handler validating a posted link, a server endpoint your extension talks to. It returns domain, is_phishing, category, dns_status, last_checked, confidence and database_size, which is enough to decide, log and explain. one lookup per API call, and lookups reset each month.

A hundred hostnames, one call, one log line

The batch endpoint is POST /api/v1/batch with a JSON body of {"apikey":"..","domains":[..]}, capped at a hundred domains per request and billed one credit per domain. Use it for anything arriving as a set: the distinct hostnames in a message, a nightly re-screen of stored listing URLs, an imported counterparty file. Batching is not merely cheaper to operate than a loop of single calls, it produces one log line per job, which is what makes the control auditable a year later.

curl -s "https://phishingdetectionapi.com/api/v1/check?domain=login-portal-example.tld&apikey=$PDA_KEY"

curl -s -X POST https://phishingdetectionapi.com/api/v1/batch \
 -H "Content-Type: application/json" \
 -d '{"apikey":"'"$PDA_KEY"'","domains":["claim-airdrop.example","support-desk.example"]}'

Both calls run server-side. The key is never present in extension bundles, mobile binaries or page source.

For a wallet extension the per-query model is usually wrong anyway, and not because of cost. Sending every hostname a user visits to a third party is exactly the property this audience objects to most loudly, and they are right to. The daily feed — the complete database as CSV on a separate subscription, plus the added and removed changelog — lets the verdict be resolved entirely on the device or inside your own infrastructure. No browsing telemetry leaves, the answer is available with the network down, and the privacy claim in your store listing becomes something you can actually defend. The same file is what a firm running its own resolvers loads into DNS filtering or a firewall blocklist.

The key itself is a server-side secret and must be treated as one. It is passed as a query parameter or in the POST body, so anything shipped to a browser, a phone or a published extension package will leak it. Put a thin endpoint of your own in front of the API, rate-limit it per user, and log the hostname you checked rather than the user who asked — a distinction this audience notices and remembers.
Support ticket bodies In-app notices Community submissions dApp directory entries Counterparty imports Withdrawal whitelist labels Extension navigation events Corporate resolver
Honest limits

A domain registered ninety seconds ago is not on this list, or on any other

The gap is real, it is shared by every blocklist that has ever existed, and pretending otherwise is how a security control turns into a false sense of safety.

Inclusion in this database requires that a domain has been observed, attributed to phishing infrastructure, and confirmed to be resolving. Every one of those steps takes time. A host registered during a token launch and put to work the same hour will be answering requests before it appears anywhere, and a share of the losses in this industry happens inside exactly that window. A clean result from the check endpoint means “not on the list,” and the distance between that and “safe” is the entire honest description of what you have bought. Anyone selling a blocklist as complete coverage is either confused or counting on you being.

What narrows the gap is not detection speed, it is discipline about what gets kept. Because inclusion requires an active DNS record and the database is rebuilt every twenty-four hours, dead hosts are dropped rather than accumulated. The list is therefore a description of what is live today rather than a growing museum of everything anyone has ever reported. That matters for two practical reasons: the ratio of useful entries to noise stays high, so the false-positive burden on your support queue stays low, and the file stays a size a resolver or an extension can actually hold in memory. A blocklist that only grows is a blocklist that eventually gets switched off by whoever is on call.

Because the fast-moving tail exists, the controls either side of it have to be real. Approval hygiene inside the wallet — bounded allowances, revocation prompts, a readable summary of what a signature actually grants — catches the drainer that arrived from a host nobody has seen yet. A withdrawal review that treats first-time destinations differently catches the credential theft the domain check missed. Device controls catch the impersonated extension. None of those are things a domain list does, and a programme that stops at the list will lose to the ninety-second domain. What the list does is make the other layers cheaper, by removing the high-volume, already-known traffic before it reaches them — which is why it belongs inside an incident response workflow rather than instead of one.

One further limit deserves naming plainly, because it is specific to this sector. A hostname check has nothing to say about a malicious contract behind a legitimate front end, a compromised dependency in a widely used interface, or a governance attack. Those are real ways people lose funds and none of them involves a suspicious domain. The control described here addresses the large, noisy, industrial category of losses that begin with somebody arriving somewhere they should not have. That is a worthwhile category to remove. It is not the whole map, and the page would be worth less if it claimed to be.
Do not present this as transaction safety. The moment a domain verdict is rendered as a tick beside an address, a signature prompt or a contract, users read it as approval of the thing they are about to do. Label it for what it is — a check on where this link goes — and the control keeps its credibility the first time something gets through.
Sizing

What the volume actually looks like once you count the calls

Credits are one per lookup and billed monthly, so sizing is an arithmetic problem rather than a licensing negotiation.

Start by counting distinct hostnames rather than events, because hostnames are what you should be caching on. A mid-sized exchange screening inbound support tickets typically finds that a few thousand tickets a day contain a link, that the links collapse into a few hundred distinct hosts, and that most of those hosts are block explorers and the exchange's own domains. Cache on the host and the billable volume falls sharply before you have tuned anything else. The same holds for community submissions, where a small number of hosts account for the bulk of posts.

Plans are monthly subscriptions with no per-seat licence, so a team can scale up or down each month as volume changes. Where the arithmetic changes shape is anything user-facing at navigation frequency — an extension checking every host a user visits, or a resolver answering for a whole company. Per-query pricing is the wrong instrument there and the daily CSV is the right one, because matching happens locally, there is no per-lookup cost, and no browsing data leaves the device. Most crypto firms end up running both models: the feed for the high-frequency local path, a monthly plan for the interactive server-side checks. The pricing page holds the definitive figures, and the fintech page walks the same arithmetic for a regulated product.

Questions from the team

The objections that come up in the design review

Seven that get raised every time a crypto team looks at putting a third-party lookup anywhere near a user path.

If the attacker's domain is minutes old, what is the point?

The point is volume, not completeness. A large share of what reaches users is not a bespoke domain minted for them; it is infrastructure that has already been used against somebody else, is still resolving, and will keep being used until it is taken down. Removing that traffic is cheap and it is most of the noise.

  • The fresh domain is a genuine miss. The answer to it is the layer behind the check — bounded approvals, withdrawal review, step-up authentication.
  • The list does not replace those layers. It exists to make them affordable by shrinking what reaches them.
Can we run this without sending user browsing data anywhere?

Yes, and for a wallet or an extension you should. The daily feed delivers the whole database as CSV on a separate subscription, so matching happens locally — on the device, in your own service, or in a resolver you operate. Nothing about a user's navigation leaves your boundary, and the verdict is available with the network down.

  • Per-query lookups suit server-side paths where the hostname was submitted to you anyway — a support ticket, a forum post, an imported file. Those are hostnames you already hold.
  • Most teams run both models. The feed for the user-facing path, credits for the operational ones.
Will this tell us whether a withdrawal address is safe?

No, and any interface implying that it will is a problem in itself. The database maps hostnames, not chain addresses. There is no lookup here that can say anything about a destination string.

  • What it contributes is session context — whether the request follows an interaction with a host confirmed to be phishing infrastructure.
  • That is an input, not a verdict. Useful to a risk engine you already run; never a statement about the transfer itself.
What does a false positive cost us, and how do we handle one?

It costs a user a blocked link and your desk a ticket, so the response has to be local and immediate. Keep an allowlist in your own layer that is consulted before the verdict is applied, and give support the ability to add to it without a deployment. Every serious deployment of a blocklist needs that valve.

  • The verification standard helps here too. Inclusion requires an active DNS record and the database is rebuilt daily, so the list carries far fewer long-dead entries than feeds that only accumulate.
  • Stale entries are where most blocklist false positives come from — which is exactly the category a daily rebuild removes.
Where exactly does the API key live in a browser extension?

Not in the extension. Anything shipped to a browser is readable, and a published package is a distribution channel for whatever is inside it. The key is a server-side secret passed as a query parameter or in a POST body.

  • Option one — a thin proxy of your own in front of the API, rate-limited per install.
  • Option two — the daily feed, so the extension needs no network call at all. Usually better for this audience, because it also removes the telemetry objection.
Does adding a lookup slow down our support console or submission path?

A single lookup typically returns in under 50 ms, which is below the threshold at which anything feels different in a console already fetching a ticket from a database. For sets, the batch endpoint takes up to a hundred domains in one request, so a message with fifteen links is one call rather than fifteen.

  • Cache on the hostname with a short lifetime and the practical cost falls further, because the same handful of hosts recur constantly.
  • If the path is latency-critical, screen asynchronously and render the link inert until the verdict lands.
We already scan links at the email gateway. Is this duplication?

It overlaps at the mailbox and covers nothing else. The lures on this page mostly do not arrive by email: they arrive in a public community channel, a direct message, a paid search result, a support conversation the user started, or a listing inside your own product. None of that passes a mail gateway.

  • The gateway protects one channel. This protects a hostname wherever it appears, in whichever product it appears in.
  • Firms running both reuse the same verdict in both places — see the email security and messaging apps pages for the equivalent patterns.

Put the check in front of the signature

390,000+ DNS-verified phishing domains, rebuilt every twenty-four hours with a full added and removed changelog. Query it per hostname, or pull the whole database and match locally.