Guida alle tecnologie

Proteggere il database dagli attacchi SQL Injection

7 min read Sicurezza Aggiornato 27 Sep 2025
Protezione da SQL Injection nei database
Protezione da SQL Injection nei database

Rappresentazione grafica del rischio di SQL injection su un database

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

  1. Scoprire: esegui scansioni e mapping degli input esposti.
  2. Proteggere: applica query parametrizzate e validazione.
  3. Limitare: riduci i privilegi e segmenta accessi.
  4. 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

  1. Isolare l’applicazione vulnerabile (se possibile, rimuovere l’accesso pubblico temporaneamente).
  2. Abilitare raccolta log dettagliati e snapshot del database (solo in lettura).
  3. Identificare query eseguite e punti di ingresso.
  4. Ripristinare da backup coerenti se i dati sono compromessi.
  5. Rifattorizzare il codice colpevole e deployare patch.
  6. 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.
Autore
Redazione

Materiali simili

Installare Asterisk: guida per il primo PBX
Telecomunicazioni

Installare Asterisk: guida per il primo PBX

Microsoft Store non funziona: guida completa di riparazione
Windows

Microsoft Store non funziona: guida completa di riparazione

Scansione sicurezza WordPress: guida completa
Sicurezza web

Scansione sicurezza WordPress: guida completa

RSS da thread di forum con Blogger e email
Guide tecniche

RSS da thread di forum con Blogger e email

Installare OCS Inventory NG 2 su CentOS 5.5
Inventario IT

Installare OCS Inventory NG 2 su CentOS 5.5

Funzione CHAR in Google Sheets: guida pratica
Guide.

Funzione CHAR in Google Sheets: guida pratica