Questo articolo spiega come prevenire l'iniezione di SQL utilizzando le istruzioni preparate in PHP. L'SQL injection è una delle vulnerabilità più comuni nelle applicazioni Web odierne. Le istruzioni preparate utilizzano parametri associati e non combinano variabili con stringhe SQL, rendendo impossibile per un utente malintenzionato modificare l'istruzione SQL.
Le istruzioni preparate combinano la variabile con l'istruzione SQL compilata, in modo che l'SQL e le variabili vengano inviati separatamente. Le variabili vengono quindi interpretate come semplici stringhe e non come parte dell'istruzione SQL. Utilizzando i metodi nei passaggi seguenti, non sarà necessario utilizzare altre tecniche di filtraggio SQL injection come mysql_real_escape_string().
Passi
Parte 1 di 2: Comprensione di SQL Injection
Passaggio 1. SQL Injection è un tipo di vulnerabilità nelle applicazioni che utilizzano un database SQL
La vulnerabilità si verifica quando un input dell'utente viene utilizzato in un'istruzione SQL:
$nome = $_GET['nome utente']; $query = "SELECT password FROM tbl_user WHERE name = '$name' ";
Passaggio 2. Il valore che un utente immette nella variabile URL username sarà assegnato alla variabile $name
Viene quindi inserito direttamente nell'istruzione SQL, consentendo all'utente di modificare l'istruzione SQL.
$nome = "amministratore" OPPURE 1=1 -- "; $query = "SELECT password FROM tbl_user WHERE name = '$name' ";
Passaggio 3. Il database SQL riceverà quindi l'istruzione SQL come segue:
SELECT password FROM tbl_users WHERE name = 'admin' OR 1=1 -- '
-
Questo è SQL valido, ma invece di restituire una password per l'utente, l'istruzione restituirà tutte le password nella tabella tbl_user. Questo non è qualcosa che vuoi nelle tue applicazioni web.
Parte 2 di 2: utilizzo di mySQLi per creare dichiarazioni preparate
Passaggio 1. Creare la query SELECT mySQLi
Utilizzare il codice seguente per SELEZIONARE i dati da una tabella utilizzando le istruzioni preparate mySQLi.
$nome = $_GET['nome utente']; if ($stmt = $mysqli->prepare("SELECT password FROM tbl_users WHERE name=?")) { // Associa una variabile al parametro come stringa. $stmt->bind_param("s", $nome); // Esegue l'istruzione. $stmt->execute(); // Recupera le variabili dalla query. $stmt->bind_result($pass); // Recupera i dati. $stmt->fetch(); // Visualizza i dati. printf("La password per l'utente %s è %s\n", $nome, $pass); // Chiude l'istruzione preparata. $stmt->chiudi(); }
Nota: la variabile $mysqli è l'oggetto connessione mySQLi
Passaggio 2. Creare la query INSERT mySQLi
Utilizzare il codice seguente per INSERIRE i dati in una tabella utilizzando le istruzioni preparate mySQLi.
$nome = $_GET['nome utente']; $password = $_GET['password']; if ($stmt = $mysqli->prepare("INSERT INTO tbl_users (nome, password) VALUES (?, ?)")) { // Associa le variabili al parametro come stringhe. $stmt->bind_param("ss", $nome, $password); // Esegue l'istruzione. $stmt->execute(); // Chiude l'istruzione preparata. $stmt->chiudi(); }
Nota: la variabile $mysqli è l'oggetto connessione mySQLi
Passaggio 3. Creare la query di AGGIORNAMENTO di mySQLi
Utilizzare il codice seguente per AGGIORNARE i dati in una tabella utilizzando le istruzioni preparate mySQLi.
$nome = $_GET['nome utente']; $password = $_GET['password']; if ($stmt = $mysqli->prepare("UPDATE tbl_users SET password = ? WHERE name = ?")) { // Associa le variabili al parametro come stringhe. $stmt->bind_param("ss", $password, $nome); // Esegue l'istruzione. $stmt->execute(); // Chiude l'istruzione preparata. $stmt->chiudi(); }
Nota: la variabile $mysqli è l'oggetto connessione mySQLi
Passaggio 4. Creare la query DELETE mySQLi
Lo script seguente mostra come eliminare i dati da una tabella utilizzando le istruzioni preparate mySQLi.
$nome = $_GET['nome utente']; $password = $_GET['password']; if ($stmt = $mysqli->prepare("DELETE FROM tbl_users WHERE name = ?")) { // Associa la variabile al parametro come stringa. $stmt->bind_param("s", $nome); // Esegue l'istruzione. $stmt->execute(); // Chiude l'istruzione preparata. $stmt->chiudi(); }