
Cobo DeFi khóa học an toàn (phần dưới): Các lỗ hổng an toàn phổ biến trong DeFi và cách phòng ngừa
Tuyển chọn TechFlowTuyển chọn TechFlow

Cobo DeFi khóa học an toàn (phần dưới): Các lỗ hổng an toàn phổ biến trong DeFi và cách phòng ngừa
Phân tích nguyên nhân các sự cố an ninh lớn xảy ra trong ngành Web3 hơn một năm qua, và cách phòng tránh.
Tác giả: Max Cobo, Giám đốc An ninh
Bài viết này là bài thứ 24 của Cobo Global
Được MoleDAO mời, gần đây Max – Giám đốc An ninh của Cobo – đã chia sẻ một buổi học về an toàn DeFi tới cộng đồng qua mạng. Max đã điểm lại các sự cố an ninh lớn trong ngành Web3 hơn một năm qua, tập trung thảo luận nguyên nhân xảy ra và cách phòng tránh, tổng hợp các lỗ hổng bảo mật thông dụng trong hợp đồng thông minh cùng các biện pháp phòng ngừa, đồng thời đưa ra một số khuyến nghị an toàn cho cả nhà phát triển dự án và người dùng thông thường. Ở đây, chúng tôi chia nội dung chia sẻ của Max thành hai phần để đăng tải, giúp người yêu thích DeFi dễ dàng lưu giữ.
Phần trên: 《Khóa học An toàn DeFi của Cobo (Phần 1): Tổng kết các Sự cố An toàn DeFi Năm 2022》
Các dạng lỗ hổng DeFi phổ biến thường bao gồm: cho vay chớp nhoáng (flash loan), thao túng giá, vấn đề quyền hạn hàm, gọi bên ngoài tùy ý, vấn đề hàm fallback, lỗi logic nghiệp vụ, rò rỉ khóa riêng, tấn công lặp lại (reentrancy).

Thống kê sự cố an toàn tháng 11-12/2022
Chúng ta sẽ tập trung vào ba loại hình phổ biến: cho vay chớp nhoáng, thao túng giá và tấn công lặp lại.
Cho vay chớp nhoáng (Flash Loan)
-
Các cuộc tấn công phổ biến thường đi kèm với flash loan; tin tặc thích mượn lượng lớn vốn qua flash loan để thao túng giá, tấn công logic nghiệp vụ, v.v.
-
Nhà phát triển cần cân nhắc xem chức năng hợp đồng có thể bị lỗi do lượng vốn khổng lồ gây ra hay không, hoặc liệu kẻ tấn công có thể sử dụng lượng tiền lớn để tương tác với nhiều hàm trong hợp đồng trong cùng một giao dịch nhằm thu lợi.
-
Chúng ta thường thấy các giá trị số lượng Token trong hợp đồng được dùng để tính thưởng, hoặc dùng số lượng Token trong cặp giao dịch DEX tham gia vào các phép toán khác nhau. Do nhà phát triển khi thiết kế chưa tính đến khả năng kẻ tấn công có thể dùng flash loan để điều khiển các biến này, dẫn đến việc tài sản trong hợp đồng bị đánh cắp.
Bản thân flash loan là một sáng tạo trong DeFi, nhưng khi bị tin tặc lợi dụng, họ có thể mượn tiền mà không mất chi phí nào, thực hiện toàn bộ quy trình chênh lệch giá rồi hoàn trả khoản vay; phần còn lại chính là lợi nhuận. Họ chẳng mất gì ngoài một khoản phí gas nhỏ nhưng có thể thu lợi lớn.
Trong hai năm qua, flash loan đã gây ra rất nhiều vấn đề. Nhiều dự án DeFi trông có vẻ sinh lời cao, nhưng thực tế chất lượng đội ngũ phát triển rất khác biệt. Ví dụ, mã nguồn có thể được mua sẵn; dù bản thân code không có lỗ hổng, logic vẫn có thể sai sót. Chẳng hạn, từng có một dự án phát thưởng định kỳ theo số lượng token nắm giữ, nhưng bị tin tặc dùng flash loan mua số lượng lớn token; khi phát thưởng, phần lớn lợi nhuận rơi vào tay kẻ tấn công. Ngoài ra, có những dự án dùng token để tính giá, có thể bị ảnh hưởng giá qua flash loan. Các bên phát triển nên cảnh giác với những rủi ro này.
Thao túng giá
Vấn đề thao túng giá liên quan chặt chẽ đến flash loan, chủ yếu do một số tham số trong quá trình tính giá có thể bị người dùng kiểm soát. Có hai dạng lỗi phổ biến:
-
Một là dùng dữ liệu từ bên thứ ba để tính giá nhưng sử dụng sai cách hoặc thiếu kiểm tra, dẫn đến giá bị thao túng ác ý.
-
Hai là dùng số dư token tại một số địa chỉ làm biến tính toán, trong khi số dư này có thể bị tăng/giảm tạm thời.
Tấn công lặp lại (Reentrancy Attack)
Một trong những nguy cơ chính khi gọi hợp đồng bên ngoài là chúng có thể chiếm quyền điều khiển luồng thực thi, và thực hiện các thay đổi không lường trước đối với dữ liệu của bạn.
```
mapping (address => uint) private userBalances; function withdrawBalance() public {
uint amountToWithdraw = userBalances[msg.sender];
(bool success, ) = msg.sender.call.value(amountToWithdraw)(""); // Nếu msg.sender là một hợp đồng, mã fallback của nó sẽ được thực thi và có thể gọi lại withdrawBalance để thực hiện tấn công lặp lại
require(success);
userBalances[msg.sender] = 0;
}
```
Do số dư người dùng chỉ được đặt bằng 0 ở cuối hàm, các lần gọi thứ hai (và tiếp theo) vẫn thành công, cho phép rút tiền liên tục.
Tấn công lặp lại có thể xuất hiện dưới nhiều hình thức tùy theo hợp đồng, có thể kết hợp nhiều hàm trong một hợp đồng hoặc giữa các hợp đồng khác nhau. Vì vậy, khi giải quyết vấn đề này cần lưu ý:
1. Không chỉ ngăn chặn lặp lại trong một hàm đơn lẻ;
2. Tuân thủ mô hình Checks-Effects-Interactions khi lập trình;
3. Sử dụng modifier chống lặp lại đã được kiểm chứng theo thời gian.
Điều đáng sợ nhất là tự phát minh lại bánh xe—tự viết mọi thứ từ đầu. Trong lĩnh vực này, có rất nhiều phương pháp an toàn tốt nhất đã được xác lập, chúng ta chỉ cần tận dụng chứ không cần tự làm lại. Khi bạn tự làm một "bánh xe", nó chưa được kiểm chứng kỹ càng, rõ ràng tỷ lệ gặp sự cố cao hơn nhiều so với việc dùng một "bánh xe" đã trưởng thành và trải qua thử thách.
Omni Protocol bị tin tặc tấn công do vấn đề lặp lại, và còn có một câu chuyện đằng sau:
Câu chuyện đằng sau lỗ hổng Omni Protocol — Cuộc đấu giữa bốn tin tặc
Mempool của Ethereum luôn bị hàng loạt tin tặc theo dõi sát sao, họ liên tục phân tích giao dịch và thực hiện front-run (đi trước) các giao dịch sinh lời để kiếm lợi. Giao dịch tấn công do người phát hiện lỗ hổng Omni Protocol gửi đi đã bị hai tin tặc khác phát hiện, họ dùng robot front-run để gửi giao dịch qua flashbot và chiếm đoạt 1.200 ETH từ giao thức Omni Protocol, trong khi người phát hiện lỗ hổng chỉ nhận được 480 ETH. Trong thời gian này, một tin tặc khác nữa phát hiện giao dịch tấn công của nhóm front-run trên flashbot, và thực hiện tấn công sandwich (ba lớp) bằng cách tận dụng đặc điểm giao dịch tấn công phải mua token ERC20 Doodle, thu lợi 151 ETH.
Người phát hiện lỗ hổng không phải là người thu lợi nhiều nhất; những “thợ săn” khác trong khu rừng tối mới là người kiếm được nhiều hơn. Trong hệ sinh thái này, đâu đâu cũng có thợ săn, và các thợ săn có thể trở thành con mồi của nhau. Ngay cả người khởi xướng tấn công, nếu là người mới, cũng khó lấy được phần lớn tiền của dự án trừ khi rút sạch một lần. Rất nhiều người sẽ dùng phí gas cao hơn để抢先 thực hiện giao dịch; trong quá trình front-run, nếu liên quan đến mua bán token trên DEX, có thể bị tấn công sandwich, tình hình rất hỗn loạn.
Khuyến nghị an toàn
Cuối cùng là một số khuyến nghị an toàn dành cho nhà phát triển dự án và người dùng thông thường.
Gợi ý an toàn cho Nhà phát triển Dự án
Một, tuân thủ các thực hành an toàn tốt nhất khi phát triển hợp đồng.
Hai, hợp đồng có thể nâng cấp và tạm dừng: Nhiều cuộc tấn công không rút toàn bộ tiền một lúc mà chia thành nhiều giao dịch. Nếu có cơ chế giám sát tương đối đầy đủ thì có thể phát hiện kịp thời. Khi phát hiện, nếu hợp đồng có thể tạm dừng, tổn thất có thể được giảm thiểu hiệu quả.
Ba, áp dụng khóa thời gian (time lock): Như trường hợp Ankr, nếu có time lock, ví dụ 48 giờ mới thực hiện được, thì trong khoảng thời gian đó nhiều người có thể phát hiện người sáng lập đã cập nhật lại phương pháp mint và ai cũng có thể dùng. Người giám sát sẽ biết dự án đã bị hack, có thể thông báo cho đội ngũ dự án xử lý. Ngay cả khi thông báo mà không ai phản hồi, ít nhất cũng có thể rút tiền của mình ra trước để bảo vệ lợi ích. Vì vậy, một dự án không có time lock về lý thuyết sẽ làm tăng xác suất xảy ra sự cố.
Bốn, tăng cường đầu tư an toàn, xây dựng hệ thống an toàn toàn diện: An toàn không phải là một điểm hay một đường thẳng, mà là một hệ thống. Đừng nghĩ rằng chỉ cần hợp đồng được nhiều công ty kiểm toán là xong. Kết quả là hacker Triều Tiên đánh cắp khóa riêng, kể cả multi-sig cũng bị lấy mất toàn bộ khóa. Hoặc mô hình kinh tế có vấn đề, mô hình nghiệp vụ có vấn đề... Có hàng ngàn cách khiến tiền bị mất, chỉ xem trước sự kiện có thể loại bỏ hết rủi ro hay không. Nên cố gắng thực hiện mô hình hóa rủi ro, từng bước loại bỏ phần lớn rủi ro, phần rủi ro còn lại cũng nằm trong mức chấp nhận được. An toàn và hiệu quả không thể đạt được cùng lúc, cần có sự đánh đổi. Nhưng nếu hoàn toàn bỏ qua an toàn, không đầu tư gì vào an toàn, thì bị tấn công là điều bình thường.
Năm, nâng cao nhận thức an toàn cho tất cả nhân viên: Nâng cao nhận thức an toàn không đòi hỏi nhiều kỹ thuật. Trên Twitter, chúng ta thường thấy nhiều người bị lừa mất NFT do phishing, thực ra các hình thức lừa đảo đều khai thác điểm yếu của con người. Chỉ cần cẩn trọng hơn một chút là có thể tránh được. Trong môi trường Web3, chỉ cần hỏi thêm một chút "tại sao", suy nghĩ sâu hơn một chút là có thể tránh được rất nhiều vấn đề.
Sáu, phòng ngừa hành vi xấu nội bộ, tăng cường kiểm soát rủi ro khi nâng cao hiệu quả: Lấy Ankr làm ví dụ. Thứ nhất, Owner hợp đồng là single-sig chứ không phải multi-sig, mất khóa riêng là mất kiểm soát toàn bộ dự án. Thứ hai, không dùng time lock, các thao tác cập nhật then chốt được thực hiện ngay lập tức mà không ai hay biết, rất bất công với người tham gia giao thức. Hơn nữa, cơ chế an toàn nội bộ không phát huy tác dụng gì.
Làm thế nào để giao thức trên chuỗi vừa đảm bảo hiệu quả, vừa nâng cao an toàn? Tôi xin quảng cáo một chút: khuyên dùng Cobo Safe. Nếu một dự án dùng multi-sig, khi thao tác sẽ hơi ảnh hưởng hiệu suất. Với Cobo Safe, có thể chỉ định cá nhân thực hiện thao tác cụ thể, ví dụ 3/5 multi-sig; có thể cấp quyền cho một địa chỉ cụ thể thực hiện thao tác nhất định, ví dụ giao cho một nút đáng tin cậy giám sát rủi ro an toàn; nếu phát hiện giao thức đang bị tấn công, tài sản đang dần chuyển sang địa chỉ hacker, nếu hợp đồng có chức năng tạm dừng, chúng ta có thể trao quyền tạm dừng cho một người nào đó để thực hiện.
Ví dụ khác, đối với nhà tạo lập thị trường (market maker) trên DEX, nếu không giới hạn quyền Owner, Owner có thể chuyển tiền sang địa chỉ khác. Qua Cobo Safe, có thể giới hạn địa chỉ nhận tiền, giới hạn chỉ được thao tác một vài cặp tiền nhất định, thiết lập chỉ được rút tiền về một địa chỉ cụ thể. Cobo Safe vừa nâng cao hiệu suất, vừa đảm bảo an toàn nhất định.
Bảy, an toàn khi tích hợp bên thứ ba: Là một mắt xích trong hệ sinh thái, mỗi dự án đều có đối tác thượng nguồn và hạ nguồn. Trong an toàn có nguyên tắc "mặc định các đối tác thượng/hạ nguồn đều không an toàn". Dù là đối tác trên hay dưới, đều phải kiểm tra. Chúng ta rất khó kiểm soát bên thứ ba, rủi ro phơi nhiễm an toàn thực tế rất lớn, vì vậy cần thận trọng khi tích hợp bên thứ ba. Hợp đồng mở mã nguồn, có thể tích hợp và gọi; nếu không mở mã nguồn thì tuyệt đối không được tham chiếu. Bởi chúng ta không biết logic bên trong là gì, hoặc nếu hợp đồng được tích hợp là loại có thể nâng cấp, dùng bình thường có thể ổn, nhưng không thể lường trước một ngày đẹp trời nó được nâng cấp thành hợp đồng ác ý—điều này nằm ngoài tầm kiểm soát.
Người dùng/LP làm sao đánh giá được hợp đồng thông minh có an toàn?
Đối với người dùng thông thường, chúng ta đánh giá độ an toàn của dự án chủ yếu qua sáu điểm sau:
Một, hợp đồng có mở mã nguồn hay không: Mọi dự án không mở mã nguồn đều tuyệt đối không tham gia, vì chúng ta không thể biết nội dung hợp đồng viết gì.
Hai, Owner có dùng multi-sig không, multi-sig có phi tập trung không: Nếu không dùng multi-sig, chúng ta không thể đánh giá logic nghiệp vụ và nội dung dự án; khi xảy ra sự cố an toàn, không thể xác định là do hacker hay không. Ngay cả khi dùng multi-sig, cũng cần đánh giá xem multi-sig có thực sự phi tập trung không.
Ba, lịch sử giao dịch hiện có của hợp đồng: Đặc biệt trên thị trường có rất nhiều dự án lừa đảo钓鱼, có thể tạo hợp đồng giống y hệt. Lúc này cần xem thời gian triển khai hợp đồng, số lần tương tác, v.v.—đây đều là tiêu chí đánh giá độ an toàn của hợp đồng.
Bốn, hợp đồng có phải là proxy contract không, có thể nâng cấp không, có time lock không: Nếu hợp đồng hoàn toàn không thể nâng cấp thì quá cứng nhắc, nên khuyến khích hợp đồng có thể nâng cấp. Nhưng nâng cấp phải có phương pháp: khi nâng cấp, thay đổi tham số quan trọng, cần có time lock, tạo cửa sổ thời gian để người dùng đánh giá xem việc nâng cấp thật sự có hại hay có lợi—đây cũng là cách minh bạch công khai.
Năm, hợp đồng đã được nhiều tổ chức kiểm toán chưa (không盲mục tin tưởng công ty kiểm toán), quyền Owner có quá lớn không: Trước hết, đừng chỉ tin một công ty kiểm toán, vì các công ty kiểm toán khác nhau, các kiểm toán viên khác nhau sẽ nhìn vấn đề dưới góc độ khác nhau. Nếu một dự án có kết quả kiểm toán từ nhiều tổ chức, phát hiện nhiều vấn đề khác nhau và đội ngũ dự án đã sửa chữa hết, thì an toàn hơn so với chỉ được một công ty kiểm toán duy nhất. Một đội ngũ dự án có trách nhiệm sẽ tìm nhiều tổ chức kiểm toán để kiểm tra chéo.
Tiếp theo, cần xem quyền Owner có quá lớn không. Ví dụ một số dự án "bắt máu" (Ponzi), Owner có thể hoàn toàn kiểm soát tiền người dùng: nếu mua token ít thì giao dịch bình thường, nếu mua số lượng lớn thì Owner lập tức khóa lại, không thể giao dịch. Một số dự án NFT cũng vậy. Một dự án bình thường, quyền Owner nhất định phải được kiểm soát, như vậy sẽ không có quá nhiều thao tác nguy hiểm, các thao tác cũng dùng time lock để người dùng biết rõ đang làm gì. Đặc biệt khi thị trường xấu, có rất nhiều dự án "chạy trốn", vì vậy mọi người cần đặc biệt chú ý đến quyền hạn của Owner.
Sáu, chú ý đến oracle: Nếu dự án dùng oracle hàng đầu trên thị trường, cơ bản sẽ không có vấn đề lớn. Nhưng nếu dùng oracle tự xây dựng, hoặc dùng oracle cho phép bất kỳ ai thế chấp token tùy tiện để nhập giá, thì cần cảnh giác. Khi phát hiện oracle có thể có vấn đề hoặc có nguy cơ bị thao túng, dù lợi nhuận dự án có cao đến đâu cũng không nên tham gia.
Chào mừng tham gia cộng đồng chính thức TechFlow
Nhóm Telegram:https://t.me/TechFlowDaily
Tài khoản Twitter chính thức:https://x.com/TechFlowPost
Tài khoản Twitter tiếng Anh:https://x.com/BlockFlow_News













