Автор: imToken
Бот MEV, который долгое время охотился на обычных трейдеров в Ethereum, в итоге сам попал в ловушку стоимостью 7,5 млн долларов.
21 июня атаковали известного сэндвич-арбитражного бота на Ethereum Jaredfromsubway.eth, с адреса которого были выведены активы WETH, USDC и другие. По предварительным оценкам, убытки превысили 7,5 млн долларов (хотя публично озвученные цифры потерь все еще разнятся).
Что интересно, эта атака не была связана с утечкой приватного ключа и не использовала традиционные уязвимости смарт-контрактов. Вместо этого,атакующий заранее развернул множество поддельных токенов, пулов ликвидности и вспомогательных контрактов, оформив их как потенциально прибыльный торговый путь, и заставил бота в процессе автоматического исполнения выдать контракту-злоумышленнику Approval на стандарт ERC-20. В итоге средства MEV-бота были «законно» выведены.
На момент публикации Jaredfromsubway.eth через ончейн-сообщение уже публично обратился к атакующему, заявив, что «в случае возврата 2150 ETH в течение 48 часов готов заплатить 50% в качестве награды white-hat хакеру, в противном случае будут предприняты все возможные правовые и правоохранительные меры».
Однако тот факт, что даже высокопрофессиональный бот MEV, управляемый кодом, попался на Approval, заставляет нас задуматься: насколько опасным на самом деле является это действие «Approval», которое мы используем каждый день?
1. Специально спроектированная охота на MEV-бота
Если внимательно проанализировать эту атаку, становится ясно, что это не случайно сработавшая уязвимость, а долгосрочная охота, построенная на логике работы Jaredfromsubway.eth.
Jaredfromsubway.eth всегда был одним из самых известных сэндвич-арбитражных ботов в Ethereum. Проще говоря, при сэндвич-атаке бот, обнаружив предстоящую транзакцию в блокчейне, покупает актив до пользователя, вызывая рост цены; после того, как пользователь совершает сделку по худшей цене, бот сразу же продает, зарабатывая на разнице.
Именно поэтому данная стратегия требует от бота постоянного сканирования ончейн-транзакций, сверхбыстрой оценки арбитражных возможностей и построения торговых путей с вызовом различных токенов и контрактов. Это также означает, что чем выше скорость и чем больше активов и протоколов покрыто, тем больше возможностей может захватить бот.
Но именно это и стало точкой прорыва в данном случае.
Согласно постфактум анализу, атакующий не атаковал напрямую контракт с фондами бота, а потратил несколько недель на создание среды, которая выглядела бы прибыльной для торговли:
- Первый шаг — развертывание множества поддельных токенов и пулов ликвидности. Эти токены по названию, интерфейсу и поведению при торговле имитировали WETH, USDC, USDT и другие распространенные активы, заставляя автоматическую систему распознавания бота ошибочно думать, что она нашла нормальный торговый путь.
- Второй шаг — постепенное завоевание доверия бота. В ранних тестах выданные ботом авторизации (approvals) нормально расходовались по мере совершения транзакций. Когда система бота начала повторно исполнять аналогичные пути, атакующий изменил логику контракта, так что часть выдаваемых ботом авторизаций перестала фактически расходоваться и не обнулялась после завершения транзакции. В результате эти авторизации остались активными.
- Наконец, атакующий сконцентрированно использовал все еще действующие лимиты авторизаций и вывел настоящие WETH, USDC и USDT из контракта бота.
Проще говоря, вся атака была полностью нацелена на особенности работы MEV-бота: сначала создать среду, соответствующую его правилам оценки прибыльности, а затем использовать его механизм автоматического исполнения торговых путей, заставив систему добровольно отдать право управления активами.
Это также объясняет, почему даже высокопрофессиональный MEV-бот попался.
Он умеет рассчитывать спреды, стоимость газа и порядок транзакций, но не обязательно проводит достаточную проверку личности каждого нового контракта. С этой точки зрения,проблема обычного пользователя в том, что он «нажимает подтверждение, не поняв», а проблема автоматизированного бота — в том, что он «автоматически исполняет, не подтверждая».
На первый взгляд, они совершенно разные, но лежащий в основе риск схож: оба воспринимают выдачу авторизации как обычный шаг перед совершением сделки, не осознавая в полной мере, насколько высок скрытый в ней риск.
2. Почему Approval всегда недооценивают?
Как известно, в стандарте ERC-20 Ethereum и совместимых с EVM блокчейнах Approve (авторизация) — это довольно базовый механизм.
Однако, когда пользователи переводят средства напрямую из кошелька, они обычно используют transfer, и Approve обычно не требуется. Авторизация возникает только в сценариях работы со смарт-контрактами, таких как DEX, кредитование, стейкинг или добавление ликвидности, когда пользователю нужно разрешить смарт-контракту управлять его токенами.
Например, когда мы хотим обменять USDT на ETH на Uniswap, смарт-контракт Uniswap не может просто забрать USDT из вашего кошелька. Сначала необходимо выполнить Approve, чтобы сказать системе: «Я разрешаю Uniswap списать X USDT с моего кошелька».
Только после завершения авторизации получивший разрешение контракт сможет через transferFrom использовать USDT пользователя в пределах установленного лимита, и последующий обмен (Swap) сможет завершиться успешно.
Другими словами, сам Approval — это не уязвимость, а важная основа для нормальной работы DeFi. Однако проблема в том, что он немного похож на разрешение на автоматическое списание в Alipay/WeChat:
Пользователь не передает продавцу пароль от учетной записи, но разрешает продавцу в оговоренных пределах активно списывать средства. Пока авторизация действительна, для последующих списаний пользователю не нужно снова вводить пароль или подтверждать каждую операцию. Это создает естественные проблемы.
Во-первых, проблема неограниченной авторизации (Infinite Approval): люди часто превращают разрешение на одну транзакцию в долгосрочное право. В основном для сокращения операционных издержек и стоимости газа, связанных с повторными авторизациями, многие DApp по умолчанию запрашивают очень большой лимит авторизации, так называемый «неограниченный Approval».
Пользователь, возможно, изначально хотел использовать всего 100 USDC для одной сделки, но разрешил контракту использовать в будущем все USDC на своем адресе. Если эта авторизация не будет отозвана, даже если в кошельке пользователя в тот момент было мало средств, вновь зачисленные в будущем USDC также могут быть затронуты.
Во-вторых, авторизация по умолчанию не исчезает после ухода с DApp. Многие пользователи путают «отключение кошелька» и «отзыв авторизации». На самом деле, отключение кошелька лишь временно лишает веб-страницу возможности читать или запрашивать текущий кошелек, но не изменяет Approval, уже записанный в блокчейн.
Закрытие страницы, удаление DApp, очистка кеша браузера или даже смена приложения кошелька не приведут к его автоматической отмене.
Наконец, даже нормальный контракт в будущем может стать опасным. Потому что многие риски, связанные с авторизациями, исходят не только изначально от фишинговых сайтов. Как и в этой охоте, пользователь мог выдать разрешение изначально нормальному протоколу, но впоследствии контракт протокола мог быть взломан, приватный ключ администратора скомпрометирован, обновляемая логика заменена или возникли проблемы с вызываемым маршрутизирующим контрактом.
Для пользователя активы все еще остаются на его адресе, но с точки зрения прав у другого контракта остается возможность использовать эти активы. Поэтому риск Approval заключается не только в «выдал ли я разрешение плохому парню», но и в «не возникнут ли проблемы в будущем у того, кому я выдал разрешение».
3. Как же управлять рисками Approval?
Перед лицом рисков Approval самый простой совет — «не выдавать неограниченную авторизацию».
Но в реальной среде использования DeFi полностью отказываться от авторизаций нереально. Как упоминалось выше, сама авторизация не является уязвимостью — это базовый способ вызова активов ончейн-приложениями.
Что действительно нужно изменить, так это превратить Approval из разового действия подтверждения в систему постоянного управления правами.
Для обычного пользователя в первую очередь необходимо выработать несколько основных привычек:
- Во-первых, соблюдать принцип «минимальных привилегий». Когда кошелек выдает запрос на авторизацию, старайтесь устанавливать лимит, исходя из фактических потребностей текущего взаимодействия. Например, если планируется использовать только 100 USDT, по возможности выдавайте авторизацию, близкую к 100 USDT, а не открывайте неограниченное разрешение.
- Во-вторых, разделять кошельки для хранения и для взаимодействия. Адрес, на котором долгосрочно хранятся крупные суммы, по возможности не следует часто подключать к незнакомым DApp. Для участия в аирдропах, минтах, новых проектах и рискованных взаимодействиях с DeFi можно использовать отдельный адрес, чтобы ограничить потенциальные потери малым диапазоном.
- В-третьих, регулярно проверять и отзывать авторизации, которые больше не нужны. Пользователи могут использовать такие инструменты, как Revoke.cash, или в imToken перейти на страницу соответствующего токена, нажать «Token Function» в левом нижнем углу, выбрать «Управление авторизациями» (Authorization Management), просмотреть объекты авторизаций, токены и лимиты для этого адреса и инициировать отзыв разрешений, которые больше не используются или чье происхождение неизвестно (дополнительное чтение: «Пошаговое руководство по управлению авторизациями с помощью Revoke.cash»).
Конечно, как ни крути, перед лицом всепроникающих атак через авторизации, полагаться только на осведомленность пользователей и их регулярные проверки недостаточно. В конце концов, большинству пользователей сложно определить, кому принадлежит строка адреса контракта, и оценить, является ли данный лимит авторизации разумным.
Поэтому, как первый рубеж защиты пользователей при входе в Web3, кошелек должен обеспечивать активную защиту на уровне своих возможностей.
Например, imToken помечает или блокирует выявленные рискованные токены, адреса и DApp.Когда пользователь выдает разрешение на управление токенами обычному внешнему аккаунту (EOA) или переводит средства напрямую на адрес контракта, также предоставляются целенаправленные предупреждения о рисках. Эти предупреждения не могут заменить суждение пользователя, но по крайней мере могут добавить необходимый буфер безопасности перед фактической подписью.
Кроме того, imToken на ключевых этапах, таких как вход в DApp, перевод средств, обмен токенов и авторизация, выполняет структурированный анализ и удобочитаемое представление подписываемого контента, помогая пользователю по возможности понять, на что он соглашается, прежде чем подтвердить.Это гарантирует, что содержимое, которое подписывает пользователь, должно соответствовать действиям, которые он видит, а не быть сжатым в набор нечитаемых хэш-данных.
С дальнейшим развитием стандартов Clear Signing, таких как ERC-7730, это удобочитаемое представление «что видишь, то и подписываешь» (What You See Is What You Sign) также имеет шанс превратиться из возможности отдельного кошелька в общий отраслевой стандарт, разделяемый между кошельками, DApp и смарт-контрактами.
В целом, приватный ключ определяет, кто владеет аккаунтом, а Approval определяет, кто еще может управлять активами на этом аккаунте. Это не одно и то же, но одинаково важно.
Это также означает, чтобезопасность кошелька не может ограничиваться только вопросом «не скомпрометирован ли приватный ключ», и это требует совместных усилий как пользователей, так и кошельков: пользователям необходимо видеть объект и лимит перед выдачей авторизации, а после взаимодействия своевременно очищать ненужные разрешения; кошелькам же необходимо сделать эти изначально скрытые в контрактах права более видимыми, понятными, а также более удобными для ограничения и отзыва.
В конце концов, реальную опасность представляет не обязательно только что совершенный перевод, но и давно забытая, но все еще действующая авторизация.














