Vai al contenuto
Capitolo 04 · 11 min

Autenticazione e autorizzazione

Gli strumenti IA costruiscono bene le schermate di login: registrazione, accesso, reset della password, tutto. Saltano con altrettanta costanza l'altra metà: controllare che l'utente loggato sia autorizzato a toccare quella cosa specifica. Quel divario, l'autorizzazione rotta, è una delle vulnerabilità gravi più comuni del web, e le app costruite con l'IA ne sono piene.

Controllare che qualcuno abbia un biglietto, ma non controllare mai che sia il biglietto per questo posto.

verifythenWho are youAuthenticateAuthorize

L'autenticazione non è l'autorizzazione

Dietro "auth" si nascondono due domande diverse. L'autenticazione chiede chi sei, dimostrato da un login. L'autorizzazione chiede cosa puoi toccare, deciso per richiesta, per risorsa. Sono indipendenti: essere loggato (autenticato) non dice nulla sul fatto che tu possa leggere l'ordine n. 124 (autorizzazione). Gli strumenti IA riescono benissimo nella prima perché è visibile e richiesta nei prompt. Mancano la seconda perché, con un solo utente di test che possiede tutto, non si presenta mai.

Il risultato è un'app dove il login è solido e, una volta dentro, puoi raggiungere i dati di tutti. La porta d'ingresso ha una buona serratura; nessuna delle porte interne ne ha una.

Il bug che avrai davvero: IDOR

Insecure Direct Object Reference è il nome poco glamour del difetto più probabile nella tua app. Il pattern: una risorsa è indirizzata da un id, e il server la restituisce a chiunque sia autenticato, senza controllare la proprietà. La tua UI ti collega solo ai tuoi record, quindi sembra tutto a posto, ma l'id nell'URL o nella chiamata API è solo un numero, e cambiandolo ottieni quello di qualcun altro.

  possiedi l'ordine 123
  GET /api/orders/123   →  200  { il tuo ordine }     ✓ corretto
  GET /api/orders/124   →  200  { di qualcun altro }  ✗ IDOR: nessun controllo di proprietà
                           ^ l'unica cosa che hai cambiato è un numero
La UI non ti mostra mai l'ordine 124. L'API te lo consegna comunque, perché niente controlla chi ne è il proprietario.

È banale da trovare e banale da sfruttare: incrementa un id, leggi la fattura di uno sconosciuto. Ed è ovunque nelle app costruite con l'IA, perché l'endpoint generato recupera il record per id e lo restituisce; la riga "questo utente ne è il proprietario?" è la protezione invisibile che nessuno ha chiesto.

L'auth deriva man mano che fai prompting

Un fallimento più sottile: una protezione aggiunta in un prompt sparisce in uno successivo, non correlato. Chiedi allo strumento di "aggiungere un filtro a questo endpoint", lui riscrive l'handler, e il controllo di proprietà che c'era è silenziosamente sparito, perché il modello ha rigenerato la funzione attorno alla nuova richiesta e non ha portato avanti il vecchio vincolo. L'endpoint restituisce ancora dati, la demo funziona ancora, e il buco si è riaperto senza lasciare traccia.

Per questo la sicurezza nelle app costruite con l'IA non può essere un passaggio una tantum. I controlli decadono ogni volta che rigeneri codice attorno a loro. Si ri-verifica dopo le modifiche, che è esattamente lo scopo della checklist del capitolo 6.

La regola: controlla sul server, ogni volta

Ogni difesa qui si riduce a una disciplina: il server decide, a ogni richiesta, usando valori che il client non può falsificare:

  • Autentica ogni richiesta protetta lato server; non dedurre mai l'identità da qualcosa che il client ha inviato.
  • Autorizza per risorsa: QUESTO utente autenticato possiede (o ha un ruolo che gli concede) QUESTA riga specifica? Non solo "è loggato".
  • Non fidarti mai di uno user_id, di un ruolo o di un flag is_admin forniti dal client; deriva identità e permessi dalla sessione verificata.
  • Nega per impostazione predefinita: se nessuna regola concede esplicitamente l'accesso, rifiuta. Preferisci restituire 404 invece di 403, così non confermi nemmeno che la risorsa esiste.

È lo stesso principio della Row-Level Security del capitolo 2, applicato al livello applicativo invece che al database. Anzi, i due si rinforzano a vicenda: la RLS intercetta ciò che un controllo applicativo mancato lascia passare, e viceversa. Difesa in profondità significa volerli entrambi.

Una riga per ciascuno

  • Autenticazione (chi sei) e autorizzazione (cosa puoi toccare) sono cose diverse; l'IA costruisce la prima, salta la seconda.
  • L'IDOR, restituire una risorsa per id senza controllare la proprietà, è il difetto grave più probabile in un'app costruita con l'IA.
  • I controlli di autorizzazione derivano: rigenerare codice attorno a una protezione la fa cadere in silenzio, quindi la sicurezza va ri-verificata dopo le modifiche.
  • La regola: il server decide per risorsa, a ogni richiesta, con un'identità verificata: negare per impostazione predefinita, mai fidarsi di id inviati dal client.
Autenticazione e autorizzazione · Cours d'IA · SDEN