Анализ уязвимостей компилятора Solidity и практические стратегии защиты безопасности смарт-контрактов

Анализ уязвимостей компилятора Solidity и стратегии реагирования

Компилятор является одним из основных компонентов современных компьютерных систем, его задача заключается в преобразовании исходного кода на высокоуровневом языке программирования в исполняемый код для компьютера. Большинство разработчиков и специалистов по безопасности обычно сосредотачиваются на безопасности приложений, но часто игнорируют безопасность самого компилятора. На самом деле, компилятор как программа также может иметь уязвимости, которые в определенных сценариях могут привести к серьезным рискам безопасности.

Например, когда браузер компилирует и выполняет код JavaScript, он может подвергнуться атаке из-за уязвимости движка JavaScript, что может привести к удаленному выполнению кода злоумышленником, когда пользователь посещает вредоносные веб-страницы, в конечном итоге контролируя браузер жертвы или даже операционную систему. Другое исследование также показало, что ошибка компилятора C++ может привести к серьезным последствиям, таким как удаленное выполнение кода.

Компилятор Solidity также имеет уязвимости в безопасности. Согласно предупреждениям о безопасности от команды разработчиков Solidity, несколько версий компилятора Solidity содержат уязвимости. Роль компилятора Solidity заключается в преобразовании кода смарт-контрактов в машинный код команд Ethereum виртуальной машины (EVM), который в конечном итоге будет загружен в Ethereum и выполнен EVM.

Необходимо различать уязвимости компилятора Solidity и уязвимости самой EVM. Уязвимости EVM относятся к проблемам безопасности, возникающим при выполнении инструкций виртуальной машины, которые могут повлиять на всю сеть Ethereum. Уязвимости компилятора Solidity касаются проблем, возникающих при преобразовании Solidity в код EVM, которые не влияют непосредственно на сеть Ethereum, но могут привести к тому, что сгенерированный код EVM будет отличаться от ожиданий разработчика.

Одна из опасностей уязвимости компилятора Solidity заключается в том, что она может привести к тому, что сгенерированный код EVM не будет соответствовать ожиданиям разработчиков смарт-контрактов. Поскольку смарт-контракты обычно связаны с криптовалютными активами пользователей, любая ошибка, вызванная компилятором, может привести к потере активов пользователей и серьезным последствиям.

Разработчики и аудиторы часто сосредотачиваются на логике контрактов и распространенных проблемах безопасности, в то время как уязвимости компилятора трудно обнаружить с помощью аудита кода. Необходимо совместно анализировать конкретную версию компилятора и шаблоны кода, чтобы определить, подвержен ли смарт-контракт уязвимостям компилятора.

Анализ уязвимости компилятора Solidity и меры по ее устранению

Вот несколько примеров реальных уязвимостей компилятора Solidity:

  1. SOL-2016-9 HighOrderByteCleanStorage

Уязвимость существует в более ранних версиях компилятора Solidity (>=0.1.6 <0.4.4). Рассмотрим следующий код:

солидность контракт C { uint32 a = 0x12345678; uint32 b = 0; функция f() публичная { a = a + 1; } функция run() публичный вид возвращает (uint32) { вернуть b; } }

Теоретически переменная b не была изменена, функция run() должна возвращать 0. Однако в коде, сгенерированном уязвимой версией компилятора, run() возвращает 1. Это происходит потому, что EVM использует элементы стека размером 32 байта, в то время как Solidity поддерживает более мелкие типы данных, такие как uint32. Компилятор при обработке должен очищать старшие биты ( clean up ), но при переполнении сложения не обработал это правильно, что привело к записи старшего бита 1 в переменную b.

  1. SOL-2022-4 ВстроеннаяАссемблернаяПамятьПобочныеЭффекты

Уязвимость существует в компиляторах версий с 0.8.13 по 0.8.15. Рассмотрим следующий код:

солидность контракт C { функция f() публичная чистая возвращает (uint) { сборка { mstore(0, 0x42) } uint x; сборка { x := mload(0) } вернуть x; } }

Компилятор для оптимизации удаляет, казалось бы, бесполезные операции записи в память, но ошибочно также оптимизирует доступ к памяти, пересекающий блоки сборки. Это приводит к тому, что функция f() возвращает 0 вместо правильного 0x42.

  1. SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup

Уязвимость затрагивает версии компилятора от 0.5.8 до 0.8.16. Рассмотрим следующий код:

солидность контракт C { function f(string[1] calldata a) внешних чистых возвращает (string memory) { вернуть abi.decode(abi.encode(a), (строка[1]))[0]; } }

В нормальных условиях эта функция должна возвращать входную строку. Однако в уязвимой версии она возвращает пустую строку. Это связано с тем, что компилятор неправильно очистил некоторые данные при ABI-кодировании массива calldata, что привело к несоответствию закодированных и декодированных данных.

Анализ уязвимостей компилятора Solidity и меры противодействия

В связи с уязвимостями компилятора Solidity, команда безопасности блокчейна Cobo предлагает следующие рекомендации:

Для разработчиков:

  1. Используйте более новую версию компилятора Solidity, в которой обычно меньше известных проблем с безопасностью.

  2. Улучшите тестовые случаи модулей. Большинство ошибок на уровне компилятора приводят к тому, что результаты выполнения кода не соответствуют ожиданиям; повышение покрытия тестами может помочь избежать подобных проблем.

  3. Избегайте использования встроенного ассемблера, сложной компиляции и декодирования ABI и других операций, не используйте слепо новые функции и экспериментальные возможности. Большинство уязвимостей компилятора связано с этими сложными операциями.

К службе безопасности:

  1. Не игнорируйте потенциальные риски безопасности, связанные с компилятором, во время аудита. Соответствующий пункт проверки: SWC-102: Устаревшая версия компилятора.

  2. В процессе разработки необходимо побуждать команду разработчиков обновлять версию компилятора, можно внедрить автоматическую проверку версии в CI/CD.

  3. Не нужно чрезмерно беспокоиться о уязвимостях компилятора. Большинство уязвимостей срабатывают только в определённых кодовых паттернах, необходимо оценить влияние на безопасность в зависимости от конкретного проекта.

Некоторые полезные ресурсы:

  • Официальное предупреждение о безопасности Solidity:
  • Официальный список ошибок Solidity:
  • Список ошибок компилятора для всех версий:
  • В правом верхнем углу страницы контракта Etherscan значок предупреждения может указывать на существующие уязвимости в текущей версии компилятора.

Анализ уязвимостей компилятора Solidity и меры реагирования

В целом, разработчики и специалисты по безопасности должны обратить внимание на потенциальные риски безопасности, связанные с уязвимостями компилятора Solidity, и принять соответствующие меры для снижения рисков, чтобы обеспечить безопасность смарт-контрактов.

Посмотреть Оригинал
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.
  • Награда
  • 6
  • Поделиться
комментарий
0/400
MetaverseLandlordvip
· 07-12 19:10
С компилятором что-то не так
Посмотреть ОригиналОтветить0
NFTHoardervip
· 07-12 03:00
Компилятор тоже может ошибаться.
Посмотреть ОригиналОтветить0
0xOverleveragedvip
· 07-10 21:09
Компилятор — это предок.
Посмотреть ОригиналОтветить0
TestnetNomadvip
· 07-10 21:08
Класс по компиляторам очень хороший
Посмотреть ОригиналОтветить0
ParallelChainMaxivip
· 07-10 21:06
Безопасность компилятора не должна игнорироваться
Посмотреть ОригиналОтветить0
DegenApeSurfervip
· 07-10 20:55
Безопасность контрактов действительно непростая задача
Посмотреть ОригиналОтветить0
  • Закрепить