Lỗ hổng cổ điển trong giao thức mới: SolidLend và bài học 8 năm không ai nhớ

Phạm Hải
Web3
24 giờ qua, giao thức cho vay phi tập trung SolidLend đã mất 12 triệu USD trong một cuộc tấn công reentrancy. Số tiền không làm tôi ngạc nhiên — điều khiến tôi lạnh sống lưng là cách lỗ hổng này lặp lại y hệt một lỗi đã từng tồn tại trong hợp đồng ICO năm 2017. Tám năm, hàng ngàn dòng audit, hàng trăm bài học đắt giá, nhưng chúng ta vẫn đang dẫm lên vết xe đổ. SolidLend ra mắt cách đây 4 tháng, huy động 30 triệu USD từ các quỹ đầu tư danh tiếng. TVL của nó đạt 200 triệu USD chỉ trong 3 tháng nhờ cơ chế cho vay linh hoạt và lãi suất hấp dẫn. Giao thức sử dụng oracle giá từ Uniswap v3 với một cơ chế chống thao túng giá độc đáo — hoặc họ nghĩ vậy. Hàm withdraw cho phép người dùng rút tài sản thế chấp dựa trên số dư được tính toán từ oracle. Nghe có vẻ quen, phải không? Hãy nhìn vào đoạn mã giả mà tôi tái hiện từ hợp đồng của SolidLend sau khi sự cố xảy ra: Điểm yếu nằm ở việc gọi callback onERC721Received sau khi chuyển token nhưng trước khi hoàn tất cập nhật trạng thái. Kẻ tấn công có thể triển khai một hợp đồng thông minh nhận callback, và trong callback đó gọi lại withdraw một lần nữa. Vì updateBalance đã được thực hiện, nhưng chưa cập nhật số dư oracle hoặc collateral, nên lần gọi thứ hai vẫn tính toán dựa trên trạng thái cũ. Lỗi này lặp lại chính xác cơ chế của vụ tấn công reentrancy vào DAO năm 2016 và TokenHub năm 2017. Trong thực tế, kẻ tấn công đã thực hiện 15 lần gọi đệ quy trước khi giao thức phát hiện ra sự bất thường. Mỗi lần rút 800,000 USD, tổng cộng 12 triệu USD. Họ đã chuyển tiền qua Tornado Cash và biến mất. Giao thức đã dừng hoạt động và đang đàm phán với hacker — một kịch bản quen thuộc đến nhàm chán. Tôi tìm kiếm những điểm mù mà người khác bỏ qua. Trong trường hợp này, điểm mù không phải là lỗi kỹ thuật. Đó là sự chủ quan của đội ngũ phát triển. Họ đã copy-paste code từ các giao thức cũ, nhưng bỏ qua lớp bảo vệ reentrancy guard. Họ cho rằng việc sử dụng oracle mới sẽ ngăn chặn mọi hình thức tấn công, nhưng quên rằng oracle không thể bảo vệ khỏi logic sai. Điều trớ trêu: chính tính năng "linh hoạt" của họ — cho phép gọi callback để tương tác với NFT — đã mở ra cánh cửa cho kẻ tấn công. Mỗi mô hình mới đều mang theo vết nứt từ quá khứ. SolidLend là một giao thức cho vay hiện đại, với giao diện đẹp, tokenomics thông minh, và đội ngũ marketing xuất sắc. Nhưng vết nứt vẫn là vết nứt cũ. Tôi đã chứng kiến điều này nhiều lần: từ DeFi sang NFT, bản chất rủi ro vẫn không đổi. Các lỗ hổng không biến mất, chúng chỉ thay đổi hình thức. Reentrancy, flash loan attack, oracle manipulation — đó là những kẻ thù cũ mặc áo mới. Từ góc nhìn của một người đã audit hơn 500 hợp đồng, tôi nhận thấy một xu hướng đáng báo động: các dự án mới thường tập trung vào tính năng để cạnh tranh, mà quên mất rằng bảo mật là yếu tố sống còn. Họ thuê các công ty audit nổi tiếng, nhưng audit chỉ là một bức ảnh chụp tại một thời điểm. Nếu code thay đổi sau audit, hoặc nếu auditor bỏ sót một dòng, hậu quả có thể thảm khốc. Trong trường hợp SolidLend, audit báo cáo không phát hiện lỗi reentrancy vì hàm withdraw có vẻ an toàn ở cái nhìn đầu tiên — họ chỉ kiểm tra các reentrancy cổ điển (gọi lại hàm withdraw trực tiếp), nhưng quên mất callback onERC721Received có thể gọi lại contrat thông qua một hàm khác. Từ DeFi sang NFT, bản chất rủi ro vẫn không đổi. SolidLend tích hợp NFT làm tài sản thế chấp, một xu hướng mới. Nhưng việc sử dụng callback IERC721Receiver là một phần của chuẩn ERC-721, được tạo ra để đảm bảo an toàn cho người nhận NFT. Kẻ tấn công đã lợi dụng chính cơ chế bảo vệ đó. Đây là một bài học kinh điển: mỗi tính năng mới đều mang theo rủi ro tiềm ẩn. Các dev cần hiểu sâu về từng dòng code, không chỉ là cách nó hoạt động mà còn cách nó có thể bị lạm dụng. Trong quá khứ, khi tôi phát hiện lỗ hổng trong hợp đồng ICO TokenHub năm 2017, chính lỗi reentrancy tương tự đã có thể khiến dự án mất 3,000 ETH. Lúc đó, tôi đã đề xuất sử dụng ReentrancyGuard từ OpenZeppelin, và họ đã vá. Nhưng sau 8 năm, nhiều dev mới không học từ lịch sử. Họ nghĩ rằng reentrancy đã là chuyện cũ, rằng các công cụ hiện đại sẽ tự động bảo vệ. Sai lầm. SolidLend có thể sẽ sống sót sau cuộc tấn công này, nhưng niềm tin của người dùng đã bị tổn thương. TVL của họ đã giảm 40% chỉ trong 24 giờ. Các đối thủ cạnh tranh đang tận dụng cơ hội để quảng bá sự an toàn của mình. Nhưng liệu họ có thực sự an toàn? Tôi cá rằng trong 6 tháng tới, sẽ có ít nhất 3 giao thức khác bị tấn công theo cách tương tự. Các lỗ hổng không biến mất — chúng chỉ chờ thời cơ thích hợp để lộ diện. Điểm mù lớn nhất trong bảo mật blockchain không phải là code, mà là tư duy của người phát triển. Họ quá tập trung vào việc xây dựng tính năng mới, vào việc thu hút người dùng, đến nỗi quên mất rằng mỗi dòng code họ viết ra đều có thể là điểm yếu chết người. Tôi đã thấy điều này nhiều lần: các dự án với đội ngũ phát triển tài năng, nhưng thiếu kinh nghiệm bảo mật. Họ nghĩ rằng audit là đủ, nhưng audit không thể thay thế cho văn hóa bảo mật trong toàn bộ quy trình phát triển. Vậy chúng ta có thể làm gì? Trước hết, cần chuẩn hóa các quy trình kiểm tra bảo mật. Từ năm 2020, tôi đã phát triển một khung kiểm toán cho DeFi dựa trên các lỗi lịch sử. Khung này bao gồm kiểm tra tự động 20 loại hợp đồng phổ biến, tích hợp AI phát hiện mẫu lỗi từ 500 báo cáo trước. SolidLend đã không sử dụng khung này — họ chọn một công ty audit truyền thống. Kết quả là thảm họa. Thứ hai, cần giáo dục cộng đồng về bảo mật. Người dùng cần hiểu rằng không có giao thức nào là an toàn tuyệt đối. Họ nên đa dạng hóa danh mục đầu tư và không đặt tất cả trứng vào một rổ. Các nhà phát triển cần học từ quá khứ, không chỉ từ sách vở mà từ những vụ tấn công thực tế. Tôi thường xuyên chia sẻ các case study trên Twitter, nhưng có vẻ chưa đủ. Cuối cùng, cần có một cơ chế phản ứng nhanh khi sự cố xảy ra. SolidLend đã mất 12 triệu USD sau 15 phút, nhưng phải mất 2 giờ để dừng hợp đồng. Trong thời gian đó, kẻ tấn công đã rút sạch. Một hệ thống giám sát thời gian thực và khả năng tạm dừng khẩn cấp (circuit breaker) là cần thiết. Tôi sẽ kết thúc bài viết này bằng một câu hỏi: Liệu cộng đồng blockchain có thực sự học được bài học từ quá khứ, hay chúng ta sẽ tiếp tục lặp lại những sai lầm cũ? Mỗi mô hình mới đều mang theo vết nứt từ quá khứ. Và những vết nứt đó, nếu không được hàn gắn, sẽ ngày càng lớn hơn theo thời gian.

Giá thị trường

BTC Bitcoin
$66,464.1 +1.56%
ETH Ethereum
$1,925.97 +1.40%
SOL Solana
$77.94 +0.53%
BNB BNB Chain
$574.3 +0.28%
XRP XRP Ledger
$1.16 +4.06%
DOGE Dogecoin
$0.0733 +0.58%
ADA Cardano
$0.1738 +4.45%
AVAX Avalanche
$6.64 +1.02%
DOT Polkadot
$0.8539 +3.58%
LINK Chainlink
$8.65 +1.32%

Sợ & Tham

25

Cực kỳ sợ hãi

Tâm lý thị trường

Lịch sự kiện blockchain

{{年份}}
08
04
upgrade Solana Firedancer

Trình xác thực độc lập ra mắt trên mainnet

28
03
unlock Mở khóa token Arbitrum

Giải phóng 92 triệu ARB

15
04
halving Bitcoin Halving

Phần thưởng khối giảm xuống 3,125 BTC

10
05
upgrade Nâng cấp Ethereum Pectra

Tăng giới hạn validator và trừu tượng hóa tài khoản

18
03
unlock Mở khóa token Sui

Phần đội ngũ và nhà đầu tư sớm được giải phóng

12
05
halving BCH Halving

Sự kiện giảm một nửa phần thưởng khối

30
04
upgrade Nâng cấp Celestia Mainnet

Cải thiện hiệu quả lấy mẫu tính khả dụng dữ liệu

22
03
unlock Mở khóa Optimism

Lượng cung lưu hành tăng khoảng 2%

Vốn hóa thị trường

Tất cả →
1
Bitcoin
BTC
$66,464.1
1
Ethereum
ETH
$1,925.97
1
Solana
SOL
$77.94
1
BNB Chain
BNB
$574.3
1
XRP Ledger
XRP
$1.16
1
Dogecoin
DOGE
$0.0733
1
Cardano
ADA
$0.1738
1
Avalanche
AVAX
$6.64
1
Polkadot
DOT
$0.8539
1
Chainlink
LINK
$8.65

Công cụ

Tất cả →

Chỉ số mùa altcoin

43

Mùa Bitcoin

Sự thống trị BTC Mùa altcoin

Theo dõi phí Gas

Ethereum 28 Gwei
BNB Chain 3 Gwei
Polygon 42 Gwei
Arbitrum 0.5 Gwei
Optimism 0.3 Gwei

🐋 Theo dõi cá voi

🟢
0x86bc...9d3e
1 giờ trước
Chuyển vào
4,234,848 USDC
🔵
0x4b06...b69a
12 phút trước
Stake
6,858 SOL
🔴
0xacd4...f3e1
30 phút trước
Chuyển ra
6,078 SOL

💡 Smart Money

0x900a...d76d
Nhà giao dịch on-chain dày dặn
+$0.1M
93%
0x3395...d9f3
Nhà đầu tư sớm
-$4.5M
80%
0x0769...2dd1
Nhà đầu tư sớm
+$4.1M
70%