Личный кабинет
Международные стандарты1 февраля

Аналитический обзор списка OWASP Smart Contract Top 10

УязвимостиOWASP

npikhovkin.jpgНиколай Пиховкин

Сообщество OWASP (Open Worldwide Application Security Project) опубликовало список Smart Contract Top 10, который предоставляет разработчикам в области Web3 и экспертам по информационной безопасности подробное описание 10 самых распространенных уязвимостей смарт-контрактов.

Смарт-контракты представляют собой программный код, который автоматизирует проверку и выполнение контрактных условий в блокчейне, тем самым исключая необходимость использования посредников. Они обеспечивают прозрачность, эффективность и надежность цифровых сделок, однако, как и обычные программы, могут содержать уязвимости и создавать риски для информационной безопасности.

В этом аналитическом обзоре мы представим адаптированную русскоязычную версию списка OWASP Smart Contract Top 10 с комментариями, рекомендациями и простыми примерами.

Повторный вход (Reentrancy Attacks)

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

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

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

Рекомендации по устранению:

  • придерживайтесь использования модели Checks-Effects-Interactions (чтобы убедиться, что все внутренние изменения состояния выполнены до передачи потока управления);
  • используйте механизмы защиты типа mutex, обеспечивающие взаимное исключение исполнения важных участков кода;
  • регулярно обновляйте Solidity до актуальных версий.

Целочисленное переполнение/антипереполнение (Integer Overflow and Underflow)

Уязвимости этого типа возникают тогда, когда значение целого числа (int) в смарт-контракте превышает максимально или минимально допустимые пределы. Это может привести к несанкционированному изменению логики работы контракта, потере активов и другому ущербу.

Недобросовестный автовладелец не хочет продавать старенький автомобиль всего за 15 тысяч рублей только потому, что пробег на шестизначном одометре его ласточки равен 999 999 км. Он может воспользоваться уязвимостью «Целочисленное переполнение» — проехать еще один километр, получить пробег в 000 000 км (напоминаем, что там не предусмотрена седьмая цифра) и продать ее в разы дороже.

Рекомендации по устранению:

  • используйте библиотеки (например, SafeMath), которые содержат функции для проведения безопасных арифметических операций;

  • используйте Solidity версии 0.8.0 и выше, в котором есть встроенная защита от этой уязвимости.

Зависимость от временной метки (Timestamp Dependence)

Уязвимость возникает, когда у хакеров есть возможность манипулировать временными метками, которые могут использоваться при реализации важных функций смарт-контрактов (генерации псевдослучайных чисел, блокировки активов на определенный промежуток времени и других функций, зависящих от времени), и таким образом влиять на логику работы смарт-контракта.

Хитрый сотрудник турфирмы заработался и не успел купить горящий тур в Дубай, который продавался во внутренней системе бронирования со скидкой 50% до конца рабочего дня. Он может использовать уязвимость «Зависимость от временной метки» и, отмотав системное время назад, все-таки совершить выгодную покупку.

Рекомендации по устранению:

  • не используйте свойства block.timestamp или now при реализации ключевых функций смарт-контракта;

  • если нужно отслеживать время, рассмотрите возможность использования свойства block.number.

Уязвимости контроля доступа (Access Control Vulnerabilities)

Уязвимости этого типа возникают в случае неправильной реализации ограничений, касающихся того, кто и как может взаимодействовать с определенными функциями смарт-контракта. К этой категории уязвимостей относится небезопасное управление правами пользователей, а также ошибки в логике проверки прав. Злоумышленник может использовать такую уязвимость для выполнения несанкционированных действий (например, для вызова функций) при проведении дальнейших атак.

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

Рекомендации по устранению:

  • используйте в смарт-контракте механизмы Ownable или RBAC;

  • проводите регулярный аудит исходного кода смарт-контракта для поиска уязвимостей контроля доступа.

Фронтраннинг (Front-running Attacks)

Такие атаки происходят, когда злоумышленник, имеющий доступ к информации об ожидающих исполнения транзакциях, размещает ордер, который принесет ему прибыль от взаимодействия с такой транзакцией. Это позволяет злоумышленнику перехватывать и изменять транзакции, что может привести к финансовому ущербу. Проведение таких атак возможно в публичных блокчейн-сетях, где данные о транзакциях хранятся в открытом доступе.

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

Рекомендации по устранению:

  • используйте схемы commit-reveal, которые скрывают фактические детали транзакции до ее обработки;

  • используйте механизм пакетных аукционов (batch auctions), который менее подвержен фронтраннингу, поскольку не зависит от порядка транзакций;

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

Отказ в обслуживании (Denial of Service Attacks)

В контексте смарт-контрактов такие атаки происходят, когда злоумышленник вызывает сбой в работе контракта и таким образом делает невозможным его нормальное использование. Также отказ в обслуживании в смарт-контрактах может происходить из-за ошибок в исходном коде или недостатков в логике работы контракта. Злоумышленник может этим воспользоваться, нарушить штатное функционирование контракта и нанести репутационный или финансовый ущерб.

Если в смарт-контракте есть функции, требующие больших вычислительных мощностей (например, циклы для подсчета количества ваших лайков в телеграм-канале «Резбез», злоумышленник может вызвать их, чтобы израсходовать весь газ и заблокировать контракт.

Рекомендации по устранению:

  • используйте функцию call вместо функций send и transfer;

  • ограничьте количество действий, которые могут быть выполнены в рамках одной транзакции;

  • внедрите механизм pull-платежей для возврата или вывода активов, который разделяет процесс начисления и вывода средств на две отдельные транзакции.

Логические ошибки (Logic Errors)

Логические ошибки возникают из-за выполнения неправильных/непредусмотренных действий в отношении смарт-контракта. Они могут привести к некорректной обработке транзакций, неправильному распределению токенов и в итоге к финансовому ущербу.

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

Рекомендации по устранению:

  • используйте инструменты автоматизированного тестирования, чтобы охватить как можно большее количество способов использования смарт-контракта;

  • проводите регулярный аудит исходного кода смарт-контракта для поиска логических ошибок;

  • документируйте предполагаемое поведение каждой функции и модуля, после чего сравнивайте его с фактической реализацией.

Небезопасная генерация случайности (Insecure Randomness)

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

Ваш начальник написал смарт-контракт лотереи для розыгрыша премии. В качестве источника случайности используется номер текущего блока. Хитрый сотрудник может проанализировать блокчейн и угадать «случайное» число, чтобы повысить свои шансы на выигрыш.

Рекомендации по устранению:

  • используйте схемы commit-reveal, в которых пользователи отправляют хешированные значения и раскрывают их позже;

  • используйте внешние оракул-сервисы.

Уязвимости, связанные с лимитом газа (Gas Limit Vulnerabilities)

Уязвимости этого типа возникают, когда для выполнения функции требуется больше ресурсов, чем предусмотрено в блоке. Эксплуатация этой уязвимости может привести к неполному выполнению функций смарт-контракта, что приведет к блокировке активов и заморозке состояния контракта.

Смарт-контракт, который управляет выплатой зарплаты, предполагает выполнение серии операций: расчет суммы к выплате, отправка сотруднику расчетного листа и сам перевод средств. Если для выполнения всех этих операций установлен недостаточный лимит газа, то транзакция не сможет успешно завершиться. Например, расчет суммы к выплате и отправка расчетного листа пройдут успешно, но на стадии перевода средств газ закончится и транзакция отменится, оставив сотрудника голодным.

Рекомендации по устранению:

  • не используйте циклы, которые итерируются по динамическим структурам данных;

  • используйте код, эффективно расходующий газ, и внедряйте тестовые функции с большим объемом входных данных, чтобы убедиться, что они не превысят лимит газа для блока;

  • разбивайте сложные вычисления на несколько транзакций.

Непроверенные возвращаемые значения внешних вызовов (Unchecked External Calls)

Такие уязвимости возникают, когда смарт-контракт вызывает другой контракт, но не проверяет результат этого вызова (вызванный контракт может завершиться с ошибкой). Это может привести к нарушению логики работы смарт-контракта, ошибкам при проведении транзакций и потере активов.

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

Рекомендации по устранению:

  • всегда проверяйте возвращаемые значения функций call, delegatecall и callcode;

  • используйте в Solidity функции transfer или send вместо call.value()().

Заключение

Применение OWASP Smart Contract Top 10 способствует формированию лучших практик в сфере разработки блокчейн-проектов, что, в свою очередь, повышает доверие пользователей и инвесторов к современным технологиям. Благодаря этому открываются новые возможности для использования таких технологий в различных отраслях экономики, что способствует инновациям и цифровой трансформации.