Phân tích lỗ hổng trình biên dịch Solidity và chiến lược ứ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, chịu trách nhiệm chuyển đổi ngôn ngữ lập trình cấp cao thành các lệnh thực thi cấp thấp. Mặc dù các nhà phát triển thường chú ý đến độ an toàn của mã ứng dụng, nhưng tính an toàn của chính trình biên dịch cũng quan trọng không kém. Lỗ hổng trong trình biên dịch trong một số trường hợp cũng có thể gây ra rủi ro an ninh nghiêm trọng, chẳng hạn như lỗ hổng trong engine JavaScript của trình duyệt có thể dẫn đến việc thực thi mã từ xa.
Trình biên dịch Solidity cũng không phải là ngoại lệ, tồn tại nhiều phiên bản với các lỗ hổng bảo mật. Khác với lỗ hổng EVM, lỗ hổng trình biên dịch Solidity chỉ ảnh hưởng đến các nhà phát triển hợp đồng, không trực tiếp đe dọa đến an ninh mạng Ethereum. Tuy nhiên, nó có thể dẫn đến mã EVM được tạo ra không đúng như mong đợi của nhà phát triển, từ đó gây ra lỗ hổng hợp đồng thông minh, đe dọa đến an toàn tài sản của người dùng.
Dưới đây là một số ví dụ thực tế về lỗ hổng biên dịch viên Solidity:
SOL-2016-9 HighOrderByteCleanStorage
Ảnh hưởng phiên bản: >=0.1.6 <0.4.4
Lỗ hổng này có thể dẫn đến việc biến storage bị sửa đổi một cách không mong muốn. Ví dụ:
solid
hợp đồng C {
uint32 a = 0x1234;
uint32 b = 0;
function run() returns (uint) {
a += 1;
return b;
}
}
hàm run() nên trả về 0, nhưng thực tế lại trả về 1. Điều này xảy ra vì trình biên dịch không làm sạch đúng cách các bit cao khi xử lý tràn số nguyên, dẫn đến việc bit tràn ghi vào biến liền kề.
SOL-2022-4 Tác Động Bên Cạnh Bộ Nhớ InlineAssembly
Ảnh hưởng phiên bản: >=0.8.13 <0.8.15
Lỗ hổng này xuất phát từ quá trình tối ưu hóa biên dịch. Ví dụ:
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)
}
return x;
}
}
Hàm f() nên trả về 0x42, nhưng phiên bản có lỗ hổng sẽ trả về 0. Điều này là do trình biên dịch đã xóa sai thao tác ghi bộ nhớ trong khối assembly đầu tiên.
Lỗ hổng này liên quan đến mã hóa ABI của mảng calldata. Ví dụ:
solidity
hợp đồng C {
function f(bytes[1] calldata a) public pure returns (bytes memory) {
return abi.encode(a);
}
}
Hàm f() nên trả về mảng đầu vào, nhưng phiên bản có lỗ hổng sẽ trả về chuỗi rỗng. Điều này là do trình biên dịch đã làm sạch sai dữ liệu lân cận trong quá trình mã hóa.
Để giảm thiểu rủi ro lỗ hổng trình biên dịch Solidity, các nhà phát triển nên:
Sử dụng phiên bản biên dịch viên mới hơn
Hoàn thiện kiểm tra đơn vị, nâng cao tỷ lệ bao phủ mã
Tránh sử dụng các đặc điểm ngôn ngữ phức tạp, chẳng hạn như lắp ghép nội tuyến, mã hóa ABI mảng đa chiều, v.v.
Nhân viên kiểm toán an toàn nên:
Xem xét rủi ro tiềm ẩn của trình biên dịch trong quá trình kiểm toán
Khuyên đội ngũ phát triển nâng cấp phiên bản biên dịch kịp thời.
Thêm kiểm tra tự động phiên bản biên dịch viên vào quy trình CI/CD
Tài nguyên tham khảo 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 GitHub Solidity
Thông báo lỗi trình biên dịch trên trang hợp đồng Etherscan
Tóm lại, mặc dù lỗ hổng biên dịch không phổ biến, nhưng ảnh hưởng có thể nghiêm trọng. Các nhà phát triển và nhân viên an ninh nên nâng cao cảnh giác và thực hiện các biện pháp phù hợp để giảm thiểu rủi ro.
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
8 thích
Phần thưởng
8
5
Chia sẻ
Bình luận
0/400
blockBoy
· 7giờ trước
Lại thấy lỗ hổng hợp đồng, thật phiền phức~
Xem bản gốcTrả lời0
GasGuzzler
· 07-07 09:10
Lại là trình biên dịch gây rối
Xem bản gốcTrả lời0
GweiTooHigh
· 07-07 09:05
Làm cái quái gì vậy, lại có lỗi nữa à?
Xem bản gốcTrả lời0
RektRecovery
· 07-07 09:00
*thở dài* lại một lỗ hổng dễ đoán khác... khi nào các nhà phát triển mới học được cách ngừng chơi với lửa
Phân tích lỗ hổng biên dịch viên Solidity: Rủi ro an ninh và chiến lược ứng phó
Phân tích lỗ hổng trình biên dịch Solidity và chiến lược ứ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, chịu trách nhiệm chuyển đổi ngôn ngữ lập trình cấp cao thành các lệnh thực thi cấp thấp. Mặc dù các nhà phát triển thường chú ý đến độ an toàn của mã ứng dụng, nhưng tính an toàn của chính trình biên dịch cũng quan trọng không kém. Lỗ hổng trong trình biên dịch trong một số trường hợp cũng có thể gây ra rủi ro an ninh nghiêm trọng, chẳng hạn như lỗ hổng trong engine JavaScript của trình duyệt có thể dẫn đến việc thực thi mã từ xa.
Trình biên dịch Solidity cũng không phải là ngoại lệ, tồn tại nhiều phiên bản với các lỗ hổng bảo mật. Khác với lỗ hổng EVM, lỗ hổng trình biên dịch Solidity chỉ ảnh hưởng đến các nhà phát triển hợp đồng, không trực tiếp đe dọa đến an ninh mạng Ethereum. Tuy nhiên, nó có thể dẫn đến mã EVM được tạo ra không đúng như mong đợi của nhà phát triển, từ đó gây ra lỗ hổng hợp đồng thông minh, đe dọa đến an toàn tài sản của người dùng.
Dưới đây là một số ví dụ thực tế về lỗ hổng biên dịch viên Solidity:
Ảnh hưởng phiên bản: >=0.1.6 <0.4.4
Lỗ hổng này có thể dẫn đến việc biến storage bị sửa đổi một cách không mong muốn. Ví dụ:
solid hợp đồng C { uint32 a = 0x1234; uint32 b = 0; function run() returns (uint) { a += 1; return b; } }
hàm run() nên trả về 0, nhưng thực tế lại trả về 1. Điều này xảy ra vì trình biên dịch không làm sạch đúng cách các bit cao khi xử lý tràn số nguyên, dẫn đến việc bit tràn ghi vào biến liền kề.
Ảnh hưởng phiên bản: >=0.8.13 <0.8.15
Lỗ hổng này xuất phát từ quá trình tối ưu hóa biên dịch. Ví dụ:
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) } return x; } }
Hàm f() nên trả về 0x42, nhưng phiên bản có lỗ hổng sẽ trả về 0. Điều này là do trình biên dịch đã xóa sai thao tác ghi bộ nhớ trong khối assembly đầu tiên.
Ảnh hưởng phiên bản: >= 0.5.8 < 0.8.16
Lỗ hổng này liên quan đến mã hóa ABI của mảng calldata. Ví dụ:
solidity hợp đồng C { function f(bytes[1] calldata a) public pure returns (bytes memory) { return abi.encode(a); } }
Hàm f() nên trả về mảng đầu vào, nhưng phiên bản có lỗ hổng sẽ trả về chuỗi rỗng. Điều này là do trình biên dịch đã làm sạch sai dữ liệu lân cận trong quá trình mã hóa.
Để giảm thiểu rủi ro lỗ hổng trình biên dịch Solidity, các nhà phát triển nên:
Nhân viên kiểm toán an toàn nên:
Tài nguyên tham khảo hữu ích:
Tóm lại, mặc dù lỗ hổng biên dịch không phổ biến, nhưng ảnh hưởng có thể nghiêm trọng. Các nhà phát triển và nhân viên an ninh nên nâng cao cảnh giác và thực hiện các biện pháp phù hợp để giảm thiểu rủi ro.