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 iniezione di codice utilizzata per modificare o recuperare dati da database SQL. Inserendo istruzioni SQL specializzate in un campo di input, un utente 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.

DOMANDE FREQUENTI

Che cos'è l'SQL injection (SQLi)?

L'SQL injection è un tipo di attacco informatico in cui gli aggressori inseriscono comandi SQL dannosi nei campi di inserimento. Se i comandi vengono eseguiti, gli aggressori possono manipolare o recuperare informazioni da un database senza autorizzazione. In parole semplici, l'SQL injection si verifica quando gli aggressori inviano codice eseguibile in aree in cui un'applicazione si aspetta dei dati ordinari.

Come funziona un attacco SQL injection?

Gli aggressori inseriscono un comando SQL nel campo di un modulo. Dopo l'invio del modulo, il backend dell'applicazione riceve il comando e lo esegue. Questo genera una risposta o un'azione non prevista dagli sviluppatori dell'applicazione: gli aggressori possono sfruttare l'SQL injection per ottenere informazioni riservate da un database o alterarne il contenuto.

Cosa può accadere se un attacco di SQL injection ha successo?

Un attacco SQL injection riuscito può consentire agli aggressori di falsificare le identità degli utenti, ottenere privilegi da amministratore, manomettere o eliminare dati, recuperare tutti i dati del server o persino ottenere l'accesso di root alla macchina.

Quali sono alcune strategie efficaci per prevenire gli attacchi di SQL injection?

Le strategie di prevenzione dell'SQL injection includono l'uso di prepared statement, la sanificazione dell'input dell'utente, l'implementazione di procedure memorizzate e l'applicazione del principio del minimo privilegio per garantire che vengano concesse solo le autorizzazioni strettamente necessarie.

Cosa sono i prepared statement e come aiutano a prevenire l'SQL injection?

I prepared statement separano il codice SQL dagli input dell'utente mediante la precompilazione del codice SQL. Questo impedisce agli autori degli attacchi di iniettare codice dannoso, poiché il database considera l'input come dati e non come comandi eseguibili.

Perché la sanificazione dell'input utente è importante per prevenire l'SQL injection?

La sanificazione dell'input utente garantisce che i caratteri speciali vengano trattati come testo normale anziché come parte di un comando SQL, riducendo il rischio che l'input dell'utente venga interpretato come un'istruzione eseguibile.

In che modo le procedure memorizzate possono contribuire a ridurre il rischio di SQL injection?

Le procedure memorizzate possono limitare i tipi e l'ambito delle operazioni del database. Se progettate correttamente, limitano le azioni che il codice iniettato può eseguire, sebbene da sole non costituiscano una difesa completa.

Cosa significa applicare il principio del privilegio minimo nel contesto della prevenzione degli attacchi SQL injection?

Applicare il principio del minimo privilegio significa limitare le autorizzazioni degli account di database solo a ciò che è strettamente necessario. In questo modo si riducono al minimo i potenziali danni nel caso in cui un utente malintenzionato sfrutti una vulnerabilità di SQL injection.