Що таке Reentrancy Attack?
Reentrancy Attack виникає, коли контракт передає контроль іншому контракту під час виклику, а зовнішній код повертається в перший контракт до того, як він встиг оновити свої записи. Така маніпуляція з часом дозволяє нападнику багаторазово виконувати чутливі операції, наприклад зняття коштів. Уявіть, що ви просите повернути гроші, але встигаєте повернутися до каси до того, як касир зафіксує операцію.
«Лише старий код може постраждати від Reentrancy Attack.» Це не так. Будь-який контракт, який виконує зовнішній виклик до того, як зафіксує власний стан, може бути вразливим, якщо логіка написана недбало.
Як працює Reentrancy Attack
Коротко. Типовий розумний контракт має функцію withdraw, яка надсилає кошти тому, хто викликав. Якщо спочатку відправляються кошти, а баланс очищається пізніше, нападник може втрутитися через зворотний виклик і запросити більше до того, як баланс буде обнулено.
- Початок: Нападник вносить деякі кошти, щоб виглядати правдоподібно.
- Виклик: Нападник запускає withdraw у цільовому контракті.
- Fallback: Цільовий контракт відправляє кошти, що запускає fallback у коді нападника.
- Повтор: Цей fallback знову викликає withdraw до того, як баланс буде оновлено.
- Виснаження: Цикл триває, доки в контракті не закінчаться кошти або газ. Так працює трюк.
Одна невелика помилка в порядку операцій, велика проблема.
Чому Reentrancy Attack має значення
Це важливо, бо помилки в часових моментах призводять до втрат реальних грошей дуже швидко. До того ж це класичний експлойт, який кожен розробник і зацікавлений користувач має вміти впізнати зразу.
- Перевага: Знання цього шаблону допомагає помічати ризиковий код і захищати кошти.
- Погляд: Він використовує публічну прозорість, адже все в блокчейні видно і доступно для виклику.
- Застосування: Ви зустрінете його в DeFi, мостах, скарбницях і навіть у виплатах для DAO.
Дотримуйтеся принципу спочатку перевірки, потім змін стану, потім взаємодії. Оновлюйте баланси першими, потім робіть зовнішні виклики. Додайте простий механізм захисту від Reentrancy Attack для додаткового захисту.
Ключові характеристики Reentrancy Attack
Ось що робить його ефективним:
- Рекурсія: Зовнішній код повертається в той самий контракт до завершення його операцій.
- Порядок: Помилка виникає, коли відправлення коштів або зовнішній виклик відбувається перед оновленням стану.
- Міжконтрактність: Це може відбуватися між кількома контрактами, а не тільки в одній функції.
- Активи: Працює з ETH, токенами і навіть з бухгалтерськими кредитами, якщо код написаний ненадійно.
Варіанти
Різні варіанти, одна й та сама проблема для недбало написаного коду:
- Single: Повторне входження в ту саму функцію кілька разів.
- Cross: Повторне входження через іншу функцію в тому ж контракті.
- Multi: Повторні входи через два або більше контрактів у циклі.
- ReadOnly: Маніпуляція запитами для читання або оракулами цін, щоб ввести в оману подальші записування.
Виправлення Reentrancy Attack не обмежується однією функцією. Перевіряйте кожен зовнішній виклик, додавайте тести для незвичних ланцюжків викликів і плануйте регулярні аудити.
Приклад
У 2016 році експлойт The DAO використовував цикл повторного входження при виклику withdraw до очищення балансів, що дозволило за кілька хвилин спорожнити велику скарбницю.
Цікавинка
Фраза "спочатку перевірки, потім зміни стану, потім взаємодії" зявилася в ранніх керівництвах з безпеки і прижилася, бо вона коротка, запамятовується і дієва.
Підсумок
Коротко, щоб запамятати: якщо зовнішній код може викликати вас до того, як ви закінчите власну бухгалтерію, вважайте, що він так зробить, і ви можете віддати йому гроші просто так. Це і є Reentrancy Attack.
