SQL Injection 101: cos'è SQLi e come prevenire gli attacchi
06 agosto 2022 - sicurezza
Che cos'è l'iniezione SQL
L'iniezione SQL (SQLi) è un tipo di attacco che consente ai criminali di eseguire istruzioni SQL dannose contro applicazioni web vulnerabili. Gli aggressori possono accedere a dati sensibili, come informazioni sui clienti, dati personali, segreti commerciali e altro ancora, aggirando le misure di sicurezza delle applicazioni. Qui parleremo dell'iniezione SQL, di come funziona e di come si possono prevenire gli attacchi.
Gli attacchi di tipo SQL injection possono verificarsi su qualsiasi sito web che utilizzi un database SQL. Questo tipo di attacco consente ai malintenzionati di accedere ai vostri dati essenziali. Possono vedere informazioni sui consumatori, dati personali, segreti commerciali e proprietà intellettuale. Secondo OWASP, si tratta di uno dei tipi più gravi di attacchi alle applicazioni web.
Tipi di SQL Injection
SQLi in banda
L'iniezione SQL in-band è un attacco in cui l'aggressore utilizza lo stesso canale per inviare e ricevere le query. In-band significa che la risposta è ottenuta utilizzando lo stesso mezzo di comunicazione. L'obiettivo dell'attaccante è ottenere immediatamente la risposta in un browser web, se possibile eseguendo l'attacco manualmente con un browser web.
Esempio di iniezione SQL in-band
Il modo più comune per un aggressore di effettuare un'iniezione SQL in-band è modificare la richiesta in modo da poter vedere le informazioni personali dell'utente corrente. Ciò può avvenire modificando il valore inviato come parte della richiesta. Ad esempio, se l'istruzione doveva visualizzare il nome dell'utente, l'aggressore può modificarla in modo che venga visualizzato il suo nome.
SELEZIONARE * DA UTENTI DOVE ID_utente È LIKE 'utente_corrente'
L'SQLi basato su errori e l'SQLi basato su unioni sono le due forme più frequenti di SQL injection in-band.
SQL basato sugli errori
Una tecnica di SQLi basata su errori è un approccio di SQL injection in-band che sfrutta i messaggi di errore del server di database per scoprire l'architettura del database. L'iniezione SQL basata su errori è il tipo più comune di iniezione SQL in-band.
Esempio di SQLi basato su errori:
Se un utente malintenzionato tenta di accedere con le seguenti credenziali:
nome utente: ' OPPURE 'a'='apassword: qualsiasi cosa
Il database restituirà un errore perché l'istruzione è sintatticamente scorretta. Il messaggio di errore rivelerà informazioni sul database, che l'attaccante potrà utilizzare a suo vantaggio.
SQLi basato sulle unioni:
L'iniezione SQL in-band è un modo per ottenere informazioni da un sito Web utilizzando l'operatore UNION per combinare i risultati di due o più istruzioni SELECT.
Iniezione SQL cieca
La Blind SQL injection è un attacco in cui l'aggressore tenta di ottenere risposte dal database ponendo domande che daranno come risultato una risposta vera o falsa. L'attaccante utilizza i messaggi di errore per vedere se l'applicazione risponde in modo diverso quando viene utilizzato un codice specifico.
Quando un hacker utilizza l'iniezione SQL, l'applicazione Web potrebbe visualizzare messaggi di avviso critici per il database, indicando che la sintassi della query SQL non è corretta. L'iniezione SQL cieca funziona come l'iniezione SQL tradizionale, tranne che per il modo in cui i dati vengono ottenuti dal database. Se un database non contiene informazioni sufficienti per essere sfruttato da un aggressore, quest'ultimo deve porre una serie di domande per ottenere i dati.
La Blind SQL injection si divide in Blind-Boolean-based SQLi e Blind-Time-based SQLi.
SQL cieco basato su booleani
L'iniezione SQL cieca basata su booleani è un attacco in cui l'aggressore cerca di ottenere risposte dal database ponendo domande che daranno come risultato una risposta vera o falsa. L'attaccante utilizza i messaggi di errore per vedere se l'applicazione risponde in modo diverso quando viene utilizzato un codice specifico.
Esempio di Blind SQLi basato su booleani:
Se un utente malintenzionato vuole scoprire il tipo di database, utilizzerà la seguente istruzione:
SELECT * FROM users WHERE user_id LIKE 'current_user' and database() like '%type%'
Se il database è MySQL, l'output sarà simile a questo:
Si è verificato un errore nella sintassi SQL; controllare il manuale corrispondente alla versione del server MySQL per conoscere la sintassi corretta da utilizzare vicino a 'and database() like '%type%' alla riga
Iniezione SQL cieca basata sul tempo
Un attacco Blind basato sul tempo avviene quando un comando SQL viene inviato al server con un codice che causa un'esecuzione più lenta delle query.
Gli attacchi ciechi basati sul tempo consentono agli aggressori di estrarre i dati in base al tempo di accesso. Un attacco di questo tipo è noto come attacco a iniezione cieca o inferenziale. Si tratta di un tipo di attacco in cui non vi è alcun flusso di dati tra l'attaccante e il database, ma poiché non vi è alcuna risposta, è noto anche come attacco a iniezione cieca.
Il tempo di risposta indica se la risposta è corretta o errata. Se la risposta è negativa, l'intruso effettua un'altra richiesta. Questa tecnica di attacco è lenta perché l'hacker deve esaminare ogni carattere singolarmente, soprattutto quando si attaccano database di grandi dimensioni.
Esempio di SQL cieco
In questo esempio, l'attaccante cerca di determinare se l'utente con id=999 esiste nel database. Per farlo, utilizza la seguente istruzione:
IF(SUBSTRING((SELECT password FROM users WHERE user_id=999),0, LEN('secret'))='secret', SLEEP(30), 'false')
Se l'utente con id 999 esiste nel database e la sua password è segreta, l'applicazione rimane in attesa per 30 secondi. L'applicazione restituirà false se l'utente non esiste nel database.
SQLi fuori banda
Chi vuole rubare i dati può inviare codice SQL a un server di database in un modo che non fa parte della normale comunicazione tra il server e gli altri computer. Ciò può avvenire inviando informazioni al server tramite richieste DNS o HTTP.
La risposta dell'applicazione non sarà influenzata dal fatto che vengano restituiti o meno dei dati, dal fatto che ci sia o meno un problema con il database o dal tempo necessario per eseguire la query. Le interazioni fuori banda possono essere utilizzate nelle interazioni di rete per attivare eventi a piacere. A seconda di una condizione iniettata, questi eventi possono essere attivati in modo condizionato per acquisire informazioni un bit alla volta.
I dati possono trapelare anche attraverso diversi protocolli di rete dalle interazioni di rete. L'immagine rappresenta la richiesta inviata dall'applicazione web al database dell'applicazione.
Esempio di SQLi fuori banda
In questo esempio, l'attaccante cerca di determinare se un utente specifico esiste nel database. Per farlo, utilizza la seguente istruzione:
SELECT user_id FROM users WHERE username='$username' AND password='$password' LIMIT 0,0 UNION SELECT NULL,'' INTO OUTFILE '/var/opt/database/$filename.php'; --
L'applicazione restituirà l'ID utente se l'utente esiste nel database. Se l'utente non esiste nel database, l'applicazione crea un file contenente codice PHP che può essere utilizzato per eseguire comandi di sistema. L'aggressore può quindi utilizzare questo file per eseguire comandi sul server.
Come prevenire un'iniezione SQL
Il modo migliore per proteggersi dagli attacchi di SQL injection è utilizzare la convalida dell'input, le istruzioni preparate e le query parametrizzate. Il codice non deve mai utilizzare direttamente l'input dell'utente. Gli sviluppatori devono sanificare tutti gli input, invece di limitarsi a quelli dei moduli web, come i moduli di login. Le virgolette singole devono essere eliminate da qualsiasi componente di codice discutibile. È anche una buona idea nascondere i problemi di database sui siti live per evitare di rivelarli inavvertitamente. L'iniezione SQL può fornire informazioni su un sistema di database che gli aggressori possono utilizzare a loro vantaggio.
Se riscontrate un problema con il vostro sito web, dovete metterlo immediatamente offline e contattare il vostro provider di hosting. Questi potrà aiutarvi a determinare se il vostro sito è stato compromesso o meno e quali sono le misure da adottare per risolvere il problema. Nel frattempo, assicuratevi che tutti gli utenti del vostro sito siano a conoscenza del problema e cambino le loro password il prima possibile.
Suggerimenti per evitare le iniezioni SQL
Esistono alcuni modi per evitare le vulnerabilità dell'iniezione SQL nel linguaggio di programmazione e nella configurazione del database. Queste tecniche possono essere utilizzate con la maggior parte dei database, come ad esempio XML. È possibile utilizzare queste tecniche per rendere i database più sicuri.
1) Utilizzo di procedure memorizzate correttamente costruite
I principianti dovrebbero iniziare imparando a creare dichiarazioni con variabili. È più semplice che creare query dinamiche e più facile da capire. Le query parametrizzate sono quelle in cui lo sviluppatore crea tutto il codice SQL e poi fornisce ogni parametro in un secondo momento. Questo metodo consente al database di distinguere tra codice sorgente e informazioni.
I Prepared Statement aiutano a garantire che l'obiettivo di una query non venga modificato, anche se qualcuno cerca di dare istruzioni SQL.
2) Convalida dell'ingresso alla lista dei permessi
Le query SQL utilizzano le variabili bind in luoghi specifici per i dati. Ad esempio, se si usa Python, si usa la variabile %s segnaposto. È possibile utilizzare un'espressione regolare per convalidare l'input dell'utente rispetto all'elenco dei caratteri consentiti in ciascuna variabile di vincolo.
Se si utilizza JavaScript, si può usare il metodo \w per abbinare i caratteri alfanumerici e i caratteri di sottolineatura.
L'elenco dei permessi deve essere il più specifico possibile per evitare falsi positivi.
Ad esempio, se si cerca un numero di telefono statunitense, si utilizza la seguente espressione regolare:
/^\d{11}$/
Questo corrisponde a una stringa di 11 cifre che potrebbe essere un numero di telefono. Se qualcuno tentasse di inviare qualcosa come 'abcdef', non corrisponderebbe e l'input non sarebbe valido.
In questo modo ci si assicura che i dati siano sani e salvi. Se avete bisogno di usare i valori del codice invece dei parametri utente, va bene lo stesso!
Tuttavia, si supponga che i valori dei parametri dell'utente si riferiscano a nomi di tabelle e colonne specifiche. In questo caso, i valori dei parametri devono essere mappati sui nomi delle tabelle e delle colonne corrispondenti, per garantire che l'input dell'utente non validato non venga inserito nella query.
3) Utilizzare le whitelist
Non filtrate l'input dell'utente in base a liste nere di caratteri non validi. È molto più efficace utilizzare elenchi di caratteri validi attesi in campi specifici. In questo modo si fermano gli attacchi di SQL injection prima che inizino.
Ad esempio, se ci si aspetta un numero di telefono, nel campo di immissione sono consentite solo cifre e trattini. Se ci si aspetta un indirizzo e-mail, si devono consentire solo i caratteri validi per un indirizzo e-mail.
4) Utilizzare le piattaforme più aggiornate
PHP non dispone di protezione SQLi nelle piattaforme di sviluppo web più vecchie. Utilizzate l'edizione più aggiornata dell'ambiente di programmazione, del linguaggio e delle tecnologie associate disponibili. In questo esempio, invece di PHP, utilizzare PDO.
5) Eseguire regolarmente una scansione dell'applicazione web
Le iniezioni SQL possono essere molto difficili da individuare. È importante eseguire regolarmente una scansione delle applicazioni web per individuare eventuali vulnerabilità.
6) Applicazione del privilegio minimo
Il principio del minimo privilegio è un concetto di sicurezza che limita gli utenti alla quantità minima di accesso necessaria per svolgere il proprio lavoro. Ciò include la limitazione del numero di account che gli utenti hanno e dei privilegi che questi account hanno.
Least Restriction on Functionality (LRF) è la pratica e il concetto di limitare i diritti degli utenti, gli account e i processi informatici solo alle risorse necessarie per svolgere compiti basilari e accettabili. In questo modo si contribuisce a mantenere livelli minimi di diritti o autorizzazioni per gli utenti, che sono fondamentali per consentire alle persone di svolgere efficacemente il proprio lavoro.
Il principio del minimo privilegio è un principio di sicurezza che prevede che le applicazioni, i sistemi e i gadget abbiano solo le autorizzazioni necessarie per svolgere un compito specifico. In questo modo, l'impatto sarà limitato se qualcuno riesce a sfruttare una vulnerabilità e a fare danni. Ciò è in contrasto con l'assegnazione agli utenti di più permessi di quelli necessari, che aumentano il rischio di danni significativi in un attacco SQL.
SQL Injection - Domande frequenti
L'iniezione SQL in-band è il tipo più comune di attacco SQL injection. Si verifica quando un aggressore può utilizzare lo stesso canale di comunicazione per fornire il payload e raccogliere i risultati.
La migliore difesa contro le SQL injection consiste nell'utilizzare query parametriche. Questo tipo di query utilizza valori segnaposto per i parametri, che vengono forniti in un secondo momento. Questo metodo consente al database di distinguere tra codice sorgente e informazioni.
L'iniezione SQL può essere rilevata in diversi modi. Un metodo consiste nell'utilizzare un firewall per applicazioni Web (WAF). Un WAF è un componente hardware o software che si interpone tra un'applicazione web e Internet. Ispeziona il traffico alla ricerca di attività dannose e può bloccare gli attacchi di SQL injection.
L'iniezione SQL di secondo ordine si verifica quando un aggressore può iniettare un payload che viene memorizzato dall'applicazione Web e poi eseguito successivamente. Questo tipo di attacco è più difficile da realizzare perché l'aggressore deve avere un modo per innescare l'esecuzione del payload memorizzato.
La Blind SQL injection è un attacco in cui l'attaccante non vede direttamente i risultati del suo payload. Deve invece utilizzare dichiarazioni vere o false per dedurre informazioni dal database. Questo tipo di attacco è più difficile da eseguire, ma può essere altrettanto pericoloso di altri tipi di SQL injection.
Una stacked query è un tipo di SQL injection in cui l'attaccante utilizza più query per estrarre informazioni dal database. Questo tipo di attacco è più difficile da eseguire, ma può essere molto pericoloso se ha successo.
L'iniezione SQL basata su errori è un attacco in cui l'aggressore utilizza gli errori del database per dedurre informazioni dal database. Questo attacco è più difficile da eseguire, ma può essere molto pericoloso se ha successo.
sicurezza
admin è una redattrice senior per Government Technology. In precedenza ha scritto per PYMNTS e The Bay State Banner e ha conseguito una laurea in scrittura creativa alla Carnegie Mellon. Risiede fuori Boston.