Phân tích lỗ hổng của trình biên dịch Solidity: Những rủi ro không thể xem nhẹ của hợp đồng thông minh

robot
Đang tạo bản tóm tắt

Phân tích lỗ hổng trình biên dịch Solidity và biện pháp ứng phó

Trình biên dịch là một trong những thành phần cơ bản của hệ thống máy tính hiện đại, có chức năng chuyển đổi mã nguồn ngôn ngữ lập trình cấp cao thành mã lệnh có thể thực thi bởi máy tính. Mặc dù các nhà phát triển và nhân viên an ninh thường tập trung vào sự an toàn của mã ứng dụng chương trình, nhưng chính trình biên dịch như một chương trình máy tính cũng có thể tồn tại lỗ hổng an ninh, trong một số trường hợp có thể gây ra rủi ro an ninh nghiêm trọng.

Ví dụ, khi trình duyệt biên dịch và thực thi mã JavaScript, có thể do lỗ hổng của công cụ phân tích mà dẫn đến việc thực thi mã từ xa, khiến kẻ tấn công có thể kiểm soát trình duyệt của nạn nhân thậm chí cả hệ điều hành. Nghiên cứu cũng cho thấy, lỗi trong trình biên dịch C++ có thể dẫn đến việc thực thi mã từ xa và những hậu quả nghiêm trọng khác.

Trình biên dịch Solidity cũng tồn tại lỗ hổng bảo mật. Theo cảnh báo an ninh từ nhóm phát triển, nhiều phiên bản của trình biên dịch Solidity đã phát hiện ra vấn đề bảo mật.

Phân tích lỗ hổng biên dịch Solidity và biện pháp đối phó

Chức năng của trình biên dịch Solidity là chuyển đổi mã hợp đồng thông minh thành mã lệnh của máy ảo Ethereum (EVM). Cần phân biệt giữa lỗ hổng của trình biên dịch Solidity và lỗ hổng của chính EVM. Lỗ hổng EVM đề cập đến các vấn đề bảo mật khi máy ảo thực thi các lệnh, có thể ảnh hưởng đến toàn bộ mạng Ethereum. Trong khi đó, lỗ hổng của trình biên dịch Solidity đề cập đến các vấn đề khi chuyển đổi Solidity thành mã EVM, không ảnh hưởng trực tiếp đến mạng Ethereum, nhưng có thể dẫn đến mã EVM được tạo ra không nhất quán với dự kiến của nhà phát triển.

Do vì hợp đồng thông minh thường liên quan đến tài sản tiền điện tử của người dùng, bất kỳ lỗi nào do trình biên dịch gây ra đều có thể dẫn đến hậu quả nghiêm trọng. Chỉ thông qua việc kiểm toán mã nguồn hợp đồng, rất khó để phát hiện lỗ hổng của trình biên dịch, cần phải phân tích kết hợp với phiên bản cụ thể và mẫu mã.

Dưới đây là một số ví dụ thực tế, trình bày các hình thức, nguyên nhân và tác hại cụ thể của lỗ hổng trình biên dịch Solidity.

SOL-2016-9 HighOrderByteCleanStorage

Lỗ hổng này tồn tại trong các phiên bản trình biên dịch Solidity trước đó (>=0.1.6 <0.4.4).

Xem xét mã sau:

solidity hợp đồng C { uint32 a = 0x1234; uint32 b = 0; chức năng f() công cộng { a += 1; } function run() public view returns (uint) { return b; } }

Biến b không bị sửa đổi, hàm run() nên trả về giá trị mặc định 0. Nhưng trong mã do trình biên dịch phiên bản có lỗ hổng tạo ra, run() sẽ trả về 1.

Điều này là do EVM sử dụng các phần tử ngăn xếp kích thước 32 byte, trong khi Solidity hỗ trợ các kiểu dữ liệu nhỏ hơn 32 byte như uint32. Trình biên dịch cần thực hiện thao tác xóa cao để đảm bảo tính chính xác của dữ liệu. Khi xảy ra tràn số trong phép cộng, trình biên dịch không xóa chính xác bit cao, dẫn đến bit 1 bị tràn được ghi vào storage, ghi đè lên biến b.

SOL-2022-4 Ảnh hưởng của Bộ nhớ Assembly Ngang

Lỗi này tồn tại trong các phiên bản trình biên dịch từ >=0.8.13 đến <0.8.15.

Xem xét mã sau:

solidity hợp đồng C { function f() public pure returns (uint) { lắp ráp { mstore(0, 0x42) } uint x; lắp ráp { x := mload(0) } trả về x; } }

Trình biên dịch trong quá trình tối ưu hóa sẽ phân tích luồng điều khiển và luồng dữ liệu để giảm kích thước mã và tối ưu hóa tiêu thụ gas. Tuy nhiên, việc tối ưu hóa này rất dễ phát sinh lỗi.

Trong ví dụ này, trình biên dịch đã sai lầm cho rằng việc ghi vào bộ nhớ 0 trong block assembly đầu tiên là thừa thãi, do đó đã loại bỏ nó, dẫn đến việc hàm f() trả về 0 thay vì 0x42 đúng.

SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup

Lỗ hổng này ảnh hưởng đến các phiên bản biên dịch viên >= 0.5.8 và < 0.8.16.

Xem xét mã sau:

solidity hợp đồng C { function f(string[1] calldata a) public pure returns (string memory) { return abi.decode(abi.encode(a), (string[1]))[0]; } }

Trong trường hợp bình thường, mã này nên trả về giá trị của biến a là "aaaa". Nhưng trong phiên bản có lỗ hổng, nó sẽ trả về chuỗi rỗng "".

Điều này là do Solidity đã xóa sai một số dữ liệu khi thực hiện thao tác abi.encode trên mảng kiểu calldata, dẫn đến việc sửa đổi dữ liệu liền kề, gây ra sự không nhất quán trong dữ liệu sau khi mã hóa và giải mã.

Cần lưu ý rằng khi gọi external và emit event, sẽ xảy ra việc abi.encode ngầm, do đó xác suất xuất hiện lỗ hổng này là khá cao.

Phân tích lỗ hổng trình biên dịch Solidity và biện pháp ứng phó

Đề xuất an toàn

Dành cho các nhà phát triển:

  • Sử dụng phiên bản trình biên dịch Solidity mới hơn, vấn đề bảo mật đã biết thường ít hơn.
  • Hoàn thiện các trường hợp kiểm tra đơn vị, tăng cường tỷ lệ bao phủ mã, giúp phát hiện các vấn đề do trình biên dịch gây ra.
  • Tránh sử dụng lắp ráp nội tuyến, mã hóa và giải mã abi phức tạp, không sử dụng một cách mù quáng các tính năng mới và chức năng thử nghiệm.

Đối với nhân viên an ninh:

  • Trong quá trình kiểm toán, đừng bỏ qua những rủi ro có thể do trình biên dịch gây ra, tương ứng với mục kiểm tra SWC-102.
  • Trong quy trình SDL, thúc đẩy nâng cấp phiên bản trình biên dịch, xem xét việc đưa vào kiểm tra tự động.
  • Đánh giá tác động thực tế của lỗ hổng biên dịch, không cần phải hoảng sợ quá mức.

Một số tài nguyên hữu ích:

  • Blog cảnh báo an toàn chính thức của Solidity
  • Danh sách lỗi trong kho Solidity
  • Danh sách lỗi biên dịch viên các phiên bản
  • Thông báo lỗ hổng trình biên dịch trên trang hợp đồng Etherscan

Phân tích lỗ hổng trình biên dịch Solidity và các biện pháp ứng phó

Tóm lại, lỗ hổng trong trình biên dịch Solidity có thể dẫn đến hành vi thực tế của hợp đồng thông minh không phù hợp với mong đợi, các nhà phát triển và nhân viên an ninh nên cảnh giác với điều này và thực hiện các biện pháp cần thiết để giảm thiểu rủi ro.

ETH-3.02%
SOL-4.98%
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
  • 5
  • Đăng lại
  • Chia sẻ
Bình luận
0/400
ColdWalletGuardianvip
· 08-06 10:09
Còn dám sử dụng trình biên dịch phiên bản cũ à, não sắt?
Xem bản gốcTrả lời0
LayerZeroHerovip
· 08-06 02:28
Trình biên dịch cũng không ổn lắm.
Xem bản gốcTrả lời0
RektRecordervip
· 08-03 12:34
Thật nguy hiểm, quá đi fam
Xem bản gốcTrả lời0
BearMarketGardenervip
· 08-03 12:30
Trình biên dịch cũng đầy lỗi, trong khi ngủ một giấc, tài sản đã biến mất.
Xem bản gốcTrả lời0
SnapshotBotvip
· 08-03 12:27
Biên dịch viên lại gặp sự cố rồi, lén lén đi thôi.
Xem bản gốcTrả lời0
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)