VeilSwap
← All posts
Security2026-10-249 min read

Clipboard Hijacking: How to Verify a Crypto Address

Checksums catch typos, not replacements. We tested 1,304 mutated Bitcoin addresses and 5,415 mutated Monero addresses — then wrote down the check that actually works.

Your clipboard is not a private channel. On practically every desktop system it is a single shared buffer that any program running under your account can read and overwrite, with no prompt and no record. That is all a clipboard hijacker needs: it watches for strings that look like crypto addresses and swaps in its own the moment you copy one. You paste, the address is well formed, the wallet accepts it, and the money leaves. This is not a hypothetical format problem — the chain is full of address formats to imitate. Bitcoin block 972,954, mined at 17:47:02 UTC on 24 October 2026, held 660 spendable outputs in five shapes: 409 P2WPKH addresses of 42 characters, 143 P2PKH of 34, 46 P2SH of 34, 44 P2TR of 62 and 18 P2WSH of 62. Read the first four characters of what you copied, and the hijacker knows exactly which shape to hand back.

Checksums are why all of this feels safer than it is. We took a real address from that block — bc1q5js6zn25fwvr0zhm537ytt30f2d2fjzuh7gs6n — flipped one character at each of its 42 positions against every other character in the bech32 alphabet, and tested 1,304 variants. Zero passed. We repeated it on a 95-character Monero address behind its 4-byte Keccak checksum: 5,415 single-character variants, zero passed. Base58Check behaves the same way. A one-character change to 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa fails its double-SHA256 check, and a one-character change to the TRON USDT contract TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t fails too — that address decodes to the 0x41 network byte plus 20 bytes, and the trailing 4 bytes are the checksum. So single-character mistakes are caught essentially always. The flaw in the argument is that a hijacker never makes a single-character mistake. It hands you a different string that was generated correctly, checksum included. (XMR to USDT exit)

This is where the pipeline's checks stop helping. On our own order endpoint the server-side validation is a length bound — 256 characters, nothing else — and the format and checksum test happens one layer down at the liquidity provider. Both rejection paths are real and we triggered them today: a 95-character Monero address with one flipped character comes back as “... is not valid. Reason: Invalid checksum”, and the string “test” comes back as “invalid destination address”. That catches a truncated paste. It cannot catch a correct one. EVM chains are the weaker case, because an Ethereum address has no mandatory checksum at all. EIP-55 encodes one in capitalisation, and only when the mixed-case form is used; we recomputed it for 0xdAC17F958D2ee523a2206206994597C13D831ec7 and it matches, but the same address in all lowercase — or with one lowercase hex digit changed — is still a string every wallet will accept. On ETH and USDT-ERC20, a typo is caught by nobody except your eyes. (XMR to USDT exit)

Four surfaces do the substituting, and only one of them is the clipboard. Host-level malware reads the buffer, matches a pattern, writes back. A malicious browser extension does not even need the clipboard — it can rewrite the value of the input field after you paste. An address saved years ago from a phishing page keeps working because address books are trusted by default and almost never re-checked. A QR overlay shows the camera one code while the screen renders another. What ties all four together is the human habit of paste, glance, send — and the glance is the weak link. On a 34-character Bitcoin address, comparing the first four and last four characters means you verified 8 of 34, about a quarter of the string, on the very screen that may have been tampered with.

The check that works is boring and takes about thirty seconds: compare the entire string, character by character, on a device that is not the one you are sending from. If you sign with a hardware wallet, that device displays the destination on its own screen at signing time — firmware draws it, not your operating system, and it is the only view a compromised host cannot rewrite. If you are paying a swap order or an exchange, the destination lives in your phone: open the receiving wallet, tap receive, and read the address against the desktop screen. QR codes skip the clipboard entirely, which removes one whole attack class — scan from the receiving wallet's own display, and still read the address text printed under the code, because QR substitution is a real technique. Once an address has been verified this way, save it in the wallet's address book and use only the saved entry; re-copying from a chat message is how the second attempt gets burned.

None of this is recoverable after broadcast, which is what makes the pre-send check the only check that matters. A Bitcoin transaction can be replaced only if you opted into RBF when signing, and a swap deposit almost never is; Monero, TRON and Ethereum transfers are final once confirmed. On a swap order the payout address is not the only one you own — the refund address is the other, and it fails in exactly the same way: a hijacked refund address turns a failed order into a donation. One asymmetry is worth knowing. The deposit address on the order page is generated per order by the provider and shown with its own QR, so it never passes through your clipboard and a hijacker has nothing to swap. The two addresses you are responsible for are the ones you type or paste: payout and refund. (recovering misdirected funds)

People reach for “send a small test amount first”, and for self-custody the arithmetic is fine. At today's rates a 141-vB Bitcoin transaction at 1 sat/vB costs 141 satoshis, about $0.11 with BTC at $80,255. A Monero 1-in/2-out transaction is 1,534 bytes at the 20,000-piconero-per-byte floor: 0.00003068 XMR, under two cents. A USDT-TRC20 transfer is 64,285 energy (6.4285 TRX) plus 345 bytes of bandwidth (0.345 TRX), roughly $2.23 at $0.3295. What does not work is testing a swap order. The minimum on USDT-TRC20 to XMR right now is 19.741234 USDT, and fitting the live quotes — 100 USDT to 0.14558008 XMR, 5,000 to 8.18028676 — gives a marginal 609.85 USDT per XMR with a fixed cost near 11.22 USDT per order. At the minimum, that fixed cost is 56.8% of the amount sent. Test the address with a self-custody transfer, not with a swap. (XMR to USDT exit)

The honest limit: if the machine you are typing on is compromised at the kernel level, no check performed on that machine means anything — not the wallet's address display, not the block explorer, not the QR code. That is exactly why the ritual is built around a second device rather than around software. The habits that survive contact with real malware are small ones. Never let a clipboard carry an address you have not compared in full. Keep a verified address book and stop re-copying from chat. Treat any freshly pasted address as untrusted even when it is the same one you used last week, because that is precisely the change a hijacker makes. And for any amount you would miss, do the comparison out loud on the hardware wallet screen or the phone before the send button. None of this is exotic. It is the difference between a thirty-second delay and an irreversible transfer to a wallet nobody can help you recover.

Frequently asked questions

Do address checksums protect me from clipboard hijackers?

No. Checksums catch typos, not replacements. We mutated a real Bitcoin bech32 address in all 1,304 possible single-character ways and a 95-character Monero address in all 5,415 — none passed validation, which shows a one-character slip is caught. A hijacker does not make a slip: it substitutes a different address that is valid and checksum-correct, so every validator accepts it.

How many characters do I actually need to compare?

All of them, on a second device — that is the only answer that holds. If you are forced to shorten, first four plus last four gives 58^8, about 128 trillion combinations, which a fixed-address hijacker cannot match; first four alone is only 58^4, about 11.3 million, which a vanity-address generator can reach. And neither helps if the screen showing the address is the compromised one.

Is sending a small test amount enough?

It catches a swapped address only after you have already confirmed the destination once, and it costs real money on some chains: about $0.11 for a 141-vB Bitcoin send at 1 sat/vB, about $2.23 for a USDT-TRC20 transfer. For a swap order it is the wrong shape entirely — the minimum is 19.741234 USDT and the fixed cost per order is near $11.22, so 56.8% of a minimum-size test order goes to overhead. Test the address in self-custody instead.

Keep reading

All articles →

Ready to swap?

No account · No KYC · No email

Exchange now
Clipboard Hijacking: How to Verify a Crypto Address — VeilSwap