Уязвимость: Reentrancy
Первый тип уязвимости, который мы разберем, на русский можно перевести как повторный вход
Схема взлома надежна как швейцарские часы, если я всё правильно понял
Допустим, в вашем контракте есть функция, которая позволяет пользователю выводить средства. В этой функции сначала происходит вывод средств, а следующей строкой изменяется счетчик баланса пользователя.
В целом, если функция вызывается просто с кошелька, то проблем нет, все работает как надо. А вот если взаимодействие с контрактом идет от другого контракта, то появляется простор для махинаций.
Дело в том, что вместо просто принятия денег на счет, в функцию, которая за это отвечает на стороне пользователя, можно встроить повторный вызов вывода средств. Таким образом, строка, отвечающая за изменение сведений о балансе, не успевает отработать до повторного вызова и контракт-жертва снова отправляет средства на атакующий контракт.
То есть код устроен так:
- проверили сумму запроса
- отправили средства
- изменили сведения о балансе
Продолжаться это может до полного дрейна жертвы.
Как противостоять
1. Использовать принцип CEI - Check Effect Interactions:
- проверили сумму запроса
- изменили инфу о балансе пользователя
- отправили средства пользователю
2. У OpenZeppelin существует ReentrancyGuard класс, от которого можно наследоваться и вешать модификатор nonReentrant() на чувствительные функции
Ущерб
Казалось бы, такая простая ошибка, так легко исправляется и детектится даже статическими анализаторами кода, но такие взломы происходят до сих пор, а в 2024 таким образом было похищено $35.7M. На текущий момент уязвимость стоит на 5 месте рейтинга OWASP
Что почитать
Есть хороший материал у QuickNode с подробным объяснением и примерами кода
Схема к посту взята отсюда
Post #10
179

- ❤ 1