La SQL injection avviene quando un dato proveniente dall’esterno viene interpretato dal database come parte di un’istruzione anziché come valore. Nella forma classica il risultato è immediatamente visibile: l’applicazione restituisce dati che non avrebbe dovuto restituire, oppure un messaggio di errore che rivela la struttura interna dell’archivio.

Nella forma cieca non accade nulla di tutto questo. L’applicazione non mostra dati e non mostra errori, e sembra funzionare normalmente. La vulnerabilità è presente e sfruttabile, ma non produce alcun segnale visibile: ed è precisamente questa assenza di segnale a renderla il caso più difficile da individuare, sia per chi verifica sia per chi subisce.

  1. Cosa rende cieca una SQL injection
  2. Le due forme di inferenza
  3. Perché è più grave della forma classica
  4. Perché sfugge alle scansioni automatiche
  5. Le difese che chiudono il problema
SQL injection cieca: la vulnerabilità che non produce errori visibili nella risposta dell'applicazione

Cosa rende cieca una SQL injection

La differenza fra le due forme non sta nella vulnerabilità, che è la stessa, ma in cosa l’applicazione restituisce.

Molte applicazioni sono state configurate correttamente per non esporre i messaggi di errore del database, perché quei messaggi rivelano nomi di tabelle, tipi di dato e versioni del motore. Altre non mostrano i risultati di una interrogazione perché li usano internamente, per esempio per decidere se un utente ha diritto a vedere una certa pagina. In entrambi i casi il canale che nella forma classica riporta l’informazione all’esterno è chiuso.

Il difetto però resta. L’istruzione modificata viene comunque eseguita dal database, e il suo esito continua a influenzare qualcosa: quale pagina viene mostrata, se una richiesta va a buon fine, quanto tempo passa prima della risposta. L’informazione non viene restituita, viene dedotta dal comportamento. È il motivo per cui questa forma è definita anche inferenziale.

La conseguenza pratica è che chiudere i messaggi di errore, che è una misura corretta e necessaria, non corregge la vulnerabilità: ne rende soltanto invisibile la presenza.

Le due forme di inferenza

Le vie per dedurre un’informazione senza riceverla direttamente sono due, e differiscono per il segnale che osservano.

FormaSegnale osservatoCondizione perché funzioniCosa si nota nei log
Basata sul comportamentoLa differenza fra due risposte dell’applicazione: contenuto presente o assente, pagina diversa, codice di stato diversoEsiste una differenza osservabile fra i due esiti possibiliUn numero elevato di richieste quasi identiche allo stesso indirizzo
Basata sul tempoLa durata della risposta: un ritardo indotto dal database segnala l’esitoIl database consente istruzioni che introducono un’attesaTempi di risposta anomali e ricorrenti su una singola funzione

Le due forme condividono una caratteristica che è anche la migliore occasione di rilevamento: ciascuna deduzione vale una singola informazione elementare. Ricostruire un contenuto di qualche rilievo richiede quindi un numero molto alto di richieste, perché ogni richiesta restituisce un frammento minimo. Un’attività di questo tipo non passa inosservata in un sistema di raccolta dei log funzionante: si presenta come un volume anomalo di richieste ripetitive concentrate su una singola funzione dell’applicazione.

sql injection cieca confronto tre forme

Esiste anche una terza via, in cui l’informazione viene fatta uscire attraverso un canale di rete separato invece che attraverso la risposta dell’applicazione. Ne abbiamo trattato in un approfondimento dedicato alla SQL injection out-of-band, perché segue una logica di rilevamento e di difesa diversa da queste due.

Perché è più grave della forma classica

C’è un paradosso in questa vulnerabilità: è più laboriosa da sfruttare e proprio per questo più pericolosa da avere.

Nella forma classica lo sfruttamento produce effetti visibili. Compaiono messaggi di errore, gli utenti segnalano comportamenti anomali, i dati esposti si notano. L’organizzazione ha buone probabilità di accorgersi che qualcosa non va, anche senza strumenti dedicati.

Nella forma cieca no. L’applicazione continua a rispondere correttamente, gli utenti non notano nulla, i messaggi di errore non compaiono perché sono stati disattivati. Una vulnerabilità di questo tipo può restare in produzione per anni senza che nessuno abbia motivo di sospettarne l’esistenza, e il momento in cui viene scoperta è di norma quello in cui i dati compaiono altrove.

Il secondo elemento riguarda l’estensione del danno. Ciò che un attaccante può raggiungere non dipende dalla vulnerabilità ma dai privilegi dell’utenza con cui l’applicazione accede al database. Se quell’utenza legge e scrive su tutte le tabelle, come accade in molte installazioni dove è stata configurata anni prima e mai rivista, il perimetro raggiungibile è l’intero archivio. È l’applicazione del principio del privilegio minimo agli account non umani, che è l’area dove viene disatteso più spesso.

Le vulnerabilità di questa famiglia si individuano verificando i punti in cui l’applicazione costruisce interrogazioni al database a partire da dati esterni. È fra i controlli di un web vulnerability assessment, insieme alle altre categorie della classificazione OWASP. La verifica riguarda ogni parametro che raggiunge l’archivio dati, compresi quelli non visibili nei moduli, come intestazioni e valori nei cookie.

Perché sfugge alle scansioni automatiche

Uno strumento automatico individua bene la forma classica, dove la corrispondenza fra ciò che invia e ciò che riceve è verificabile in modo meccanico. Sulla forma cieca il rendimento cala, per tre ragioni.

La prima è che il segnale da osservare è una differenza, non una presenza. Uno strumento deve stabilire se due risposte differiscono per effetto dell’istruzione modificata o per una qualsiasi altra causa: contenuti dinamici, elementi che variano a ogni caricamento, sistemi di cache. È il tipo di valutazione che produce sia mancati rilevamenti sia falsi positivi.

La seconda riguarda la forma basata sul tempo, dove il segnale è un ritardo. Su un’applicazione con tempi di risposta variabili — carico, rete, interrogazioni pesanti — distinguere un ritardo indotto da un ritardo normale richiede molte misurazioni, e gli strumenti impostati per non rallentare l’applicazione non le compiono.

La terza è il perimetro raggiungibile. Le funzioni più esposte a questa vulnerabilità sono spesso quelle che stanno dietro un’autenticazione: ricerche interne, filtri, esportazioni, pannelli di gestione. Una scansione senza credenziali si ferma alla pagina di accesso e non le vede mai.

Le difese che chiudono il problema

A differenza di altre vulnerabilità, questa ha una correzione risolutiva e nota da vent’anni. Il resto sono misure di contenimento, utili ma subordinate.

MisuraEffettoLimite
Interrogazioni parametrizzateIl dato esterno viene trattato come valore e non può diventare istruzione. È la correzione, non una mitigazioneVa applicata a ogni punto, e i punti dimenticati sono di norma quelli scritti prima dell’adozione della regola
Uso di uno strato di astrazione verso il databaseParametrizza per impostazione predefinita, riducendo il numero di occasioni di erroreLe interrogazioni scritte a mano che ogni progetto contiene restano fuori dalla protezione
Privilegi minimi sull’utenza del databaseLimita cosa è raggiungibile se la vulnerabilità esisteNon impedisce lo sfruttamento, ne riduce la portata
Validazione dei dati in ingressoScarta in partenza i valori che non rispettano il formato attesoNon sostituisce la parametrizzazione: molti valori legittimi restano problematici se concatenati
Gestione controllata degli erroriEvita che i messaggi del database rivelino la struttura internaÈ la misura che trasforma la forma classica in forma cieca: nasconde, non corregge
Raccolta e analisi dei logRende visibile il volume anomalo di richieste ripetitive necessario allo sfruttamentoRileva l’attività in corso, non la vulnerabilità

La riga sulla gestione degli errori merita attenzione, perché contiene il punto centrale dell’articolo. Disattivare i messaggi di errore è corretto e va fatto, ma è anche l’intervento che rende cieca una vulnerabilità che prima era visibile. Un’applicazione che ha chiuso i messaggi senza correggere le interrogazioni è passata da un difetto rilevabile a un difetto silenzioso.

Il log management è ciò che compensa quella cecità dal lato del rilevamento. Le richieste necessarie per dedurre un contenuto sono migliaia, e in un sistema di raccolta funzionante quel volume è un’anomalia evidente.

Quando le funzioni da verificare stanno dietro un’autenticazione — ricerche interne, filtri, esportazioni, pannelli di gestione — la verifica pertinente è il web application penetration test. L’analisi è condotta con credenziali e perimetro concordati, e raggiunge le aree in cui una scansione non autenticata non entra, distinguendo le vulnerabilità reali dalle differenze di comportamento che hanno un’altra causa.


    Dichiaro di aver letto e compreso l'Informativa sul trattamento dei dati