Crypto Exchange Security: 25 Controls Drawn From Real Thefts
Founder and Principal Security Consultant - CISSP, CEH, CHFI, Mandiant

25 controls, drawn from documented thefts
Protecting a private key is not enough if an attacker can make an authorised signer approve the wrong transaction. Almost every large exchange loss of the last four years turned on that sentence.
The crypto industry spent a decade solving key custody, and solved it fairly well. Hardware security modules, threshold signing, multi-signature wallets, air-gapped ceremonies: the cryptography mostly held. Then the money left anyway.
It left because the attack moved. Instead of stealing a key, attackers learned to make the legitimate key holder sign the wrong thing. The signature is valid. The quorum is satisfied. The audit log shows three authorised people approving a transaction. And the funds are gone, because what those three people saw on screen was not what they signed.
What follows is 25 technical controls, organised by the part of the business they protect. They are drawn from documented incidents at exchanges, custodians, wallet vendors, bridges and trading firms. Where the cause is still disputed, the observed failure is described without assigning blame. No public record covers every breach, so treat this as the pattern that is visible, not the complete set.
The core idea
The assumption that broke
A 3-of-5 wallet proves that three keys produced signatures. It does not prove that three people independently checked where the money was going. If all three signers read the transaction from the same interface, and that interface is compromised, the wallet behaves exactly as designed while it empties.
This is what happened at Bybit, where investigators found altered JavaScript served through Safe infrastructure. It is what signers described at Radiant, where compromised devices displayed legitimate details while malicious transactions were signed. WazirX reported a mismatch between displayed and signed contents, though responsibility there remains disputed.
The signature was never the weak point. The screen was.
The common thread across Bybit, Radiant and the disputed WazirX timeline
Every control in the custody section below exists to break that single dependency: the assumption that what a signer sees is what a signer signs.
The evidence
Six ways the money actually left
Sorting incidents by attacker or by blockchain tells you very little. Sorting them by failure path tells you what to test. Six paths account for the documented losses.
| Failure path | What went wrong | Documented incidents |
|---|---|---|
| Signers approved malicious actions | The display and the payload diverged | Bybit, WazirX (disputed), Radiant |
| A supplier reached asset control | A third party could substitute a transaction or a chain event | DMM Bitcoin (308 million USD), JumpCloud, KelpDAO |
| Keys or privileges reached too far | Credentials retained authority beyond their purpose | Binance (7,000 BTC), Wintermute, Ronin (five of nine validator keys) |
| Software distribution failed | Published code or API secrets were not what customers expected | Ledger Connect Kit, 3Commas |
| Valid actions created invalid value | The chain accepted messages that should not have existed | Nomad, BNB bridge, Resolv |
| Accounting or market assumptions failed | Balances, prices or finality were not what the system believed | QuadrigaCX, Mango Markets, Ethereum Classic |
Sources are the published post-mortems, regulator filings and investigator reports linked above, current to September 2026.
Controls 1 to 8
Custody and transaction authority
1. Set a hard loss limit for every wallet tier
Define hot, warm and cold by the maximum value each can lose, not by their names or network connection. Enforce per-asset balances, per-transaction ceilings, rolling 24-hour outflow limits and a refill rate outside the wallet application. If a hot wallet is compromised, its balance plus refill allowance should be the maximum plausible loss.
Test it: Try to exhaust a wallet with many small transfers from different accounts.
2. Keep signing keys inside independently controlled boundaries
Use non-exportable HSM keys or a reviewed threshold-signing design. Place shares under separate administrators, devices, networks and recovery procedures. Three shares controlled through one identity provider or one cloud administrator are one compromise domain wearing a disguise. NIST SP 800-57 covers key lifecycle.
Test it: Whether a single cloud administrator, CI account or custody supplier can assemble enough authority to sign.
3. Separate the signing quorum from the authorisation quorum
Have an independent policy service approve the business intent before any signer receives a request. Prevent the proposer, the policy administrator and the threshold signers from sharing a privileged control plane.
Test it: A compromise of the identity provider that authenticates all three roles.
4. Verify the bytes to be signed using a separate decoder
From the unsigned payload, independently derive chain ID, wallet address, nonce, operation type, to, value, function selector, decoded arguments and transaction hash. Compare them with a separately approved transfer instruction. Show that interpretation on a trusted device or independent channel, never solely on the proposing website. Reject unknown calldata, nested calls and any display that cannot show material effects. EIP-712 describes domain binding with fields such as chainId and verifyingContract.
Test it: Substituting different calldata behind an identical-looking display.
5. Give treasury wallets a restrictive transaction policy
A routine cold-to-warm transfer should permit only the expected token contract, transfer selector, approved recipient, amount range, chain and time window. Treat DELEGATECALL, arbitrary batch calls, token approvals, module changes, owner changes and upgrades as separate governance operations. Simulate the exact raw transaction before signing and fail closed on any difference.
Test it: Substituting a wallet upgrade or a token approval for a routine transfer.
6. Delay dangerous changes in a way signers cannot bypass
Apply a timelock and a separate approval path to implementation upgrades, signer changes, modules, guards, token spend approvals and bridge verifier changes. Monitor both upgrade events and the actual EIP-1967 implementation slot. A wallet guard is insufficient if the same owners can disable it: put the asset-bearing vault behind a separate contract-level policy.
Test it: Whether the existing quorum can disable the guard and drain the vault in one transaction.
7. Test key recovery as carefully as key generation
Generate keys with reviewed entropy; prohibit vanity-address generators and imported keys of unknown origin. Wintermute is the cautionary case here: a likely weak vanity-wallet key that still held vault privileges. Keep encrypted recovery material under split control and rehearse restoration without giving one operator the full secret. When replacing a suspect key, remove its contract roles and allowances, not just its balance.
Test it: Whether the old address can still administer a vault after its balance reaches zero.
8. Use dedicated signer devices with a narrow software set
Keep development tools, personal email, chat, browser extensions and downloaded code off signing devices. Restrict outbound connections, require managed firmware and endpoint monitoring, and alert on new processes, extensions, remote-control sessions and wallet-software changes.
Test it: A signer workstation that displays a legitimate transfer but submits different calldata.
Controls 9 to 16
People, suppliers and software delivery
9. Treat custody frontends as part of the signing boundary
Pin reviewed frontend builds and third-party scripts for operational signing; verify the delivered artifact hash outside the serving cloud account. Alert on changes to object storage, CDN origins, DNS, JavaScript bundles and the identities allowed to publish them. A legitimate URL and a valid HTTPS connection did not stop the malicious code served to Bybit signers.
Test it: Whether a cloud session able to alter website assets can also alter what the signing team sees.
10. Audit what a supplier can cause, not what it claims to store
Map every supplier with access to transaction creation, signing displays, RPC responses, identity administration, wallet management or deployment. Ask whether a compromised supplier employee or session can substitute a transaction or return a false chain event. KelpDAO is the worked example: compromised RPC nodes and a single verifier accepting a forged source-chain event.
Test it: A malicious but correctly authenticated response from each supplier.
11. Make privileged sessions short-lived and revocable
Require phishing-resistant WebAuthn for cloud, identity, CI, custody and package-publishing access. Bind high-risk sessions to managed devices and use just-in-time roles. Removing a password or adding MFA does not evict an attacker holding a live session. Rehearse session revocation; see NIST SP 800-63B on phishing resistance.
Test it: Revoking every active session under time pressure, then proving it took effect.
12. Contain recruiter and code-test attacks against staff
Developers and wallet operators should open unsolicited repositories, interview tests and trading tools only in disposable environments with no corporate sessions, credentials, SSH agent, wallet software or route to production. This is not theoretical: the FBI attributed the 308 million USD DMM Bitcoin theft to a wallet supplier employee compromised through a fake recruitment test. Treat such execution as possible session-token theft, not a malware alert to be closed.
Test it: The response to a compromised developer browser session.
13. Require controlled, reproducible releases to package registries
Build from reviewed commits, lock dependencies, verify build provenance and publish through a CI identity with short-lived credentials. Remove departing staff from npm and other external services during offboarding: the Ledger Connect Kit incident began with a former employee account publishing malicious versions. Keep an immediate package and CDN rollback procedure.
Test it: Whether a former employee registry session can still publish a new version.
14. Constrain customer and partner API keys
Separate read, trade, transfer and withdrawal scopes; default third-party trading keys to no withdrawal permission. Add short expiry, fast revocation, permitted IP ranges and per-key volume and market limits. Detect self-trading and abrupt concentration in illiquid pairs: a trade-only key can still extract value through deliberately bad trades.
Test it: Whether a leaked trade-only key can transfer wealth out through an illiquid market.
15. Design support systems for a bribed insider
Give agents masked balances and the minimum identity data a case needs. Gate full ID images, account history and bulk queries behind case-specific access with short expiry. Support must not be able to remove a withdrawal hold or reset a high-assurance factor alone.
Test it: How much data one support account can collect in a single shift.
16. Make account recovery incapable of immediate asset movement
A password reset, device change, passkey replacement, API-key creation or support-assisted recovery should trigger a withdrawal hold and a notice through previously registered channels. Require stronger checks for a new destination than a repeat one, and keep allowlist changes on a separate delay.
Test it: An account takeover executed immediately after a support-assisted recovery.
Controls 17 to 21
Deposits, balances and trading
This section is where an exchange stops resembling a wallet and starts resembling a bank. The failures here are not cryptographic at all. QuadrigaCX did not lose a key to an attacker; it recorded balances that were never backed. That is an accounting control failure, and it ended in an Ontario Securities Commission report rather than a forensic one.
17. Use an append-only, double-entry customer ledger
Every deposit, trade, fee, internal transfer and withdrawal should create balanced postings with a unique event ID. A database administrator or a trading service must not be able to mint a spendable customer balance by editing one row. Assert that customer liabilities plus exchange-owned balances equal controlled assets after pending movements.
Test it: Unauthorised credits attempted through the admin UI, the database and the event consumer.
18. Reconcile liabilities to assets independently and frequently
Rebuild balances from the event journal and compare per asset and chain against independently queried wallet balances, pending withdrawals, custodian statements and known encumbrances. Alert on unmatched transactions, negative suspense accounts, stale reconciliation and any liability increase without an authorised asset inflow. A proof-of-reserves snapshot without complete, current liabilities establishes nothing about backing.
Test it: Whether a separate team reviews exceptions, or the same team that creates them.
19. Make deposit credit depend on chain-specific finality
Do not use one fixed confirmation count across all assets. Track canonical block hash and transaction position, detect reorganisations, reverse provisional credits and block withdrawals against deposits that have lost finality. Ethereum Classic is the reference case: deep reorganisations containing double spends.
Test it: A deep reorg against deposits already traded into other assets.
20. Parse assets by chain and contract identity, not ticker
A deposit processor should require the expected chain ID, token contract or mint, a finalised transaction, successful execution and an actual balance effect. Handle fee-on-transfer tokens, rebases, proxies, decimals and chain-specific behaviour explicitly. Treat each newly listed asset as new deposit and withdrawal code, with its own loss limit until tested.
Test it: Duplicate events, removed logs, failed calls emitting misleading data, and two tokens sharing a symbol.
21. Assume a price feed can report a real trade at a manipulated price
For margin, lending and derivatives, use independent venues, freshness checks, liquidity weighting, deviation bands and limits on how fast collateral value can rise. Cap borrowable value by exit liquidity and concentration even when the oracle reports a valid price. In the Mango Markets case, trades across three source exchanges drove a reported price increase of more than thirteenfold in 30 minutes. Every individual trade was real.
Test it: An adversarial test in which one trader moves every source market the feed uses.
Controls 22 to 25
Chains, contracts and response
22. Verify bridge events independently before releasing value
Bind each message to source and destination chain, emitting contract, event, nonce, amount, recipient and finalised block; enforce one-time consumption. Require independent verifier infrastructure and check the value invariant: destination releases must correspond to confirmed source locks or burns. Nomad passed unproven messages through a zero-root check; the BNB bridge accepted a forged Merkle proof.
Test it: A verifier supplying plausible but nonexistent source-chain blocks.
23. Test financial invariants, including old contracts, at extreme inputs
For each mint, burn, swap, vault share or fee path, write properties such as assets_out <= assets_available and minted_value <= authorized_collateral_value. Fuzz maximum integers, low-decimal assets, dust reserves, rounding direction, reentrancy and operations financed by flash loans. Repeat against deployed bytecode and the exact compiler version. Truebit was an integer overflow in an older contract; Balancer V1 a rounding deficiency in an unmaintained pool. Inventory legacy contracts even when no team maintains them.
Test it: The same properties against bytecode you no longer have the source build for.
24. Monitor authority changes from outside the system being monitored
Use independent chain nodes and data providers to watch wallet owners, modules, guards, implementation slots, token approvals, mint roles, bridge verifiers and outflow by asset. Correlate with custody requests and the internal ledger. A signed transaction with no approved intent, or an impossible mint-to-collateral ratio, should trigger an automatic hold.
Test it: Whether monitoring still works after the primary custody provider or RPC cluster is compromised.
25. Rehearse stopping a theft while the attacker still has access
Maintain tested switches for withdrawals, deposits, trading by asset, API keys, hot-wallet refills, bridge releases and contract functions. Run a drill that starts with a compromised signer or supplier session: revoke sessions, block further signing, preserve logs and raw payloads, rotate roles, reconcile balances and restart one asset at a time. Prearrange contacts with custodians, major exchanges, chain security teams and law enforcement.
Test it: The elapsed time from first unauthorised transaction to enforced containment. Write the number down.
Priorities
Where to start, and why these six
Twenty-five controls is a programme, not a sprint. Test 4, 5, 9, 17, 18 and 24 first. Together they answer the single most consequential question an exchange faces: can someone make an apparently authorised action move or create assets without an independent system proving that the action matches a real customer or treasury obligation?
The logic of that grouping is worth spelling out. Controls 4 and 5 make the signer see the truth and restrict what a treasury wallet will accept. Control 9 removes the assumption that the interface delivering the transaction is trustworthy. Controls 17 and 18 mean that if value does move, the books cannot be quietly adjusted to hide it. Control 24 means the alarm does not depend on the systems the attacker already controls. Skip any one of the six and the other five can be walked around.
The uncomfortable implication: if you cannot currently answer that question with evidence, the remaining nineteen controls are risk reduction on a foundation you have not verified. That is still worth doing. It is not the same as knowing.
Regulation
What this looks like under MiCA and DORA
For crypto-asset service providers operating in the EU, most of the above stopped being optional. MiCA brings authorised CASPs into a supervised regime with explicit custody, segregation and operational requirements. DORA then applies the financial sector digital-resilience rules on top: an ICT risk management framework, a register of information covering ICT third-party providers, incident classification and reporting on a clock, and threat-led penetration testing for entities that meet the criteria.
The mapping is closer than most teams expect. Control 10, auditing what a supplier can cause, is DORA third-party risk management with a sharper question attached. Control 18, independent reconciliation, is what a segregation-of-client-assets obligation looks like when implemented rather than asserted. Control 25 is the response and recovery testing requirement, measured. If you are building the controls anyway, build them so the evidence is reusable.
We cover the regulatory side separately in our guides to DORA requirements for financial organisations and the EU AI Act, and the pentest side in our penetration testing service.
Questions
Frequently asked
We use a well-known custody provider. Does this still apply?
Yes, and control 10 becomes the most important one. A custody provider reduces key-management risk and adds a supplier who can, if compromised, influence what you sign or what you believe a chain reported. DMM Bitcoin lost 308 million USD through a wallet supplier employee, not through a broken key.
Is multi-signature enough?
Multi-signature answers one question: how many keys signed. It does not answer whether the signers saw the real destination, whether they share a compromised interface, or whether the same quorum can disable its own guard. Controls 3, 4 and 6 exist because the answer to all three has repeatedly been no.
How long does implementing all 25 take?
For an exchange with an existing custody stack, expect three to six months to get controls 4, 5, 9, 17, 18 and 24 genuinely tested, and twelve to eighteen months for the full set including contract invariants and drills. The six priority controls are worth doing on their own timeline rather than waiting for the programme.
Which of these would have stopped the Bybit theft?
Control 4 primarily, with 9 as the supporting control. An independent decoder showing the real destination and decoded arguments on a device the proposing interface cannot reach breaks the attack path, because the signer compares two sources rather than trusting one.
We are not an exchange, we are a fund or a treasury. Is this relevant?
The custody section is, almost entirely. Controls 1 through 8 and 24 apply to anyone holding assets under a signing quorum. The deposits and ledger sections only matter if you hold balances for other people.
What is the single most common gap you find?
Signers reading the transaction from the same interface that proposed it, with no independent decode anywhere in the path. It is present in most first assessments, and it is the gap that every incident in the first row of that table exploited.
Start with the question, not the checklist
Can an apparently authorised action move your assets without an independent system proving it should?
We test that question directly: the signing path, the treasury policy, the frontend boundary, the ledger and the monitoring that has to survive a compromised supplier. 200+ security assessments across 14 countries since 2013.
Talk to us about a custody reviewor see how we test
Alexander Sverdlov
Founder of Atlant Security. CISSP, CEH, CHFI and Mandiant certified. Author of 2 information security books, cybersecurity speaker at the largest cybersecurity conferences in Asia and a United Nations conference panelist. Former Microsoft security consulting team member, external cybersecurity consultant at the Emirates Nuclear Energy Corporation.
Connect on LinkedIn