Colorful code scrolls across a dark background
Foto di Peaky Frames su Unsplash

Vulnerabilità & CVE

SQL injection: cos'è e come proteggere database e applicazioni web

15 October 2026 2 min lettura

Un modulo di login, un campo di ricerca o una pagina che mostra i dettagli di un ordine possono sembrare funzionalità del tutto innocue. Eppure, se l'applicazione costruisce le query al database in modo scorretto, questi punti possono diventare la porta d'ingresso per una delle vulnerabilità più conosciute della sicurezza informatica: la SQL injection.

Il problema si verifica quando dati controllati dall'utente vengono interpretati come parte del comando SQL anziché essere trattati esclusivamente come valori.

Le conseguenze possono essere serie: accesso non autorizzato a informazioni, modifica o cancellazione di dati e, in alcune condizioni, ulteriori compromissioni dell'applicazione.

Vediamo come funziona una SQL injection, quali errori la rendono possibile e quali misure adottare per prevenirla, soprattutto nelle applicazioni PHP e MariaDB.

Che cos'è una SQL injection?

SQL è il linguaggio utilizzato da molti database relazionali per interrogare e modificare le informazioni.

Un'applicazione può utilizzare SQL per verificare le credenziali di un utente, recuperare prodotti, mostrare ordini o aggiornare le impostazioni di un account.

Una SQL injection si verifica quando l'applicazione inserisce dati non attendibili all'interno di una query in modo da modificarne la struttura o la logica.

Il problema non è che un utente possa digitare caratteri speciali. Il problema è che il software non separa correttamente i dati dal comando che il database deve eseguire.

Un esempio semplice

Immaginiamo una pagina PHP che cerca un prodotto per nome. Un'implementazione poco sicura potrebbe costruire la query concatenando direttamente il valore ricevuto:

<?php

$nome = $_GET['nome'];

$sql = "SELECT * FROM prodotti WHERE nome = '$nome'";

In questo esempio, il valore proveniente dalla richiesta viene inserito direttamente nella stringa SQL.

Se il dato contiene caratteri che modificano la sintassi della query, il risultato potrebbe non corrispondere più all'operazione prevista dallo sviluppatore.

Non è necessario che un campo contenga codice PHP o JavaScript: la vulnerabilità riguarda il modo in cui il database interpreta la query.

La regola fondamentale è semplice: i dati forniti dall'utente non devono poter modificare la struttura della query SQL.

Che cosa può provocare una SQL injection?

L'impatto dipende dai privilegi dell'account utilizzato dall'applicazione, dalla struttura del database e dal tipo di query vulnerabile.

1. Lettura di informazioni riservate

Una query vulnerabile potrebbe consentire di recuperare dati che normalmente dovrebbero essere accessibili soltanto attraverso determinate funzioni dell'applicazione.

In base al contesto, potrebbero essere coinvolti profili, ordini, informazioni commerciali o altri dati personali.

2. Aggiramento dei controlli di accesso

Se una query viene utilizzata per verificare le credenziali o determinare l'identità di un utente, un errore nella sua costruzione potrebbe alterare la logica del controllo.

L'autenticazione non dovrebbe mai dipendere da query costruite concatenando direttamente input non attendibili.

3. Modifica o cancellazione dei dati

In determinate condizioni, una vulnerabilità può consentire operazioni di scrittura non previste.

Il rischio è maggiore quando l'account del database dispone di permessi eccessivi o quando l'applicazione esegue query che modificano informazioni importanti.

4. Esposizione di dettagli interni

Gli errori del database restituiti direttamente al client possono rivelare nomi di tabelle, colonne, percorsi o informazioni sulla tecnologia utilizzata.

Questi dettagli non sono necessariamente sufficienti per compromettere un sistema, ma possono facilitare l'analisi di una vulnerabilità.

5. Ulteriori conseguenze sull'infrastruttura

In alcune configurazioni, determinate funzionalità del database possono interagire con il filesystem o con altre risorse del sistema. Questi scenari dipendono strettamente dal motore utilizzato, dai privilegi concessi e dalla configurazione.

Non è corretto presumere che ogni SQL injection consenta di eseguire comandi sul server: l'impatto deve essere valutato nel contesto specifico.

Come prevenire la SQL injection in PHP

La difesa principale consiste nell'utilizzare query parametrizzate, che separano la struttura SQL dai valori forniti dall'utente.

Con PDO, per esempio, è possibile scrivere:

<?php

$pdo = new PDO(
    'mysql:host=localhost;dbname=app;charset=utf8mb4',
    $dbUser,
    $dbPassword,
    [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_EMULATE_PREPARES => false,
    ]
);

$stmt = $pdo->prepare(
    'SELECT id, nome, prezzo
     FROM prodotti
     WHERE nome = :nome'
);

$stmt->execute([
    'nome' => $_GET['nome'] ?? '',
]);

$prodotti = $stmt->fetchAll(PDO::FETCH_ASSOC);

In questo esempio, il valore di nome viene passato come parametro e non inserito direttamente nella struttura della query.

Le query preparate sono una difesa fondamentale contro la SQL injection nei valori, ma non risolvono automaticamente ogni problema legato alla costruzione dinamica delle query.

È inoltre importante gestire correttamente gli errori, verificare gli input secondo le esigenze dell'applicazione e assegnare al database soltanto i privilegi necessari.

Attenzione ai nomi di colonne e alle parti dinamiche

I parametri SQL sono progettati per rappresentare valori, non per sostituire liberamente nomi di tabelle, colonne o parole chiave.

Immaginiamo che una pagina permetta di ordinare i risultati per prezzo o nome. Non è corretto inserire direttamente un parametro ricevuto dal client nella posizione del nome della colonna.

La soluzione consiste nel definire una lista chiusa di opzioni consentite e utilizzare esclusivamente i valori previsti dal codice.

Per esempio:

<?php

$ordinamenti = [
    'nome' => 'nome',
    'prezzo' => 'prezzo',
];

$richiesto = $_GET['ordine'] ?? 'nome';
$colonna = $ordinamenti[$richiesto] ?? 'nome';

$sql = "SELECT id, nome, prezzo
        FROM prodotti
        ORDER BY $colonna";

In questo caso, il valore interpolato proviene da una lista definita dall'applicazione e non direttamente dall'input dell'utente.

La stessa attenzione è necessaria per filtri dinamici, nomi di colonne, direzioni di ordinamento e altre parti della query che non possono essere parametrizzate come normali valori.

Perché l'escaping da solo non è la soluzione migliore

Una pratica storica consiste nell'utilizzare funzioni di escaping per modificare i caratteri speciali prima di inserirli nelle query.

L'escaping può avere un ruolo in alcuni contesti specifici, ma è facile applicarlo in modo incompleto o con regole incompatibili con la connessione al database.

Per questo motivo, quando sono disponibili, le query parametrizzate rappresentano normalmente la scelta preferibile.

È altrettanto importante evitare di considerare la validazione dell'input una sostituzione delle query preparate. Un campo che accetta soltanto numeri può comunque essere gestito in modo scorretto altrove nell'applicazione.

La strategia corretta combina query parametrizzate, validazione coerente con il dato atteso e gestione prudente degli errori.

Il principio del minimo privilegio nel database

Anche un'applicazione ben sviluppata può contenere bug. Per questo è utile ridurre i danni potenziali nel caso in cui una vulnerabilità venga sfruttata.

L'account utilizzato dall'applicazione dovrebbe avere soltanto i permessi necessari alle sue funzioni.

Per esempio, un servizio che deve leggere un catalogo non dovrebbe necessariamente poter modificare ogni tabella del database o gestire gli utenti del database stesso.

Separare i privilegi per attività differenti, quando possibile, limita le conseguenze di un errore applicativo.

È inoltre opportuno evitare di utilizzare account amministrativi del database per le normali richieste del sito.

Come verificare la sicurezza di un'applicazione

Una revisione efficace dovrebbe includere tutti i punti in cui dati esterni vengono utilizzati per costruire query:

  • [ ] Form di login e registrazione.
  • [ ] Campi di ricerca e filtri.
  • [ ] Parametri negli URL.
  • [ ] Endpoint delle API.
  • [ ] Funzioni di ordinamento e paginazione.
  • [ ] Importazioni di file e processi automatici.
  • [ ] Query utilizzate nei pannelli amministrativi.
  • [ ] Componenti e plugin di terze parti.

Durante i test autorizzati, è importante utilizzare un ambiente controllato e verificare che input inattesi non alterino la logica delle query.

Anche i log e i messaggi di errore meritano attenzione: i dettagli tecnici dovrebbero essere registrati in modo sicuro per chi gestisce il sistema, senza essere esposti inutilmente agli utenti.

Gli strumenti automatici possono aiutare a individuare alcuni segnali, ma non sostituiscono la revisione del codice e la verifica dei comportamenti applicativi.

SQL injection e siti WordPress

Anche WordPress e i suoi plugin utilizzano database. Un sito può quindi essere esposto a SQL injection quando un tema o un plugin costruisce query in modo non sicuro.

Gli sviluppatori che utilizzano $wpdb dovrebbero preferire i meccanismi di preparazione delle query previsti da WordPress, come $wpdb->prepare(), applicandoli correttamente ai valori.

È importante ricordare che la sicurezza di un sito non dipende soltanto dal core di WordPress: codice personalizzato, plugin e temi devono essere mantenuti e verificati con la stessa attenzione.

Aggiornare i componenti riduce l'esposizione a vulnerabilità note, ma non corregge automaticamente errori presenti nel codice personalizzato.

Conclusione

La SQL injection è una vulnerabilità prevenibile nella maggior parte dei casi attraverso una corretta progettazione delle query, la separazione tra codice e dati e l'uso di privilegi limitati per il database.

Con MiHakero puoi analizzare domini, applicazioni web, API e servizi pubblici per individuare esposizioni e problemi rilevabili dall'esterno. Per confermare o escludere una SQL injection è spesso necessario integrare l'analisi esterna con test applicativi autorizzati e una revisione del codice che interagisce con il database.

Testa la sicurezza del tuo sito

Avvia una scansione gratuita e scopri cosa la tua azienda espone online.

Prova Gratis

Prova MiHakero sulla tua azienda

Avvia una scansione gratuita e scopri cosa la tua azienda espone online.