Proteggere il database dagli attacchi SQL Injection

Perché questo articolo è utile
Questo articolo spiega in modo pratico come avvengono le SQL injection e mostra misure concrete per prevenirle. È pensato per sviluppatori, amministratori di database e team di sicurezza che vogliono ridurre il rischio e prepararsi a rispondere a un incidente.
Cos’è una SQL injection (breve definizione)
Una SQL injection è un attacco in cui un aggressore inserisce codice SQL malevolo in un campo di input, inducendo il database a eseguire comandi non previsti. In una frase: dati malevoli trasformati in codice.
Come avviene un attacco SQL injection
Un’applicazione compone una query SQL includendo direttamente i dati forniti dall’utente. Se quei dati non vengono filtrati o separati dalla struttura della query, un’aggiunta malevola può cambiare la logica della query.
Esempio concettuale: un campo password che contiene: ‘ OR ‘1’=’1 Se la stringa viene concatenata senza protezioni, la condizione diventa sempre vera e l’attaccante ottiene accesso.
Esempio vulnerabile in PHP
Di seguito un semplice esempio che illustra il problema. Non eseguire codice non sicuro in produzione.
Se l’utente passa username=computer e password=comp123, la query normale cercherà il record corrispondente. Ma se l’attaccante invia password = ‘ OR ‘a’=’a, la query si trasforma e la condizione può risultare sempre vera, consentendo l’accesso senza credenziali valide.
Tipi comuni di SQL injection (panoramica)
- Error-based: l’attaccante sfrutta messaggi di errore dettagliati.
- Union-based: l’attaccante unisce risultati arbitrari.
- Boolean-based blind: inferenze tramite risposte true/false.
- Time-based blind: inferenze tramite ritardi nelle risposte.
Important: non tutti gli attacchi restituiscono dati visibili; alcuni sono “blind” e richiedono tecniche diverse.
Strategie principali per proteggere il database
Di seguito le tecniche più efficaci, con esempi pratici e raccomandazioni.
1. Usare query parametrizzate (prepared statements)
Le query parametrizzate separano i dati dalla struttura SQL. I placeholder non possono modificare la sintassi della query.
Esempio con PDO (PHP) — consigliato:
PDO::ERRMODE_EXCEPTION,
]);
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :username AND user_password = :password');
$stmt->execute([':username' => $_POST['username'], ':password' => $_POST['password']]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
?>
Esempio con MySQLi (prepared statements):
prepare('SELECT * FROM users WHERE username = ? AND user_password = ?');
$stmt->bind_param('ss', $_POST['username'], $_POST['password']);
$stmt->execute();
$result = $stmt->get_result();
?>
Quando possibile, preferisci i prepared statements a ogni forma di escaping manuale.
2. Sanitizzare e validare gli input (lato server)
Sanitizzazione: rimuovere o neutralizzare caratteri potenzialmente pericolosi. Validazione: confermare che il dato rispetti formato, lunghezza e tipo attesi.
Regole pratiche:
- Applica whitelist dei caratteri per identificatori, numeri, email.
- Rimuovi spazi superflui, newline e caratteri di controllo.
- Limita la lunghezza massima dei campi.
- Fallisci sicuro: rifiuta input che non rispettano le regole.
Esempio di sanitizzazione con mysqli_real_escape_string (se non si usano prepared statements):
Nota: l’escaping è una misura utile ma meno sicura e più soggetta a errori rispetto alle query parametrizzate.
3. Principio del privilegio minimo (restrict database permissions)
Non usare account con privilegi elevati per le connessioni applicative. Concedi solo ciò che serve (SELECT/INSERT/UPDATE/DELETE specifici).
Esempio su Microsoft SQL Server:
deny select on sys.tables to sqldatabasepermit;
deny select on sys.packages to sqldatabasepermit;
deny select on sys.sysobjects to sqldatabasepermit;
Altre raccomandazioni:
- Separare account di lettura e scrittura se possibile.
- Non usare account dbo/sysadmin dalle applicazioni.
- Audita i permessi e rimuovi accessi inutilizzati.
4. Non divulgare messaggi di errore dettagliati
Mostra all’utente messaggi generici. Logga i dettagli a parte in un sistema protetto (SIEM). I messaggi di errore possono aiutare un attaccante a costruire payload efficaci.
5. Web Application Firewall (WAF) e regole layered
Il WAF può bloccare payload noti e pattern sospetti. Consideralo come parte di una difesa a più livelli, non come unica protezione.
6. Monitoraggio, logging e alerting
- Logga query fallite e tentativi di input sospetti.
- Definisci alert per pattern ripetuti (es. molte richieste con caratteri speciali).
- Conserva i log in modo immutabile per analisi post-incidente.
7. Test e verifica continua
Integra scanner di vulnerabilità, test di penetrazione e test automatizzati nel CI/CD.
Esempi di test:
- Test che inviano payload di SQL injection noti e verificano che la risposta sia gestita.
- Test di regressione per sanitizzazione e validazione.
Quando le contromisure falliscono (controesempi e limiti)
- Codice legacy che usa concatenazione di stringhe senza refactor.
- Stored procedure che generano SQL dinamico senza sanificazione.
- Privilegi eccessivi: anche query parametrizzate non evitano perdita di dati se l’account ha permessi elevati.
- Configurazioni errate del database o errori di deploy che attivano debug e messaggi di errore in produzione.
Importante: la difesa migliore combina più misure.
Mini-metodologia: approccio in quattro fasi
- Scoprire: esegui scansioni e mapping degli input esposti.
- Proteggere: applica query parametrizzate e validazione.
- Limitare: riduci i privilegi e segmenta accessi.
- Verificare: test automatici e pen-test periodici.
Playbook operativo (passi rapidi per sviluppatori e DBA)
- Sviluppatore: sostituisci concatenazioni con prepared statements; aggiungi validazione lato server; scrivi test che attestino il comportamento.
- DBA: verifica gli account applicativi e riduci i permessi; abilita logging e auditing.
- Team di sicurezza: configurare WAF, eseguire scansioni regolari e pen-test.
Incident runbook: cosa fare in caso di sospetta SQL injection
- Isolare l’applicazione vulnerabile (se possibile, rimuovere l’accesso pubblico temporaneamente).
- Abilitare raccolta log dettagliati e snapshot del database (solo in lettura).
- Identificare query eseguite e punti di ingresso.
- Ripristinare da backup coerenti se i dati sono compromessi.
- Rifattorizzare il codice colpevole e deployare patch.
- Comunicare l’incidente secondo le policy aziendali e, se necessario, agli enti regolatori.
Criteri di accettazione per una funzione di login sicura
- Tutte le query verso l’auth layer usano prepared statements.
- Input utente validati e limitati per lunghezza e formato.
- L’account DB usato da login ha permessi minimi.
- Test automatici rilevano injection note e falliscono se ci sono regressioni.
Checklist per ruolo
- Sviluppatore:
- Usare prepared statements sempre.
- Validare dati lato server.
- Scrivere test unitari e di integrazione.
- DBA:
- Controllare e rimuovere permessi superflui.
- Abilitare auditing delle query sensibili.
- Sicurezza:
- Eseguire scan e pen-test periodici.
- Monitorare log e configurare alert.
Privacy e conformità (GDPR e dati personali)
Se il database contiene dati personali, una violazione può avere impatti legali. Azioni raccomandate:
- Limitare l’accesso ai dati personali solo a chi ne ha bisogno.
- Tenere log di accesso e modificarli per la durata richiesta.
- Preparare comunicazioni per gli interessati in caso di esposizione di dati sensibili.
Nota: consultare il team legale per obblighi di notifica specifici.
Test cases / acceptance criteria (campione)
- Input: username contiene “‘ OR ‘1’=’1”; risultato atteso: accesso negato e log dell’evento.
- Input: email con caratteri non validi; risultato atteso: input rifiutato con errore di validazione.
- Load test: il WAF non introduce latenza significativa sotto carico normale.
Breve glossario (una riga ciascuno)
- Prepared statement: query SQL con segnaposto che separa dati e codice.
- Sanitizzazione: rimozione o modifica di caratteri per ridurre rischi.
- Whitelist: elenco consentito di caratteri o pattern.
- WAF: Web Application Firewall, filtro tra client e applicazione.
Valutazione impatto × sforzo (orientativa)
- Prepared statements: impatto alto, sforzo medio (modifica del codice sorgente).
- Validazione lato server: impatto medio, sforzo basso-medio.
- Riduzione permessi DB: impatto alto, sforzo basso.
- WAF: impatto medio, sforzo medio.
Riepilogo finale
La SQL injection rimane una delle vulnerabilità più sfruttate. La difesa efficace combina: query parametrizzate, validazione/sanitizzazione lato server, privilegi minimi, logging/monitoraggio e test continui. Applica la metodologia in quattro fasi e mantieni playbook e runbook pronti per rispondere a incidenti.
Note importanti:
- Non affidarti a una sola misura di difesa.
- Aggiorna regole di sicurezza e test regolarmente.
Materiali simili
Installare Asterisk: guida per il primo PBX

Microsoft Store non funziona: guida completa di riparazione

Scansione sicurezza WordPress: guida completa

RSS da thread di forum con Blogger e email
Installare OCS Inventory NG 2 su CentOS 5.5
