L'idea è molto semplice: la query e i dati vengono inviati al server di database separatamente .
È tutto.
La radice del problema di iniezione SQL è nella miscelazione del codice e dei dati.
In effetti, la nostra query SQL è un programma legittimo . E stiamo creando un tale programma in modo dinamico, aggiungendo alcuni dati al volo. Pertanto, i dati possono interferire con il codice del programma e persino modificarlo, come mostra ogni esempio di iniezione SQL (tutti gli esempi in PHP / Mysql):
$expected_data = 1;
$query = "SELECT * FROM users where id=$expected_data";
produrrà una query regolare
SELECT * FROM users where id=1
mentre questo codice
$spoiled_data = "1; DROP TABLE users;"
$query = "SELECT * FROM users where id=$spoiled_data";
produrrà una sequenza dannosa
SELECT * FROM users where id=1; DROP TABLE users;
Funziona perché stiamo aggiungendo i dati direttamente al corpo del programma e diventa una parte del programma, quindi i dati possono alterare il programma e, a seconda dei dati passati, avremo un output regolare o una tabella users
eliminata.
Mentre in caso di dichiarazioni preparate non alteriamo il nostro programma, rimane intatto
Questo è il punto.
In primo luogo stiamo inviando un programma al server
$db->prepare("SELECT * FROM users where id=?");
dove i dati sono sostituiti da una variabile chiamata parametro o segnaposto.
Si noti che esattamente la stessa query viene inviata al server, senza dati in essa contenuti! E poi stiamo inviando i dati con la seconda richiesta, essenzialmente separati dalla query stessa:
$db->execute($data);
quindi non può alterare il nostro programma e fare del male.
Abbastanza semplice, no?
L'unica cosa che devo aggiungere è sempre stata omessa in ogni manuale:
Le istruzioni preparate possono proteggere solo i letterali di dati , ma non possono essere utilizzate con qualsiasi altra parte della query.
Quindi, una volta che dobbiamo aggiungere, per esempio, un identificatore dinamico - un nome di campo, ad esempio - le istruzioni preparate non possono aiutarci. Di recente ho spiegato la questione , quindi non mi ripeterò.