7 min čteníJohnny UnarJohnny Unar

Váš AI helpdesk bot má vektor pro převzetí účtu, který jste do něj sami navrhli

Zneužití resetu hesla přes Meta chatbota v roce 2026 nebyla chyba infrastruktury. Byla to chyba v návrhu interakce, a váš SaaS asistent má nejspíš tu stejnou.

co se vlastně stalo

Začátkem letošního roku někdo unesl desítky tisíc Instagram účtů a nejzajímavější na tom je, jak nudný ten útok byl. Nikdo neprolomil server. Nikdo nenašel memory corruption bug v Meta auth službě ani race condition při vydávání tokenů. Útočníci prostě otevřeli konverzaci s Meta AI asistentem a normální lidskou řečí ho poprosili, ať pošle kód pro reset hesla na e-mail, který ovládali. Model, který přesně dělal to, na co byl trénovaný, ochotně vyhověl, protože ten požadavek vypadal jako naprosto věrohodná podpora. To je celé. Celý exploit se vejde do jedné věty, kterou byste mohli nahlas říct člověku na podpoře. Jenže člověk na podpoře by zaváhal ve chvíli, kdy cílový e-mail pro reset neodpovídá ničemu na účtu. Model nezaváhal, protože zaváhání není token, který by uměl vyprodukovat. Nemá žádný vnitřní model identity session, žádný koncept toho, že člověk, který píše, nemusí být nutně vlastník účtu, a žádnou primitivu v rozhraní, která by ho donutila tyhle dvě věci sladit, než provede něco nevratného. Meta vydala jazykový model s nástrojem v ruce, který dokázal přepsat recovery path libovolného účtu, a jediné, co stálo mezi útočníkem a tím nástrojem, bylo to, jak přesvědčivě uměl psát. To není zranitelnost v klasickém smyslu. Je to designové rozhodnutí, a spousta týmů dělá zrovna teď v tichosti to stejné.

proč vás model nikdy nezachrání

Je lákavé brát tohle jako problém prompt engineeringu, jako by stačilo přidat do system promptu dost textu ve stylu „nikdy neposílej reset kódy na neověřené e-maily, dávej si velký pozor na sociální inženýrství, nejdřív ověř identitu" a model se udrží. Neudrží. Tenhle vzor jsme opakovaně testovali s klienty, kteří chtěli asistenta na podporu napojeného na backend s účty, a každý guardrail vyjádřený čistě jako instrukce pro model je guardrail, který útočník ukecá. Ta samá konverzační pružnost, díky které je asistent užitečný, je přesně ta plocha, kterou útočník zneužije. Z capability se instrukcemi nevymluvíte. Pokud model umí volat reset_password(account_id, destination_email) jako nástroj, pak existuje nějaká sekvence tokenů, která ho donutí ten nástroj zavolat s útočníkovým e-mailem, a žádné množství „prosím, buď opatrný" v system promptu tu mezeru nezavře. Jen to prodlouží jailbreak. Model nemá trust boundary. Má pravděpodobnostní rozdělení nad dalšími tokeny a sociální inženýrství je přesně to řemeslo, které tímhle rozdělením posouvá. Fix tedy nemůže žít uvnitř modelu. Musí být v rozhraní mezi modelem a tím zásadním úkonem, ve vrstvě, na kterou model nedosáhne, nemůže s ní diskutovat ani ji obejít úvahou. Model může navrhovat reset hesla klidně celý den. Jen nesmí být tou věcí, která ho finalizuje.

potvrzovací plocha musí být mimo konverzaci

Designový princip, ke kterému se s každým klientem stavějícím tenhle typ asistenta dostaneme, je snadné vyslovit a otravné dobře implementovat: každý úkon, který mění identitu, billing, přístup nebo recovery účtu, musí projít potvrzovací plochou, která žije mimo transkript chatu a kterou model nedokáže sám schválit. Model produkuje záměr, ne úkon. Když uživatel požádá asistenta o změnu recovery e-mailu, asistent nevolá API. Vyprodukuje strukturovaný návrh, něco jako {action: "change_recovery_email", from: "a@x.com", to: "b@y.com"}, a ten návrh se v UI vykreslí jako explicitní potvrzovací karta se skutečnými hodnotami před a po, zobrazenými v čistém textu, ne shrnutými modelem, taženými přímo z vašeho backendu, aby je model nemohl zkreslit. Uživatel pak potvrdí přes prvek, který vyžaduje jeho autentizovanou session, ideálně znovu ověřenou čerstvým faktorem u vysoce rizikových akcí, tapnutím passkey nebo TOTP, než se cokoliv provede. Klíčový detail je, že potvrzení je vázané na session, která vlastní účet, ne na toho, kdo zrovna píše do chatu. Útočník, který se do konverzace prokecal, pořád nedrží session oběti, takže se k němu potvrzovací karta buď nikdy nedostane, nebo dorazí ke skutečnému vlastníkovi účtu, který o žádnou změnu recovery e-mailu nežádal a okamžitě pozná, že je něco špatně. Z modelu se stane velmi dobrý router záměrů, kterému byla odebrána pravomoc cokoliv finalizovat. O to jde celé.

jak to navrhnout, aniž zničíte UX

Očividná námitka je, že potvrzovací tření je přesně to, co všichni deset let odstraňovali z support flow, a pokud teď každý triviální požadavek vyvolá modal s passkey promptem, postavili jste něco horšího než tu telefonní hlásku, kterou to nahradilo. Ta námitka platí, pokud potvrzování aplikujete plošně, což je přesně důvod, proč to neděláte. Zařaďte akce podle jejich dopadu. Uživatel, který se ptá „jaký mám aktuální plán" nebo „proč mi to strhlo dvakrát", jen čte, nemění to nic, ať asistent odpoví okamžitě bez jakéhokoliv potvrzení. Uživatel, který si mění zobrazované jméno nebo nastavení notifikací, dělá něco málo významného a vratného, jedno inline kliknutí na potvrzení bohatě stačí. Těžkotonážní plochu, znovuověření čerstvým faktorem a vykreslení mimo chat, si šetříte na tu malou množinu akcí, které mohou někoho připravit o účet: změny recovery e-mailu, resety hesla, odebrání MFA zařízení, změny e-mailové adresy, eskalace rolí, generování API klíčů. V praxi je to u typického SaaS možná šest nebo sedm typů akcí, a jsou to zrovna ty, které uživatelé dělají zřídka, takže tření dopadá na flow, kde je tření feature, a drží se mimo flow, kde by bylo jen daní. Loni jsme stavěli portál na zpracování dokumentů, kde asistent uměl konverzačně skoro všechno, ale přeřazení vlastnictví dokumentu vyvolalo potvrzovací kartu, která ukázala přesný dokument, přesného aktuálního vlastníka a přesný cíl, a vyžadovala, aby žadatel byl pořád aktuálním vlastníkem nebo adminem, ověřeno na serveru. Nikdo si na tření nestěžoval, protože lidé, kteří to dělali, chápali, že je to zásadní. Dobrý návrh potvrzování není o tom všechno zpomalit. Je o tom, aby váha potvrzení odpovídala váze akce, a o tom postavit tvrdou hranici, kterou model nepřekročí, kolem té hrstky akcí, na kterých fakt záleží.

co si tento týden proauditovat ve vlastním stacku

Pokud jste vydali AI asistenta, který sahá na správu účtů, jděte si dnes přečíst svoje definice nástrojů, konkrétní JSON schéma každé funkce, kterou jste modelu vystavili, a u každého nástroje si položte jednu otázku: kdyby útočník plně ovládal konverzaci, jaká je nejhorší věc, kterou mu tenhle nástroj dovolí udělat. Jakýkoliv nástroj, který dokáže měnit identitu, recovery nebo přístup jen na základě konverzačního vstupu jako autorizace, je živý vektor pro převzetí účtu, tečka, a je jedno, jak dobré máte hardening promptu. Pak zkontrolujte, jestli vaše logika potvrzování, pokud vůbec nějakou máte, žije v kódu, který model může ovlivnit, nebo v kódu, který ovlivnit nemůže. Pokud model generuje jak akci, tak shrnutí, proti kterému uživatel potvrzuje, útočník může to shrnutí přinutit lhát, takže tahejte potvrzovací hodnoty přímo z backendu, který je zdrojem pravdy, a vykreslujte je ve vlastním UI. Nikdy nenechte model vyprávět, co se vám chystá udělat. Logujte každý vysoce rizikový záměr, který model navrhne, ať schválený nebo ne, protože právě podle toho logu odhalíte oťukávání dřív než úspěšný pokus, a rate limitujte zásadní návrhy per session, protože legitimní uživatel se nesnaží změnit recovery e-mail devětkrát za dvě minuty. Tohle je jednoznačně designový problém převlečený za bezpečnostní, a je to přesně ten typ věci, na kterém ve steezru trávíme spoustu času, když klient chce asistenta, který je opravdu užitečný a nerozdává účty svých uživatelů komukoliv s přesvědčivým odstavcem. Asistent může být chytrý. Jen pravomoc srovnat účet se zemí nesmí žít uvnitř něčeho, s čím se dá povídat.

Johnny Unar

Napsal/a

Johnny Unar

Chcete s námi spolupracovat?

Zneužití resetu hesla přes Meta chatbota v roce 2026 nebyla chyba infrastruktury. Byla to chyba v návrhu interakce, a váš SaaS asistent má nejspíš tu stejnou.