⚠️ Cảnh báo bảo mật — Đọc trong 60 giây
Blind Signing: Bạn Đang Ký Cái Gì Không Biết
Blind signing là khi bạn ký một transaction hoặc message mà wallet không hiển thị nội dung rõ ràng — chỉ hiện raw hex hoặc hash. Bạn không biết mình đang approve transfer bao nhiêu token, cho địa chỉ nào, hay cấp quyền gì cho contract nào.
Đây là vector tấn công phổ biến nhất trong Web3 hiện tại. Attacker tạo ra transaction hợp lệ về mặt kỹ thuật nhưng có hại — đưa vào flow của dApp giả mạo và chờ user ký mà không đọc. Giải pháp là clear signing — wallet decode và hiển thị đầy đủ nội dung trước khi confirm.
01 · Khi nào
Khi wallet hiện hex thô hoặc không decode được calldata
02 · Nguy hiểm
Approve unlimited, setApprovalForAll, permit signature ẩn
03 · Giải pháp
EIP-712, clear signing plugin, simulation trước khi ký
04 · Phòng tránh
Revoke.cash, approve tối thiểu, verify URL, slow down
Mọi hành động trên blockchain — chuyển token, swap, mint NFT, vote — đều là một transaction được ký bằng private key. Nội dung thực sự của transaction là một chuỗi bytes (calldata) encode theo ABI của contract. Blind signing xảy ra khi wallet không decode được calldata này để hiển thị cho user hiểu.
Clear Signing vs Blind Signing
CLEAR SIGNING — User thấy:
✓ Gọi contract: Uniswap V3 Router (0x68b3...)
✓ Hành động: Swap 100 USDC → ETH
✓ Slippage tối đa: 0.5%
✓ Deadline: 20 phút
✓ Gas: ~0.002 ETH
BLIND SIGNING — User thấy:
⚠ Data: 0x38ed1739000000000000000000000000000000000000000000000000000000003b9aca00
000000000000000000000000000000000000000000000000002386f26fc1000000...
⚠ Contract: 0x????...????
← Bạn có confirm không? [CANCEL] [CONFIRM]
Blind signing xảy ra phổ biến trong ba tình huống:
- dApp dùng custom smart contract mà wallet không có ABI để decode — wallet chỉ hiện raw hex.
- Hardware wallet khi dApp không implement Ledger/Trezor plugin — thiết bị buộc phải enable "blind signing mode" trong settings.
- Message signing —
eth_sign và personal_sign ký arbitrary data — nếu dApp truyền data không có cấu trúc rõ ràng, user không biết mình ký gì.
1. Approve Unlimited — Cấp Quyền Vô Hạn
ERC-20 approve(spender, amount) cho phép một contract tiêu token thay bạn. Nhiều dApp (và nhiều user) dùng amount = 2²⁵⁶ - 1 (uint256 max) — tức là approve vô hạn. Nếu contract đó sau này bị hack hoặc là malicious từ đầu, kẻ tấn công có thể drain toàn bộ token đó từ ví.
Khi blind signing, bạn không thấy amount là bao nhiêu — và không biết mình vừa cấp quyền vô hạn.
2. setApprovalForAll — Giao Hết NFT
setApprovalForAll(operator, true) trên ERC-721/ERC-1155 cấp cho một địa chỉ quyền transfer toàn bộ NFT trong collection đó — không giới hạn số lượng. Phishing sites thường giả mạo mint page nhưng thực ra gọi setApprovalForAll cho địa chỉ của attacker thay vì mint.
🔴
Case study — OpenSea phishing 2022
Đầu 2022, hàng chục NFT holder bị mất tổng cộng hơn 1,7 triệu USD NFT qua một phishing campaign. Attacker gửi email giả mạo OpenSea "yêu cầu migrate listing" — link đến một site giả. User ký một Wyvern protocol order trông như OpenSea listing bình thường nhưng thực ra là lệnh bán 0 ETH. Không có blind signing awareness, không có simulation — user click confirm mà không đọc kỹ nội dung.
3. Malicious Contract Interaction
Attacker deploy một smart contract có function tên giống dApp hợp lệ (ví dụ claimAirdrop()) nhưng thực ra gọi transferFrom để drain token. Nếu user đã approve token cho contract đó trước đó, chỉ cần trigger function là đủ. Blind signing che giấu địa chỉ contract thực sự.
4. Cross-chain Replay Attack
Một signature hợp lệ trên chain A đôi khi có thể replay trên chain B nếu contract address giống nhau và không có chain ID trong signature. eth_sign không tự động include chain ID — EIP-712 khắc phục điều này bằng domainSeparator.
| Vụ việc | Thiệt hại | Cơ chế | Bài học |
| Ledger Connect Kit (2023) |
~600K USD |
Supply chain attack: npm package của Ledger bị inject malicious code drain ví qua approve |
Ngay cả thư viện "chính thống" cũng có thể bị compromise |
| OpenSea Phishing (2022) |
~1.7M USD |
Giả mạo email migration, user ký Wyvern order bán NFT giá 0 |
Luôn verify URL và đọc kỹ order content |
| Monkey Drainer (2022–2023) |
~13M USD |
Drainer-as-a-service: fake mint sites, setApprovalForAll, permit phishing |
Simulate transaction trước khi ký |
| Permit2 Phishing (2023) |
Nhiều vụ nhỏ |
Uniswap Permit2 signature bị phishing — user ký off-chain, attacker submit on-chain |
Không ký permit signature trên site không phải Uniswap |
| Kevin Rose (2023) |
~1.1M USD NFT |
Founder Moonbirds ký một Seaport order — bị social engineer ký off-chain signature transfer toàn bộ NFT |
Kể cả expert cũng có thể bị blind signing |
Điểm chung của tất cả các vụ trên: signature hợp lệ về mặt kỹ thuật — không phải bug trong protocol. Attacker không cần hack private key. Họ chỉ cần khiến user ký một message đã được craft cẩn thận.
EIP-712 (Typed Structured Data Hashing and Signing) định nghĩa chuẩn để ký structured data thay vì raw bytes — wallet có thể decode và hiển thị từng field rõ ràng cho user đọc trước khi ký.
// EIP-712 — Structured data thay vì raw hex
// Trước EIP-712 — eth_sign: ký raw hash
eth_sign(account, "0x3c21d4b8c5f91cbf22fa9424df98b1a81e4...")
// ← User không biết hash này chứa gì
// Với EIP-712 — signTypedData: ký structured data
signTypedData(account, {
domain: {
name: "Uniswap",
chainId: 1, // chain ID prevent replay attacks
verifyingContract: "0x68b3..."
},
types: {
Swap: [
{ name: "tokenIn", type: "address" },
{ name: "tokenOut", type: "address" },
{ name: "amountIn", type: "uint256" },
{ name: "deadline", type: "uint256" }
]
},
message: {
tokenIn: "0xA0b8...", // USDC
tokenOut: "0xC02a...", // WETH
amountIn: "100000000", // 100 USDC
deadline: "1709823600" // 1 hour
}
})
// ← Wallet hiển thị: "Swap 100 USDC → WETH, deadline 1 giờ"
Clear Signing với Ledger Plugin
Ledger đi xa hơn EIP-712 với Clear Signing Plugin (Blind Signing Killer initiative): dApp deploy một plugin đặc biệt trên Ledger, plugin này decode transaction calldata và hiển thị ngữ cảnh rõ ràng trên màn hình hardware wallet. Không chỉ show raw parameters mà còn interpret ý nghĩa: "Bạn đang swap 100 USDC lấy ≈0.04 ETH trên Uniswap."
🛡️
Transaction Simulation — Tầng bảo vệ quan trọng
Một số wallet hiện đại (MetaMask Snaps, Rabby, Phantom) tích hợp transaction simulation: trước khi ký, wallet simulate transaction trên fork của mainnet và hiển thị kết quả dự kiến — "Bạn sẽ nhận ~0.04 ETH, mất 100 USDC, gas ~$3." Nếu simulation cho thấy kết quả bất thường (mất token không mong đợi, không nhận gì), đó là dấu hiệu cảnh báo. Rabby Wallet và MetaMask Snaps hỗ trợ tốt tính năng này.
EIP-2612 Permit cho phép approve token spending qua off-chain signature thay vì on-chain transaction — tiết kiệm gas. User ký một message (EIP-712), sau đó bất kỳ ai giữ signature đó có thể gọi permit() on-chain để submit approval.
🔴
Tại sao Permit nguy hiểm hơn Approve thường?
Khi bạn on-chain approve một contract, transaction xuất hiện ngay trên blockchain — bạn có thể thấy và revoke trước khi bị dùng. Permit signature là off-chain — không có gì xuất hiện on-chain cho đến khi attacker submit. Bạn không thể revoke một signature đã ký mà chưa được submit. Và khi nó được submit, action xảy ra trong cùng transaction — không có window để phản ứng.
Phishing flow với Permit phổ biến nhất:
- Attacker tạo site giả mạo (fake airdrop, fake mint, fake claim).
- Site request user ký một EIP-712 message — trông bình thường.
- Message thực ra là
Permit cho USDC/USDT/token khác, spender = attacker address, value = max uint256.
- User ký (không đọc kỹ hoặc wallet không decode rõ).
- Attacker submit signature on-chain →
permit() được gọi → transferFrom(victim, attacker, balance) → tất cả token bị drain.
Nhận diện Permit request: Nếu wallet hiển thị EIP-712 message có các field owner, spender, value, deadline, nonce — đó là Permit. Hỏi: tại sao site này cần bạn ký Permit? Nếu không có lý do rõ ràng, đừng ký.
Trước khi ký bất kỳ transaction nào
- Verify URL cẩn thận: Phishing sites thường dùng domain rất giống (uniswap-app.com thay vì app.uniswap.org). Bookmark các dApp quan trọng, không vào qua Google ads hay link trong Discord.
- Đọc nội dung transaction: Nếu wallet hiện hex thô mà bạn không decode được, đó là red flag. Đừng ký cho đến khi hiểu rõ.
- Dùng simulation: Wallet như Rabby, MetaMask với simulation snap, hay Tenderly (paste calldata) để xem kết quả dự kiến trước khi ký.
- Check contract trên Etherscan: Paste contract address vào Etherscan/Polygonscan — verified contract, số transactions, có comments cảnh báo không?
Về token approvals
- Không approve unlimited: Nhiều dApp để default là max uint256 — edit xuống đúng amount bạn cần cho transaction này.
- Revoke định kỳ: Dùng Revoke.cash hoặc Etherscan Token Approval Checker để xem và revoke các approval cũ không còn cần thiết.
- Không setApprovalForAll cho sites không tin: Nếu site yêu cầu setApprovalForAll mà bạn không biết tại sao, đó là dấu hiệu phishing.
Hardware wallet
- Tắt blind signing khi không cần: Trong settings Ledger/Trezor, chỉ bật blind signing khi thực sự cần thiết và biết rõ mình đang ký gì.
- Nếu hardware wallet hỏi enable blind signing: Dừng lại. Tìm cách khác hoặc dùng wallet khác có clear signing support.
🛠
Tools hữu ích để tự bảo vệ
Revoke.cash — Xem và revoke tất cả token approvals trên mọi chain.
Rabby Wallet — Chrome extension với transaction simulation built-in, hiển thị balance changes trước khi ký.
Tenderly — Simulate transaction bằng cách paste calldata, xem full execution trace.
Pocket Universe — Browser extension cảnh báo khi detect malicious transaction pattern.
Fire — Extension decode và explain EIP-712 messages.
Ledger và Trezor có giúp tránh blind signing không?+
Một phần. Hardware wallet hiển thị giao dịch trên màn hình nhỏ nhưng nhiều dApp vẫn gửi raw hex mà thiết bị không decode được, buộc user phải enable blind signing trong settings để confirm. Ledger đã tích cực push clear signing — yêu cầu dApp dùng Ledger plugin để hiển thị nội dung rõ ràng trên thiết bị. Trezor tương tự với metadata hiển thị. Nếu hardware wallet hỏi bạn có muốn enable blind signing không, đó là dấu hiệu nội dung không decode được — cần thêm cẩn thận.
setApprovalForAll có phải blind signing không?+
setApprovalForAll không phải blind signing theo nghĩa kỹ thuật — MetaMask decode được function name và hiển thị. Nhưng nhiều user không hiểu ý nghĩa thực sự: nó cấp cho một địa chỉ quyền transfer TOÀN BỘ NFT trong collection đó, không giới hạn. Nhiều phishing site giả mạo mint page yêu cầu setApprovalForAll thay vì mint thực sự. Luôn đọc kỹ function name và hiểu ý nghĩa trước khi ký — không chỉ nhìn vào tên dApp hiển thị.
EIP-712 có giải quyết được hoàn toàn vấn đề blind signing không?+
EIP-712 cải thiện đáng kể với structured data thay vì raw hex, wallet có thể hiển thị từng field. Nhưng không giải quyết hoàn toàn: wallet vẫn cần ABI để decode đúng; user vẫn cần đọc và hiểu nội dung được hiển thị; Permit signature dùng EIP-712 nhưng vẫn bị dùng trong phishing vì user không nhận ra nó cấp quyền tiêu token. Clear signing plugin-based của Ledger đi xa hơn bằng cách interpret context và hiển thị ý nghĩa thực sự của transaction.
Permit signature là gì và tại sao nguy hiểm hơn approve thường?+
EIP-2612 Permit cho phép approve token spending qua off-chain signature thay vì on-chain transaction — không tốn gas. Nguy hiểm hơn approve thường vì: (1) Signature không xuất hiện on-chain cho đến khi bị dùng — không thể revoke trước khi attacker submit. (2) User ký một message trông vô hại, nhưng attacker dùng signature đó để call permit() trên token contract, sau đó transferFrom toàn bộ balance trong cùng transaction. (3) MetaMask và nhiều wallet chưa hiển thị rõ permit signature. Đây là vector phishing ngày càng phổ biến.
Tài liệu tham khảo
EIPs, post-mortem và security resources về blind signing.
- Ethereum Foundation. EIP-712: Typed structured data hashing and signing. eips.ethereum.org/EIPS/eip-712. — Chuẩn chính thức để giải quyết blind signing.
- Ethereum Foundation. EIP-2612: Permit Extension for EIP-20 Signed Approvals. eips.ethereum.org/EIPS/eip-2612. — Permit signature specification.
- Revoke.cash. Token Approval Checker and Revocation Tool. revoke.cash. — Tool thiết yếu để quản lý và revoke approvals.
- ZachXBT. Monkey Drainer Post-mortem. Twitter/X, 2022–2023. — Phân tích drainer campaign $13M.
- ZRO Research. Hardware Wallet Là Gì? twt.vn/hardware-wallet-la-gi/. — Bảo mật hardware wallet và blind signing.
- ZRO Research. Private Key Là Gì? twt.vn/private-key-la-gi/. — Cơ chế ký transaction.
- ZRO Research. Các Vụ Hack Ví Lớn Nhất. twt.vn/cac-vu-hack-vi-lon-nhat/. — Case studies đầy đủ về hack liên quan blind signing.