La tecnica di attacco SQL injection ha più di venticinque anni. La lista OWASP Top 10 la include da quando esiste. Ogni framework moderno offre gli strumenti per evitarla. Eppure continua a comparire nei report di sicurezza delle applicazioni web delle aziende.

La colpa non è degli IT manager. Basta un solo punto del codice scritto nel modo vecchio, spesso anni prima da qualcuno che non lavora più in azienda. Quella vulnerabilità resta lì e nessuno la sta cercando.

Vediamo cosa accade tecnicamente, quali forme assume e perché una scansione automatica ne trova solo una parte.

  1. Che cosa succede in una SQL injection
  2. Perché il database esegue quelle istruzioni
  3. Le varianti principali
  4. Cosa comporta per l’azienda
  5. Perché gli scanner automatici non bastano
  6. Come si previene davvero
istruzione malevola che penetra in un database attraverso un input applicativo

Che cosa succede in una SQL injection

Ogni applicazione web che mostra dei dati ha bisogno di interrogare un database. Quando cercate un prodotto in un catalogo, l’applicazione prende il testo che avete digitato e costruisce un’istruzione in linguaggio SQL. Poi la trasmette al database, che restituisce i risultati corrispondenti.

Il problema nasce da come l’applicazione costruisce quell’istruzione. Se incolla il testo dell’utente direttamente nella query, il database non ha alcun elemento per distinguere i dati dalle istruzioni. Riceve una stringa unica e la interpreta tutta come linguaggio SQL, perché è esattamente il suo compito.

A quel punto chi scrive nel campo di ricerca non inserisce più un dato in un’istruzione preesistente: scrive una porzione dell’istruzione stessa. È questo il significato del termine injection. Il meccanismo si ripresenta in tutte le altre vulnerabilità di injection. Lo ritroviamo nella XPath injection sui documenti XML e nella prompt injection nei chatbot aziendali. Qui però le contromisure consolidate della SQL injection non valgono più.

Perché il database esegue quelle istruzioni

Il database non commette alcun errore: svolge esattamente il compito per cui esiste. Riceve una query sintatticamente valida e la esegue. Non ha nessuna informazione per sapere che una parte di quella query arriva da un modulo compilato da una persona sconosciuta.

La causa quindi non sta nel database ma nel fatto che dati e istruzioni viaggiano sullo stesso canale, mescolati in un’unica stringa. Finché a separarli c’è soltanto una convenzione di scrittura, quel confine resta soggetto a interpretazione.

Per questo la contromisura corretta deve essere strutturale e non un filtro. Filtrare i caratteri sospetti significa tentare di prevedere in anticipo tutte le forme che un input malevolo potrebbe assumere: le diverse codifiche dei caratteri, le varianti di sintassi SQL tra un motore e l’altro, le funzioni di conversione disponibili. A chi attacca basta un solo caso non previsto. Chi difende deve prevederli tutti.

Per la stessa ragione la OWASP Top 10 dedica alle injection una categoria autonoma: il difetto sta nella progettazione del flusso dei dati e non in una singola riga di codice da correggere.

L’applicazione trasmette al database un’istruzione che contiene al suo interno il testo digitato dall’utente. Il database la esegue per intero e restituisce anche i record che l’applicazione non avrebbe dovuto mostrare.

Le varianti principali

Di solito si divide la SQL injection in tre famiglie. Si distinguono per il modo in cui l’attaccante ottiene la risposta dal database e non per la strada da cui l’input ci arriva.

FamigliaCome arriva la rispostaQuando si presenta
In-bandDirettamente nella pagina, nei risultati oppure nei messaggi di erroreL’applicazione mostra all’utente finale gli errori del database
BlindNon arriva in alcuna forma visibile: l’attaccante la deduce dal comportamento della pagina o dai tempi di rispostaL’applicazione gestisce correttamente gli errori ma resta comunque vulnerabile
Out-of-bandSu un canale esterno all’applicazione, attraverso le funzioni di rete del databaseIl server può collegarsi all’esterno senza controlli

La forma in-band è la più evidente e anche la più semplice da individuare durante una verifica. Le altre due spiegano perché una pagina che si comporta in modo apparentemente corretto può nascondere una vulnerabilità. La SQL injection di tipo blind non produce nessun output osservabile. Con la variante out-of-band la risposta non passa nemmeno dall’HTTP dell’applicazione.

C’è poi un caso che sfugge quasi sempre alle verifiche superficiali. L’input finisce nel database senza creare alcun problema immediato ed entra in una query solo in un secondo momento, magari attraverso un’altra funzione dell’applicazione o un processo pianificato che gira di notte. Il dato entra in un punto del sistema e il difetto si manifesta in un altro. Chi verifica un campo alla volta non ha modo di collegarli.

Cosa comporta per l’azienda

Il primo effetto riguarda la lettura non autorizzata dei dati. Supponiamo che la query interroghi il catalogo dei prodotti ma che l’account con cui l’applicazione si collega al database abbia accesso a tutte le tabelle. In quel caso l’attaccante raggiunge anche gli archivi di utenti, ordini e credenziali.

Il secondo effetto riguarda la scrittura. Se l’account applicativo ha i permessi necessari, l’attaccante può modificare o eliminare record. In certi casi può anche alterare la logica con cui l’applicazione controlla le autenticazioni, senza conoscere alcuna password.

Il terzo effetto è il movimento laterale nella rete ed è quello che quasi tutti sottovalutano. Un database con privilegi molto ampi può leggere e scrivere file sul sistema operativo che lo ospita oppure raggiungere altre macchine della rete interna. In questo scenario l’applicazione web non è l’obiettivo dell’attacco ma soltanto il punto d’appoggio da cui l’attacco prosegue.

Sul piano normativo, se una vulnerabilità nota espone dati personali il GDPR chiede di gestire e documentare la violazione. Per i soggetti che rientrano nella NIS2 la verifica periodica della sicurezza applicativa fa parte delle misure attese. Ne abbiamo parlato a fondo nell’articolo sulle verifiche documentate e la conformità.

Avete già fatto verificare le vostre applicazioni web su questo?

Il Web Vulnerability Assessment analizza applicazioni e siti seguendo la OWASP Top 10 e restituisce le vulnerabilità che trova in ordine di priorità.

Scopri il Web Vulnerability Assessment

Perché gli scanner automatici non bastano

Uno strumento automatico funziona molto bene sui casi lineari: un parametro da modificare, una risposta che cambia in modo osservabile, un rilievo da riportare. Su un’applicazione reale però trova soltanto una parte del problema.

Questi strumenti si fermano quasi sempre negli stessi punti:

  • flussi che richiedono un’autenticazione, dove lo scanner perde la sessione e finisce per verificare pagine di errore anziché funzioni applicative;
  • processi su più passaggi, dove il parametro vulnerabile diventa raggiungibile solo dopo aver completato tutti gli step precedenti;
  • casi in cui l’applicazione salva il dato e lo usa in un secondo momento;
  • parametri costruiti in modo non convenzionale, che lo strumento non riconosce nemmeno come parametri.

C’è poi il problema opposto, che in termini di tempo pesa di più: le segnalazioni che sembrano vulnerabilità senza esserlo. Per distinguerle bisogna provare a sfruttarle in modo controllato. È proprio il lavoro che un Web Application Penetration Test svolge dopo la scansione. Ne abbiamo scritto anche a proposito dei limiti degli assessment automatici.

Questo non significa che gli strumenti automatici siano inutili. Sono il punto di partenza corretto di qualunque verifica. Il problema nasce quando li si considera anche il punto di arrivo.

Come si previene davvero

Le contromisure esistono da tempo. Nella tabella le abbiamo ordinate per efficacia reale sul rischio e non per facilità di adozione.

MisuraPerché funziona
Query parametrizzateIl valore inserito dall’utente viaggia su un canale separato rispetto all’istruzione. Il database lo tratta come dato e non arriva mai a interpretarlo come codice
Privilegi minimi sull’account del databaseLimita ciò che un attaccante raggiunge se riesce a sfruttare la vulnerabilità. Un account applicativo non ha alcuna necessità di poter eliminare tabelle
Messaggi di errore generici verso l’esternoIl dettaglio tecnico serve nei log interni, non nella pagina che vede l’utente. Toglie all’attaccante il canale di risposta più immediato
Validazione dell’input per tipo e formatoÈ un livello aggiuntivo di protezione e non la difesa principale. Un campo che deve contenere una data non deve accettare testo libero
Web application firewallContiene il problema ma non corregge il difetto. Serve a guadagnare tempo quando non potete correggere subito il codice
Revisione del codice nei punti che costruiscono queryÈ lì che si trovano i residui: le funzioni più vecchie, i moduli ereditati da progetti precedenti, le query scritte a mano per aggirare un limite del framework

ORM e componenti secondari

Un ORM riduce molto il rischio ma non lo elimina. Tutti i framework offrono metodi per scrivere query grezze e gli sviluppatori li usano ogni volta che serve qualcosa che l’ORM non copre. Quei punti richiedono la stessa attenzione del codice scritto a mano, perché è esattamente quello che sono.

Vale infine la pena allargare lo sguardo oltre l’applicazione principale. Le injection compaiono spesso sui componenti secondari: un vecchio pannello di amministrazione ancora raggiungibile, un modulo di ricerca in una sezione poco visitata del sito, un’integrazione con un sistema esterno realizzata anni prima. Sono le parti che nessuno modifica da tempo. E proprio per questo nessuno pensa di verificarle. Un Vulnerability Assessment parte esattamente dal censire ciò che risulta raggiungibile, prima di decidere quali componenti testare in profondità.

Il codice vulnerabile lo scrivono le persone, non gli strumenti.

I percorsi della Cyberment Academy affrontano le vulnerabilità applicative dal punto di vista di chi sviluppa, partendo dagli errori che si incontrano nei progetti reali.

Scopri i corsi per le aziende


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