L’SQL injection è una tecnica di attacco in cui un malintenzionato inserisce (inserisce) codice SQL arbitrario in una query SQL tramite l’input dell’utente, con l’obiettivo di manipolare il database. Questo tipo di attacco può portare a risultati devastanti, come la visualizzazione di dati non autorizzati, la modifica o la cancellazione di dati, o addirittura il controllo totale del server di database. L’SQL injection è possibile quando un’applicazione non valida correttamente l’input dell’utente, permettendo l’esecuzione di comandi SQL indesiderati.
Per esempio, se in un’applicazione PHP si ha una query che cerca un utente nel database tramite un nome utente fornito dall’utente stesso:
```
$username = $_GET[‘username’];
$query = “SELECT * FROM users WHERE username = ‘$username’”;
$result = mysqli_query($conn, $query);
```
Se un utente malintenzionato inserisce `admin’ —` come parametro `username`, la query SQL diventa:
```
SELECT * FROM users WHERE username = ‘admin’ —‘
```
Il `—` è un commento in SQL che fa sì che il resto della query venga ignorato. Questo significa che tutte le password vengono ignorate e l’attaccante ottiene accesso al record dell’amministratore.
Uno dei metodi più efficaci per prevenire l’SQL injection è utilizzare query parametrizzate (o prepared statements), che permettono di separare il codice SQL dai dati. Questo metodo è supportato da molte librerie di database, come PDO (PHP Data Objects) per PHP.
Esempio con PDO:
```
// Connessione al database con PDO
$dsn = ‘mysql:host=localhost;dbname=testdb’;
$username = ‘root’;
$password = ‘’;
$options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
$pdo = new PDO;
// Utilizzo di una query parametrizzata
$stmt = $pdo->prepare(‘SELECT * FROM users WHERE username = :username’);
$stmt->bindParam(‘:username’, $_GET[‘username’]);
$stmt->execute();
$results = $stmt->fetchAll();
```
Un’altra tecnica è utilizzare funzioni di escaping come `mysqli_real_escape_string()` che assicurano che i caratteri speciali nell’input dell’utente siano trattati come letterali anziché comandi.
```
// Connessione al database
$conn = new mysqli($servername, $username, $password, $dbname);
$username = $conn->real_escape_string($_GET[‘username’]);
$query = “SELECT * FROM users WHERE username = ‘$username’”;
$result = $conn->query($query);
```
Gli ORM, come Eloquent in Laravel o Doctrine in Symfony, offrono un livello di astrazione che rende più difficile comporre query SQL malformate, riducendo così il rischio di SQL injection.
```
// Esempio con Eloquent in Laravel
$user = User::where(‘username’, $username)->first();
```
Dovresti sempre validare e sanificare l’input dell’utente per assicurarti che rispetti i formati attesi.
```
$username = filter_input(INPUT_GET, ‘username’, FILTER_SANITIZE_STRING);
```
L’SQL injection è una vulnerabilità molto pericolosa, ma con le giuste pratiche come l’uso di query parametrizzate, funzioni di escaping, ORM, e la validazione e sanificazione dell’input, è possibile prevenire efficacemente questi attacchi.
1. OWASP (Open Web Application Security Project). [SQL Injection Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html)
2. PHP Manual. [PDO](https://www.php.net/manual/en/book.pdo.php)
3. W3Schools. [PHP and MySQL](https://www.w3schools.com/php/php_mysql_connect.asp)
Adottare queste misure di sicurezza può aiutarti a proteggere la tua applicazione PHP da attacchi SQL injection, garantendo la sicurezza dei dati e del sistema nel suo complesso.