La falla più comune nei portali è invisibile a qualunque scanner

  • 2 min di lettura

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.