SQLite - Iniezione

Se prendi l'input dell'utente attraverso una pagina Web e lo inserisci in un database SQLite, è possibile che tu sia rimasto completamente aperto a un problema di sicurezza noto come SQL Injection. In questo capitolo imparerai come evitare che ciò accada e ti aiuterà a proteggere i tuoi script e le istruzioni SQLite.

L'iniezione di solito si verifica quando chiedi un input a un utente, come il suo nome, e invece di un nome ti danno un'istruzione SQLite che eseguirai inconsapevolmente sul tuo database.

Non fidarsi mai dei dati forniti dall'utente, elaborare questi dati solo dopo la convalida; di regola, questo viene fatto dalla corrispondenza del modello. Nell'esempio seguente, il nome utente è limitato a caratteri alfanumerici più trattino basso e una lunghezza compresa tra 8 e 20 caratteri: modificare queste regole secondo necessità.

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)){
   $db = new SQLiteDatabase('filename');
   $result = @$db->query("SELECT * FROM users WHERE username = $matches[0]");
} else {
   echo "username not accepted";
}

Per dimostrare il problema, considera questo estratto:

$name = "Qadir'; DELETE FROM users;";
@$db->query("SELECT * FROM users WHERE username = '{$name}'");

La chiamata di funzione dovrebbe recuperare un record dalla tabella degli utenti in cui la colonna del nome corrisponde al nome specificato dall'utente. In circostanze normali,$nameconterrebbe solo caratteri alfanumerici e forse spazi, come la stringa ilia. Tuttavia in questo caso, aggiungendo una query completamente nuova a $ name, la chiamata al database si trasforma in un disastro: la query DELETE inserita rimuove tutti i record dagli utenti.

Esistono interfacce di database che non consentono lo stacking delle query o l'esecuzione di più query in una singola chiamata di funzione. Se provi a impilare le query, la chiamata fallisce ma SQLite e PostgreSQL eseguono felicemente le query in pila, eseguendo tutte le query fornite in una stringa e creando un serio problema di sicurezza.

Prevenire SQL Injection

Puoi gestire tutti i caratteri di escape in modo intelligente nei linguaggi di scripting come PERL e PHP. Il linguaggio di programmazione PHP fornisce la funzionestring sqlite_escape_string() per eseguire l'escape dei caratteri di input speciali per SQLite.

if (get_magic_quotes_gpc()) {
   $name = sqlite_escape_string($name);
}
$result = @$db->query("SELECT * FROM users WHERE username = '{$name}'");

Sebbene la codifica renda sicuro l'inserimento dei dati, renderà semplici confronti di testo e LIKE clausole nelle query inutilizzabili per le colonne che contengono i dati binari.

Note - addslashes()NON dovrebbe essere usato per citare le stringhe per le query SQLite; porterà a risultati strani durante il recupero dei dati.