Signature phishing: permit, approve, setApprovalForAll
One signature can hand over spending power without your key leaking. What approve, permit, and setApprovalForAll grant, blind signing, and why hardware wallets get drained.
Quick answer
approve grants a spender up to a set amount of one token until revoked; unlimited means your whole balance. permit grants the same power via a gasless off-chain signature. setApprovalForAll hands an operator every NFT in a collection. Phishing hides these behind a friendly story, and blind signing lets even hardware-wallet users approve them.
Key points
- approve grants spending of one token up to an amount, until revoked.
- permit grants the same power via a gasless off-chain signature.
- setApprovalForAll grants operator control of a whole NFT collection.
- Blind signing means approving what your wallet cannot display in plain language.
- Hardware wallets protect your key, not a malicious approval you confirm.
Signature phishing is the practice of getting you to sign something whose real effect is not what the page claims. It is the engine behind most modern wallet theft, because a single well-chosen signature can hand over spending power without the attacker ever touching your key. To defend against it you need to know what three specific authorizations actually grant, and why even a hardware wallet does not make you immune.
approve: spending permission for one token
The ERC-20 approve(spender, amount) call grants a spender the right to move up to amount of one specific token from your wallet, using transferFrom, until you change or revoke it. If amount is set to the maximum uint256 value, common implementations treat it as unlimited and never decrement it, so the spender can move your entire balance of that token, now and in the future.
approve(0xSpender, 115792089237316195423570985008687907853269984665640564039457584007913129639935)
// max uint256 == effectively unlimited allowance for ONE token
What it grants: control of one token, up to the approved amount, until revoked. What it does not grant: access to other tokens, your NFTs, or your native balance. This is the narrowest of the three, and it is an on-chain transaction, so it costs gas and appears in your history.
permit: the same power, from an off-chain signature
Under EIP-2612, a token can implement permit, which accepts an off-chain, EIP-712 typed-data signature and sets an allowance in the same call that spends it. You sign a message; a relayer or the application submits it on chain. Tokens such as USDC and DAI support this, and it is marketed as a gasless approval.
The security consequence is that permit grants the same spending power as approve, but through a signature rather than a transaction. That means no gas cost to give you pause, nothing in your transaction history at the moment you sign, and a prompt that can be dressed up to look like a harmless login or verification. Permit2, a widely integrated contract from Uniswap, extends this signature model to tokens without native permit support and can grant allowances to spenders for specified amounts and durations. A permit or Permit2 signature is not safer than an on-chain approval simply because it is gasless; if anything it is easier to slip past a distracted user.
setApprovalForAll: the entire collection
For NFTs, the ERC-721 standard defines setApprovalForAll(operator, approved). Setting it to true grants the operator authority over every token you own in that collection, including tokens you mint or buy later, until you revoke it. This is the broadest authorization of the three and the primitive behind a large share of NFT phishing losses. One signature can place an entire collection under an attacker’s control.
setApprovalForAll(0xOperator, true)
// operator can move ALL of your NFTs in this collection, now and later
What it grants: blanket, collection-wide operator control. What makes it dangerous: the victim usually believes they are approving one action, such as listing a single item, while granting control over everything.
Why the story on screen is the attack
All three authorizations are legitimate features used constantly by honest applications. Phishing works by decoupling the human-readable claim from the machine-readable call. The page says “Claim airdrop,” “Verify wallet,” or “Enable trading.” The signature underneath is approve, permit, or setApprovalForAll pointing at the attacker’s spender. If your signing surface shows only a hash or an unlabeled block of typed data, there is nothing to contradict the story, and you approve the attacker’s request believing you approved the page’s.
Blind signing
Blind signing is approving a transaction or message that your wallet cannot fully display in human-readable form, so you are trusting the requesting site rather than the request itself. It happens when a device hashes or truncates complex EIP-712 data because its screen cannot render it, or when software wallets show raw data most users cannot parse. Blind signing is precisely the condition drainers need: they supply the story, your wallet supplies an opaque prompt, and you supply the signature.
Why hardware wallets still get drained
This is the point that surprises people. A hardware wallet keeps your private key isolated, so it defends brilliantly against key theft. It does not, on its own, defend against you authorizing a malicious action, because you are the one confirming it. If the device can only show a hash or truncated typed data for a complex permit or setApprovalForAll, you are blind signing on hardware, and a hardware-signed malicious approval is exactly as final as a software-signed one. The device faithfully signs what you told it to sign; it has no way to know the story on the website was a lie.
The industry response is clear signing: standards such as EIP-712 for structured, readable data and the ERC-7730 clear-signing metadata format let devices present function calls and typed messages in plain language, so you can see that you are about to approve a spender rather than merely “sign a message.” Ledger introduced clear signing and later transferred stewardship of the standard to the Ethereum Foundation, with Ledger and Trezor among its stewards. Clear signing narrows the gap that blind signing opens, but it is only protective when it is actually enabled and supported for the specific call in front of you.
How to defend
- Name the call before you sign. Ask which of these it is: a plain transfer, an
approve, apermitor Permit2 message, or asetApprovalForAll. If you cannot tell, do not sign. - Treat signature requests as approvals. A gasless message can hand over spending power. It deserves the same scrutiny as a transaction.
- Refuse to blind sign. If your wallet or device shows only a hash or unlabeled data for anything touching your assets, stop. Enable clear signing where available and use wallets that decode transactions.
- Be suspicious of unlimited and collection-wide requests from sites you do not fully trust, especially framed as claims, verifications, or support steps.
- Compartmentalize and revoke. Interact with a low-value wallet, keep holdings separate, and periodically revoke approvals you no longer need.
The defense is not a product; it is a habit of reading the authorization rather than the marketing around it. A hardware wallet is a valuable tool, but it protects your key, not your judgment at the signing prompt.
Sources
Frequently asked questions
What is the difference between approve and permit?
Why is setApprovalForAll so dangerous?
What is blind signing?
If I use a hardware wallet, am I safe from this?
Is a gasless signature request safer because it costs nothing?
What is clear signing?
Note: CamoCrypt is security & education only — no prices, no predictions, no investment advice. Verify every address and contract yourself; we cannot recover lost funds and neither can anyone who contacts you claiming they can.