La falla più comune nei portali è invisibile a qualunque scanner
Un portale clienti. Un utente vero, con login regolare, apre un suo documento. L’indirizzo è qualcosa come /api/documenti/4187.
Cambia il numero. 4186. E vede il contratto firmato di un’altra azienda.
È la prima voce della classifica OWASP per le API, si chiama Broken Object Level Authorization, e la troviamo in una buona parte dei portali su cui ci chiamano.
Perché nessuno scanner la trova
Perché tecnicamente non c’è nessun errore. Il programma fa esattamente quello che gli è stato chiesto: gli è stato chiesto il documento 4186, e lui restituisce il documento 4186. Non va in crash, non produce warning, risponde 200.
Uno strumento automatico cerca schemi noti: input non filtrati, versioni vecchie, configurazioni sbagliate. Non può sapere che quel documento non è di chi lo sta chiedendo, perché quell’informazione sta nel vostro modello di business, non nel codice.
Come si scrive per sbaglio
Così:
if (!utente_autenticato()) {
return null;
}
return db()->riga('SELECT * FROM documenti WHERE id = ?', [$id]);
Un controllo c’è, ed è quello che tutti si aspettano di vedere: senza login non si passa. Ma la domanda a cui l’ultima riga risponde è «esiste il documento 4186?», non «il documento 4186 è di chi lo sta chiedendo?».
Come si chiude
$utente = utente_autenticato();
if (!$utente) {
return null;
}
return db()->riga(
'SELECT * FROM documenti WHERE id = ? AND cliente_id = ?',
[$id, $utente->cliente_id]
);
La correzione non aggiunge un controllo: toglie la possibilità di dimenticarlo.
Finché l’autorizzazione è un if scritto accanto alla query, prima o poi qualcuno scriverà una query nuova senza quell’if a fianco — magari fra due anni, magari un fornitore diverso. Messa dentro la query, la domanda sbagliata non si può più formulare.
E c’è un effetto collaterale utile: chi prova un numero a caso riceve un 404, quindi non impara nemmeno che quel numero corrisponde a qualcosa.
Come si verifica sul vostro
Serve una persona che provi, con due account di prova e mezz’ora. Aprite qualcosa con il primo account, prendete l’indirizzo, e riprovate con il secondo. Se vedete il documento del primo, avete trovato.
Non serve essere tecnici per fare questa prova. Serve solo farla.
$ ls ./journal --altri
Da leggere dopo
Il backup che nessuno ha mai provato a ripristinare non è un backup
È una copia. La differenza si scopre nel momento peggiore possibile.
App mobile o web app? La domanda giusta non è questa
Prima di scegliere la tecnologia bisogna rispondere a una domanda sull'uso, e le risposte possibili sono solo tre.
Tre domande da fare a chi ti costruisce il software
Non servono competenze tecniche per farle, e le risposte dicono più di qualunque portfolio.
