Анализ уязвимостей компилятора Solidity и стратегии противодействия
Компилятор является одной из основных компонентов современных компьютерных систем, отвечающим за преобразование языков высокого уровня в низкоуровневые исполняемые инструкции. Хотя разработчики обычно сосредотачиваются на безопасности прикладного кода, безопасность самого компилятора также важна. Уязвимости компилятора в некоторых случаях могут привести к серьезным рискам безопасности, например, уязвимости JavaScript-движка браузера могут привести к удаленному выполнению кода.
Компилятор Solidity не является исключением; в нем существует несколько версий уязвимостей. В отличие от уязвимостей EVM, уязвимости компилятора Solidity затрагивают только разработчиков контрактов и не угрожают напрямую безопасности сети Ethereum. Однако это может привести к тому, что сгенерированный код EVM не будет соответствовать ожиданиям разработчика, что может вызвать уязвимости смарт-контрактов и поставить под угрозу безопасность активов пользователей.
Вот несколько примеров реальных уязвимостей компилятора Solidity:
SOL-2016-9 HighOrderByteCleanStorage
Влияние версии: >=0.1.6 <0.4.4
Этот уязвимость может привести к неожиданному изменению переменной storage. Например:
солидность
контракт C {
uint32 a = 0x1234;
uint32 b = 0;
функция run() возвращает (uint) {
a += 1;
вернуть b;
}
}
функция run() должна возвращать 0, но на самом деле возвращает 1. Это происходит потому, что компилятор неправильно очищает старшие биты при обработке переполнения целого числа, в результате чего бит переполнения записывается в соседнюю переменную.
Уязвимость возникает в процессе оптимизации компиляции. Например:
солидность
контракт C {
функция f() публичный чистый возвращает (uint) {
сборка {
mstore(0, 0x42)
}
uint x;
сборка {
x := mload(0)
}
вернуть x;
}
}
ф() функция должна возвращать 0x42, но версия с уязвимостью вернет 0. Это связано с тем, что компилятор ошибочно убрал операцию записи в память из первого блока assembly.
Уязвимость связана с ABI-кодированием массива calldata. Например:
солидность
контракт C {
function f(bytes[1] calldata a) public pure возвращает (bytes memory) {
возврат abi.encode(a);
}
}
f() Функция должна возвращать входной массив, но у уязвимой версии она возвращает пустую строку. Это связано с тем, что компилятор неправильно очистил соседние данные в процессе кодирования.
Чтобы снизить риск уязвимостей компилятора Solidity, разработчики должны:
Используйте более новую версию компилятора
Улучшение модульного тестирования, повышение покрытия кода
Избегайте использования сложных языковых особенностей, таких как встроенная ассемблерная кодировка, многомерное массивное ABI и т.д.
Специалисты по безопасности должны:
Учитывайте потенциальные риски компилятора в процессе аудита
Рекомендуется команде разработчиков своевременно обновлять версию компилятора
В процессе CI/CD добавить автоматическую проверку версии компилятора
Полезные справочные ресурсы:
Официальный блог о безопасности Solidity
Список ошибок в репозитории Solidity на GitHub
Уведомление о уязвимости компилятора на странице контракта Etherscan
В общем, уязвимости компилятора хоть и встречаются не часто, но последствия могут быть серьезными. Разработчики и специалисты по безопасности должны быть внимательными и принимать соответствующие меры для снижения рисков.
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 Лайков
Награда
8
5
Поделиться
комментарий
0/400
blockBoy
· 7ч назад
Снова нашли уязвимость в контракте, так раздражает~
Посмотреть ОригиналОтветить0
GasGuzzler
· 07-07 09:10
Снова компилятор делает свои дела
Посмотреть ОригиналОтветить0
GweiTooHigh
· 07-07 09:05
Какого черта, снова появились уязвимости?
Посмотреть ОригиналОтветить0
RektRecovery
· 07-07 09:00
*вздох* еще одна предсказуемая уязвимость... когда же разработчики научатся не играть с огнем
Анализ уязвимостей компилятора Solidity: риски безопасности и стратегии реагирования
Анализ уязвимостей компилятора Solidity и стратегии противодействия
Компилятор является одной из основных компонентов современных компьютерных систем, отвечающим за преобразование языков высокого уровня в низкоуровневые исполняемые инструкции. Хотя разработчики обычно сосредотачиваются на безопасности прикладного кода, безопасность самого компилятора также важна. Уязвимости компилятора в некоторых случаях могут привести к серьезным рискам безопасности, например, уязвимости JavaScript-движка браузера могут привести к удаленному выполнению кода.
Компилятор Solidity не является исключением; в нем существует несколько версий уязвимостей. В отличие от уязвимостей EVM, уязвимости компилятора Solidity затрагивают только разработчиков контрактов и не угрожают напрямую безопасности сети Ethereum. Однако это может привести к тому, что сгенерированный код EVM не будет соответствовать ожиданиям разработчика, что может вызвать уязвимости смарт-контрактов и поставить под угрозу безопасность активов пользователей.
Вот несколько примеров реальных уязвимостей компилятора Solidity:
Влияние версии: >=0.1.6 <0.4.4
Этот уязвимость может привести к неожиданному изменению переменной storage. Например:
солидность контракт C { uint32 a = 0x1234; uint32 b = 0; функция run() возвращает (uint) { a += 1; вернуть b; } }
функция run() должна возвращать 0, но на самом деле возвращает 1. Это происходит потому, что компилятор неправильно очищает старшие биты при обработке переполнения целого числа, в результате чего бит переполнения записывается в соседнюю переменную.
Влияние версии: >=0.8.13 <0.8.15
Уязвимость возникает в процессе оптимизации компиляции. Например:
солидность контракт C { функция f() публичный чистый возвращает (uint) { сборка { mstore(0, 0x42) } uint x; сборка { x := mload(0) } вернуть x; } }
ф() функция должна возвращать 0x42, но версия с уязвимостью вернет 0. Это связано с тем, что компилятор ошибочно убрал операцию записи в память из первого блока assembly.
Версия воздействия: >= 0.5.8 < 0.8.16
Уязвимость связана с ABI-кодированием массива calldata. Например:
солидность контракт C { function f(bytes[1] calldata a) public pure возвращает (bytes memory) { возврат abi.encode(a); } }
f() Функция должна возвращать входной массив, но у уязвимой версии она возвращает пустую строку. Это связано с тем, что компилятор неправильно очистил соседние данные в процессе кодирования.
Чтобы снизить риск уязвимостей компилятора Solidity, разработчики должны:
Специалисты по безопасности должны:
Полезные справочные ресурсы:
В общем, уязвимости компилятора хоть и встречаются не часто, но последствия могут быть серьезными. Разработчики и специалисты по безопасности должны быть внимательными и принимать соответствующие меры для снижения рисков.