AI агенти, заплащащи за API извиквания чрез x402 SDK, биха могли да подпишат плащане за целия си наличен баланс от поддържан токен, ако злонамерено API го поиска, съобщиха от компанията за сигурност V12 на 22 октомври.
Причината се крие в клиента по подразбиране на SDK пакетите, при който липсваше лимит на разходите до добавянето на такъв в изданията от 18 август. Рискът засягаше само агенти, които автоматично подписват плащания и чиито приложения нямат дефинирани лимити.
Липсващият лимит е една от 25-те уязвимости, открити от V12 в кода на x402, и една от трите, класифицирани като критични и описани подробно. Фондацията x402 Foundation, която поддържа SDK пакетите, вече бе отстранила и трите критични уязвимости в изданията от 18 август.
Втората уязвимост позволяваше на фасилитатор (услугата, която проверява x402 плащанията) да приеме Solana трансакция, която не прехвърля никакви токени, като валидно плащане. Сред SDK пакетите на x402 само този за TypeScript съдържаше този дефект. Третата уязвимост позволяваше на злонамерен сървър да накара агент да подпише съобщение за вход за различен уебсайт.
От V12 откриха уязвимостите чрез анализ на кода и провеждане на локални тестове. Нито V12, нито x402 Foundation са докладвали публично за реални атаки, които да са се възползвали от тях.
Фондацията не е публикувала официален бюлетин за сигурност относно трите уязвимости, а регистрите с промени (changelogs) описват корекциите, без да ги определят като корекции за сигурност. Към 23 октомври npm audit не показваше бюлетини за сигурност за последните TypeScript версии преди корекциите, а в PyPI нямаше регистрирани уязвимости за последната Python версия преди тях, установи The Hacker News. Разработчиците, които разчитат на тези автоматизирани проверки, не получават предупреждение за обновяване.
Coinbase създаде x402 и по-рано тази година го предаде на x402 Foundation — проект под шапката на Linux Foundation, чиито членове включват Visa и Mastercard. Coinbase заема най-високопоставеното място в техническия управителен комитет на фондацията.
Липса на лимит за разходи в клиента по подразбиране
x402 е отворен стандарт, позволяващ на софтуерни решения, включително AI агенти, да заплащат за API извиквания директно в самата уеб заявка, без да се изисква одобрение на всяко плащане от човек.
Сървър, изискващ плащане, отговаря с HTTP статус код 402 Payment Required и предоставя списък с опции за плащане, всяка със сума, токен и получател. Клиентът избира една опция, подписва плащането и изпраща заявката отново.
Клиентът по подразбиране избираше първата опция от списъка и преди да бъде въведена корекция за сигурност, не поставяше никакъв лимит върху сумата.
Недобронамерено API би могло да използва това поведение, за да превърне рутинна заявка за данни в искане за целия наличен баланс на портфейла от поддържан токен, посочват от V12. Предходно малко плащане би могло да разкрие адреса на портфейла, така че сървърът първо да провери наличния баланс.
При наличие на автоматично подписване и липса на зададени политики за плащане от страна на приложението, клиентът би могъл да подпише плащане за цялата сума. За токени, поддържащи подписани трансфери, атакуващият след това би могъл да изпрати подписаното плащане и да изтегли средствата.
Изданията от 18 август добавиха контрол върху разходите в клиентите за TypeScript, Python и Go. По подразбиране плащанията вече са с таван от $1 и са разрешени единствено разпознавани от SDK стейбълкойни, обвързани с щатския долар, като например USDC.
Одобрения на токени, приемани като плащания в Solana
В рамките на x402 сървърът на търговеца разчита на фасилитатор за валидация на всяко плащане и предаването му към блокчейна. В мрежата на Solana фасилитаторът поема и таксата за трансакцията.
Кодът на фасилитатора за Solana в TypeScript проверяваше дали плащането извиква позволена програма за токени, след което го отчиташе като превод, без да проверява типа на инструкцията. Одобрението на токен (token approval), което дава право на друг акаунт да изразходва токени на по-късен етап, но само по себе си не прехвърля средства, се различава от превода единствено по своя първи байт.
В локалния тест на V12 фасилитаторът прие подобно одобрение като валидно плащане. Тестът не е изпращал реална трансакция към мрежата.
Търговец, разчитащ на този фасилитатор, би могъл да предостави платен ресурс, без реално да получи токени, обясняват от V12, определяйки проблема като „пълно заобикаляне на процеса по плащане“. За целта на атакуващия му е бил необходим акаунт за токени, но не и наличност, като същевременно фасилитаторът е заплащал таксата за трансакцията всеки път.
SDK пакетите за Python и Go вече съдържаха проверка за типа на инструкцията. Версиите от 18 август добавиха същата проверка и в кода на TypeScript.
Всяка публикувана версия на @x402/svm от 2.0.0 до 2.22.0 съдържа този дефект, а всяка версия от 2.23.0 нататък разполага с необходимата проверка, установи The Hacker News при преглед на публикуваните пакети.
Подписване на данни за вход за други уебсайтове
Стандартът x402 включва и разширение за автентикация, наречено Sign-In-With-X (SIWx). То позволява на агент да влезе в профил, като подпише кратко съобщение със своя портфейл — например за да докаже предходно плащане, вместо да заплаща повторно. В Ethereum съобщението съдържа името на уебсайта, адреса на портфейла и еднократен код.
Автоматизираният клиент подписваше тези съобщения, без да провери дали посоченият сайт съвпада с този, с който е осъществена връзка.
Злонамерен сървър би могъл да получи ново съобщение за вход от друг сайт, да го препрати на агента и да използва подписа, за да влезе в съответния сайт от името на портфейла на агента, посочват от V12. Това би сработило навсякъде, където другият сайт приема препратеното съобщение, предоставяйки на атакуващия пълния достъп, осигуряван от входа.
Изданията от 18 август карат клиентите за TypeScript, Python и Go да отказват подписване, освен ако сайтът в съобщението не съвпада със сайта, изпратил отговора с код 402. Проектът промени и спецификацията на SIWx, която вече изисква клиентът да откаже подписване при несъответствие между двата адреса.
Кодът на TypeScript, който извиква директно createSIWxPayload, вече задължително трябва да подава URL адреса от отговора с код 402 след всякакви пренасочвания. Обвивките @x402/fetch и @x402/axios подават адреса автоматично.
Какво е необходимо да се обнови
Обновяването до най-новите версии включва и последващи корекции за сигурност, сред които и такава за отделно заобикаляне на плащания в @x402/core 2.27.0 от септември. Към 23 октомври актуалните версии са 2.28.0 за @x402/core, @x402/svm, @x402/extensions, @x402/fetch и @x402/axios, v2.28.0 за Go модула и 2.25.0 за пакета на Python.
В TypeScript клиентите получават защитата срещу неограничени разходи чрез обновяване на @x402/fetch или @x402/axios до 2.23.0 или по-нова версия, което автоматично изтегля съответния @x402/core. Приложенията, използващи SIWx, изискват също @x402/extensions 2.23.0 или по-нова версия, където се намира проверката за автентикация. Фасилитаторите, обработващи Solana плащания, се нуждаят от @x402/svm 2.23.0 или по-нова версия.
След обновяването съществуващите клиенти разполагат с лимит от $1 за всяко плащане и са ограничени само до разпознати стейбълкойни, освен ако самото приложение не зададе собствени контроли върху разходите. Приложенията, които подават spendControls: false, изключват изцяло тези защити.
Екипите, които нямат възможност да инсталират обновления веднага, могат да регистрират политика за плащания, която отхвърля всяка опция над определена сума. По-старите версии на клиентите поддържат това чрез registerPolicy в TypeScript и Go и register_policy в Python, където има и готова политика max_amount.
От V12 препоръчват клиентите да се уверят, че съобщението за вход в SIWx идентифицира сайта, с когото комуникират, преди да го подпишат, да задават бюджети за отделните плащания и общите разходи, както и да ограничават кои токени, мрежи и получатели могат да бъдат финансирани.