Cos'è l'SQL injection?

Utilizzando l'SQL injection, gli aggressori possono eseguire comandi di database non autorizzati sul database SQL di una vittima.

Obiettivi di apprendimento

Dopo aver letto questo articolo sarai in grado di:

  • Definire l'SQL injection
  • Spiegare come funziona l'SQL injection
  • Scoprire come difendersi dall'SQL injection
  • Esplorare gli attacchi SQLI composti

Argomenti correlati


Vuoi saperne di più?

Abbonati a theNET, il riepilogo mensile di Cloudflare sulle tematiche più discusse in Internet.

Fai riferimento all'Informativa sulla privacy di Cloudflare per scoprire come raccogliamo ed elaboriamo i tuoi dati personali.

Copia link dell'articolo

Cos'è l'SQL injection (SQi)?

Structured Query Language (SQL*) Injection è una tecnica di code injection utilizzata per modificare o recuperare dati dai database SQL. Inserendo istruzioni SQL specializzate in un campo di immissione, un malintenzionato è in grado di eseguire comandi che consentono il recupero di dati dal database, la distruzione di dati sensibili o altri comportamenti manipolativi.

Con la corretta esecuzione del comando SQL, l'utente non autorizzato è in grado di falsificare l'identità di un utente con maggiori privilegi, di nominare se stesso o altri amministratori di database, di manomettere i dati esistenti, di modificare transazioni e saldi e di recuperare e/o distruggere tutti i dati del server.

Nell'informatica moderna, l'SQL injection avviene in genere su Internet inviando query SQL dannose a un endpoint API fornito da un sito Web o da un servizio (ne parleremo più avanti). Nella sua forma più grave, l'SQL injection può consentire a un malintenzionato di ottenere l'accesso come root a una macchina, ottenendone il controllo completo.

*SQL è un linguaggio di programmazione utilizzato per gestire la maggior parte dei database.

Come funziona un attacco SQL injection?

Immaginiamo un'aula di tribunale in cui un uomo di nome Bob è sotto processo e sta per comparire davanti a un giudice. Quando compila i documenti prima del processo, Bob scrive il suo nome come "Bob è libero di andare". Quando il giudice arriva al suo caso e legge ad alta voce "Ora Bob è libero di andare", l'ufficiale giudiziario lascia andare Bob perché lo ha detto il giudice.

Sebbene esistano varianti leggermente diverse di SQLi, la vulnerabilità di base è essenzialmente la stessa: un campo di query SQL che dovrebbe essere riservato a un tipo particolare di dati, come un numero, riceve invece informazioni inaspettate, come un comando. Una volta eseguito, il comando oltrepassa i confini previsti, consentendo comportamenti potenzialmente nefasti. Un campo di query viene solitamente compilato con i dati immessi in un modulo su una pagina Web.

Diamo un'occhiata a un semplice confronto tra istruzioni SQL normali e dannose:

Query SQL normale:

In questa normale query SQL, la stringa studentId viene passata in un'istruzione SQL. L'obiettivo è cercare nell'elenco di studenti uno studente che corrisponda allo studentId inserito. Una volta trovato, verrà restituito il record dello studente. In parole povere, il comando dice "vai a cercare questo utente e dammi i suoi dati".

Il codice potrebbe assomigliare a questo:

studentId = getRequestString("studentId");
lookupStudent  = "SELECT * FROM students WHERE studentId = " + studentId
   

Se uno studente inserisce un ID studente di 117 all'interno di un modulo di pagina Web con l'etichetta "Inserisci il tuo ID studente"

campo del modulo normale

la query SQL risultante sarà simile a:

SELECT * FROM students WHERE studentId = 117;

Questo comando restituirà il record per lo studente specifico con lo studentId, che è ciò che lo sviluppatore che ha scritto l'API si aspetta che accada.

Query SQL injection:

In questo esempio, un autore di un attacco inserisce invece un comando SQL o una logica condizionale nel campo di input, inserendo un numero per l'ID studente come riportato:

campo del modulo di esempio di SQL injection

Laddove normalmente la query cercherebbe l'ID corrispondente nella tabella del database, ora cerca un ID o verifica se 1 è uguale a 1. Come ci si potrebbe aspettare, l'affermazione è sempre vera per ogni studente nella colonna e, di conseguenza, il database restituirà tutti i dati dalla tabella degli studenti all'autore dell'attacco che esegue la query.

SELECT * FROM students WHERE studentId = 117 OR 1=1;
Infografica di SQL injection

SQLi funziona prendendo di mira un'API vulnerabile. API in questo caso è l'interfaccia software attraverso la quale un server riceve e risponde alle richieste.

Esistono strumenti comunemente utilizzati che consentono a un malintenzionato di cercare automaticamente moduli in un sito Web e quindi tentare di immettere varie query SQL che potrebbero generare una risposta che gli sviluppatori del software del sito Web non avevano previsto per sfruttare il database.

L'SQL injection è facile da implementare e, cosa interessante, anche abbastanza facile da prevenire, se si adottano le giuste pratiche di sviluppo. La realtà è più confusa, poiché scadenze ravvicinate, sviluppatori inesperti e codice obsoleto spesso comportano una qualità del codice e pratiche di sicurezza variabili. Un singolo campo vulnerabile in un modulo o in un endpoint API di un sito Web che ha accesso a un database può essere sufficiente per esporre una vulnerabilità.

Come viene prevenuto un attacco di SQL injection?

Esistono diversi metodi per ridurre il rischio di una violazione dei dati dovuta all'SQL injection. Come best practice, si dovrebbero utilizzare diverse strategie. Esaminiamo alcune delle implementazioni più comuni:

  • Uso di istruzioni preparate (con query parametrizzate): questo metodo di sanificazione degli input del database obbliga gli sviluppatori a definire prima tutto il codice SQL e poi a passare solo parametri specifici alla query SQL; ai dati immessi viene esplicitamente assegnato un ambito limitato oltre il quale non è possibile espandersi. Ciò consente al database di distinguere tra i dati immessi e il codice da eseguire, indipendentemente dal tipo di dati forniti nel campo di input. A questo scopo, vengono comunemente utilizzate alcune librerie ORM (object-relational mapping), poiché alcune versioni di queste puliscono automaticamente gli input del database.
  • Escape di tutti gli input forniti dall'utente: quando si scrive in SQL, caratteri o parole specifici hanno un significato particolare. Ad esempio, il carattere "*" significa "qualsiasi" e la parola "OR" è una condizione. Per evitare che gli utenti inseriscano accidentalmente o intenzionalmente questi caratteri in una richiesta API al database, è possibile eseguire l'escape dell'input fornito dall'utente. L'escape di un carattere è il modo per indicare al database di non analizzarlo come un comando o una condizione, ma di trattarlo come un input letterale.
  • Utilizzo di stored procedure: sebbene non siano di per sé una solida strategia di sicurezza, le stored procedure possono aiutare a limitare il rischio associato all'SQL injection. Limitando opportunamente le autorizzazioni dell'account del database che esegue query SQL, anche il codice applicativo non robusto che è vulnerabile all'SQL injection non avrà le autorizzazioni necessarie per manipolare tabelle di database non correlate. Le stored procedure possono anche controllare il tipo di parametri di input, impedendo l'immissione di dati che violano il tipo che il campo è progettato per ricevere. Nei casi in cui le query statiche non sono sufficienti, in genere è opportuno evitare le stored procedure.
  • Applicare il privilegio minimo: come regola generale, in tutti i casi in cui un sito Web deve utilizzare l'SQL dinamico, è importante ridurre l'esposizione all'SQL injection limitando le autorizzazioni all'ambito più ristretto necessario per eseguire la query pertinente. Nella sua forma più ovvia, ciò significa che un account amministrativo non dovrebbe in alcun caso eseguire comandi SQL a seguito di una chiamata API da una richiesta non autorizzata. Sebbene le procedure memorizzate siano utilizzate al meglio per le query statiche, l'applicazione del privilegio minimo può aiutare a ridurre i rischi delle query SQL dinamiche.

Cos'è un attacco SQL injection composto?

Per aggirare le misure di sicurezza, gli aggressori più abili a volte implementano attacchi multi-vettore contro un sito Web mirato. Anche se un singolo attacco può essere mitigato, può diventare il centro dell'attenzione degli amministratori di database e dei team di sicurezza informatica. Gli attacchi DDoS, il l'hijack del DNS e altri metodi di interruzione vengono talvolta utilizzati come diversivo per implementare attacchi di SQL injection su vasta scala. Di conseguenza, una strategia completa di mitigazione delle minacce fornisce la più ampia gamma di protezione. Il firewall per applicazioni Web, la mitigazione degli attacchi DDoS e la sicurezza DNS di Cloudflare costituiscono gli elementi fondamentali di una strategia di sicurezza olistica.