НовостиКриптовалютыXRP Ledger устранил уязвимость, которая могла привести счета в состояние задолженности

XRP Ledger устранил уязвимость, которая могла привести счета в состояние задолженности

Автор: Coindoo·

Ключевые выводы

  • •Поправка fixCleanup3_4_0 была активирована 4 ноября в 14:52 UTC в валидированном леджере 108,112,129, завершив окно уязвимости, начавшееся с запуском делегирования 8 октября под PermissionDelegationV1_1.
  • •До исправления делегат с правом только PaymentBurn мог отправить выкуп, превышающий баланс счёта, а превышение появлялось в виде долговых токенов, выпущенных делегирующим счётом, создавая обязательство, на которое счёт не соглашался.
  • •Уязвимость требовала, чтобы получающий эмитент открыл trust line, принимающий IOU делегирующего счёта; нативный XRP не был затронут, а Multi-Purpose Tokens были отмечены как смежный случай, не покрытый тестом исправления.
  • •Поправка ограничивает объём выкупа для делегата с правом сжигания, но не ограничивает, какие валюты охватывает право, поскольку гранулярные права XRPL нельзя разделить по валютам.
  • •Поскольку записи Delegate в леджере публичны, любую эксплуатацию до леджера 108,112,129 можно проверить onchain, выявив платежи, подписанные делегатами с правом сжигания, оставившие отрицательные балансы trust line.
XRP Ledger устранил уязвимость, которая могла привести счета в состояние задолженности

4 ноября в 14:52 UTC валидаторы XRP Ledger включили поправку fixCleanup3_4_0, закрыв почти четырёхнедельный период, в течение которого делегированное сжигание токенов могло увести баланс счёта за пределы нуля. Coindoo подтвердил транзакцию активации в валидированном леджере 108,112,129, а публичный сервер Ripple в Mainnet указывает поправку как включённую.

Активация последовала за голосованием, которое в конце октября временно потеряло сверхбольшинство — этот setback был отслежен в предварительном отчёте Coindoo. В том отчёте был изложен чек-лист, который рекомендовалось выполнить эмитентам. Код и тест, добавленные вместе с исправлением, отвечают на более узкий вопрос: чьи токены фактически создало превышение.

Почти четыре недели без проверки нулевого баланса

Делегирование было запущено 8 октября под поправкой PermissionDelegationV1_1, согласно панели поправок XRPL. С того момента и до 4 ноября делегат с правом PaymentBurn мог при некоторых конфигурациях увести выкуп за пределы нуля. Поэтому справочник прав XRPL рекомендовал не делегировать это право до включения данной поправки. Это условие было выполнено 4 ноября.

Коммит в rippled, лежащий в основе исправления, автор которого работает под ником yinyiqian1 на GitHub, добавляет отсутствующую проверку. Когда делегат обладает только правом PaymentBurn, леджер сравнивает сумму платежа с фактическим балансом счёта и отклоняет всё, что больше. Документация XRPL уже описывала сжигание как останавливающееся на нуле; для делегированных платежей код не принуждал этот предел до данной поправки.

Внутри теста: Alice, шлюз и чрезмерный платёж

Тест в коммите использует три счёта. Alice владеет 50 USD, выпущенными счётом с именем gateway. Gateway, в свою очередь, открыл trust line, принимающий до 200 USD, выпущенных alice, что в комментариях к коду описано как предоставление платёжному движку «эмиссионной ликвидности, доступной после достижения нуля по trustline».

Затем Alice предоставляет третьему счёту, bob, право PaymentBurn, и bob отправляет платеж от alice к gateway на сумму вдвое больше её баланса. Трассировка показывает, как леджер обработал этот платёж и последующие операции по каждому набору правил.

Старые правила · только PaymentBurn

  • 100 USD: принято
  • 50 alice выкуплено, затем создано 50 USD, выпущенных alice
  • Конечное состояние: gateway владеет 50 USD, выпущенными alice

Новые правила · только PaymentBurn

  • 100 USD: отклонено
  • 20 USD: принято, осталось 30
  • 30 USD: принято, баланс на нуле
  • 1 USD: отклонено

Новые правила · PaymentBurn + PaymentMint

  • 100 USD: принято
  • Переход через ноль, поскольку эмиссия разрешена, а gateway принимает IOU alice

Новые токены были долгом Alice

По старым правилам платёж не добавил ни единицы USD gateway. Обязательство gateway перед alice снизилось с 50 до нуля. Вместо этого появились 50 USD, выпущенные alice и находящиеся у gateway: alice завершила транзакцию, задолжав эмитенту, на основании платежа, подписанного делегатом, которому она разрешила только выкуп.

Леджер рассматривает их как два разных актива. Документация XRPL по форматам активов идентифицирует токен trust line по коду валюты и выпускающему счёту, поэтому USD alice и USD gateway имеют одинаковый код, но разные эмитенты. Нативный XRP, у которого нет эмитента, находился вне уязвимости полностью.

Таким образом, в задокументированном случае риск лежал на двух сторонах: счёте, делегировавшем право сжигания, который мог получить обязательство, на которое он никогда не соглашался, и эмитенте, получившем эти IOU. Держатели USD gateway не сталкивались с новыми единицами принадлежащего им токена.

Предусловие, сужавшее уязвимость

Превышение зависело от одной настройки на стороне gateway. Без trust line, принимающего IOU alice, у платежа не было способа создать USD, выпущенные alice. Эмитент должен сам создать эту trust line, что является главным аргументом в пользу ограниченного практического охвата уязвимости.

Этот аргумент имеет нюанс. Документация XRPL по делегированию также перечисляла Multi-Purpose Tokens (MPT) среди активов, которые делегат с правом только сжигания мог эмитировать до исправления, при этом тест коммита охватывает только случай trust line. Ни один источник не описывает реальный инцидент, но трактовку через trust line не следует распространять на эмитентов MPT без отдельного теста.

Одно право по-прежнему охватывает все валюты

Поправка ограничивает, сколько делегат с правом сжигания может выкупить. Она не меняет того, какие токены охватывает это право. Гранулярные права жёстко заданы, и та же документация указывает, что счёт не может предоставить делегату право отправлять одни валюты, withholding другие.

Для операционного счёта, владеющего токенами USD и EUR или стейблкоинами двух эмитентов, одно предоставление PaymentBurn позволяет делегату выкупить все из них, каждый до его баланса. Любое разделение по валютам должно происходить за счёт распределения активов по счетам. Право на тип транзакции Payment охватывает ещё больше — платежи этого типа в целом, поэтому проверка, ограниченная двумя гранулярными значениями, может его упустить. Ранее материал Coindoo о том, как XRPL разделяет операционные полномочия между счетами описывает, как институты структурируют эти роли.

Что показало бы, использовалась ли уязвимость

Каждое предоставление права публично. Запись Delegate в леджере фиксирует предоставляющий счёт, делегата и список его прав, что делает вопрос о злоупотреблении проверяемым любым желающим onchain.

Onchain-паттерн:

  • Платёж, валидированный после 8 октября и до леджера 108,112,129.
  • Подписанный делегатом, обладавшим на тот момент PaymentBurn, но не PaymentMint и не Payment.
  • Отправленный эмитенту токена, оставляющий у делегирующего счёта отрицательный баланс по этой trust line.

Платёж, соответствующий всем трём критериям, подтвердил бы превышение в Mainnet. Проверка всех предоставлений PaymentBurn за этот период, не выявившая ни одного, исключила бы это для токенов trust line, при этом MPT остаются отдельной проверкой. Поскольку DelegateSet полностью заменяет список прав, как пояснялось в предварительном отчёте, проверка должна использовать права, действовавшие на момент валидации каждого платежа.

Поправка применяется с леджера 108,112,129 и далее. Любой платёж, валидированный до неё, остаётся в точности как записан, включая платежи, перешедшие через ноль. Для операторов, проверяющих транзакции вокруг изменения, номер валидированного леджера является соответствующей границей для определения применявшихся правил.

Источник: Coindoo