Cuộc tấn công tái nhập: Hiểu và Ngăn chặn Lỗ hổng Hợp đồng thông minh này

Tôi đã dành hàng giờ đồng hồ để gỡ lỗi các lỗ hổng hợp đồng, và cho phép tôi nói với bạn - các cuộc tấn công tái nhập là những kẻ giết người thầm lặng của hợp đồng thông minh. Chúng đơn giản một cách đánh lừa nhưng lại hiệu quả một cách tàn khốc. Hãy cùng khám phá chúng là gì và làm thế nào để ngăn chặn chúng trước khi chúng làm cạn kiệt quỹ của bạn.

Khi tôi lần đầu tiên gặp phải một lỗ hổng tái nhập, tôi đã mất hàng giờ đồng hồ để cố gắng hiểu cách mà ai đó có thể khai thác một đoạn mã dường như vô hại như vậy. Khái niệm này thật sự đơn giản một cách gây thất vọng: một hợp đồng có thể gọi lại vào một hợp đồng khác trước khi lần thực thi đầu tiên hoàn tất.

Hãy tưởng tượng điều này: ContractA có 10 ETH và ContractB đã gửi 1 ETH vào đó. Khi ContractB rút tiền, ContractA gửi ETH trước khi cập nhật số dư của B thành không. Lỗi sắp xếp nhỏ này tạo ra một lỗ hổng bảo mật lớn.

Chuyện gì xảy ra? Hàm fallback của hợp đồng độc hại ngay lập tức gọi lại withdraw(), và vì số dư chưa được cập nhật, nó lại vượt qua kiểm tra số dư một lần nữa! Chu trình này lặp lại cho đến khi ContractA hoàn toàn bị rút cạn. Thật thông minh, phải không?

Đây là cách một kẻ tấn công khai thác điều này trong mã:

// Hợp đồng tấn công gọi rút tiền() // ContractA gửi ETH kích hoạt fallback() // fallback() gọi withdraw() một lần nữa trước khi số dư được cập nhật // Rửa và lặp lại cho đến khi tất cả tiền bị đánh cắp

Tôi đã thấy nhiều dự án mất hàng triệu vì họ không hiểu được vector tấn công đơn giản này. Tôi cảm thấy tức giận khi có nhiều nhà phát triển vẫn mắc phải sai lầm nghiệp dư này.

Ba Kỹ Thuật Để Bảo Vệ Hợp Đồng Của Bạn

  1. Bộ điều chỉnh nonReentrant

    Điều này khóa hợp đồng trong quá trình thực thi, ngăn chặn bất kỳ chức năng nào được đánh dấu bằng bộ điều chỉnh này không bị vào lại. Đơn giản nhưng hiệu quả.

  2. Mô hình Kiểm tra - Tác động - Tương tác

    Đây là sở thích cá nhân của tôi. Thay vì:

    // CÓ THỂ BỊ TẤN CÔNG require(balance > 0); gửi(ether); số dư = 0;

    Làm điều này:

    // AN TOÀN require(balance > 0); balance = 0; // Cập nhật trạng thái TRƯỚC các tương tác bên ngoài gửi(ether);

    Luôn cập nhật trạng thái của bạn trước khi gửi ETH hoặc token!

  3. GlobalReentrancyGuard

    Đối với các dự án có nhiều hợp đồng tương tác, điều này cung cấp sự bảo vệ trên toàn bộ hệ sinh thái hợp đồng của bạn bằng cách sử dụng một cơ chế khóa chia sẻ.

Những kỹ thuật này không chỉ mang tính học thuật - chúng đã cứu vô số dự án khỏi sự sụp đổ tài chính hoàn toàn.

Quá nhiều nhà phát triển vẫn nghĩ "nó sẽ không xảy ra với tôi" và bỏ qua những biện pháp bảo vệ này. Đừng trở thành người như vậy. Mỗi chức năng duy nhất gửi ETH hoặc token nên triển khai ít nhất một trong những cơ chế bảo vệ này.

Hãy nhớ rằng, trong phát triển hợp đồng thông minh, sự hoài nghi là một tính năng, không phải là một lỗi. Một sự bảo vệ bị bỏ lỡ có thể khiến bạn mất tất cả.

ETH1.94%
Xem bản gốc
Trang này có thể chứa nội dung của bên thứ ba, được cung cấp chỉ nhằm mục đích thông tin (không phải là tuyên bố/bảo đảm) và không được coi là sự chứng thực cho quan điểm của Gate hoặc là lời khuyên về tài chính hoặc chuyên môn. Xem Tuyên bố từ chối trách nhiệm để biết chi tiết.
  • Phần thưởng
  • Bình luận
  • Đăng lại
  • Retweed
Bình luận
0/400
Không có bình luận
  • Ghim
Giao dịch tiền điện tử mọi lúc mọi nơi
qrCode
Quét để tải xuống ứng dụng Gate
Cộng đồng
Tiếng Việt
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)