La idea es muy simple: la consulta y los datos se envían al servidor de la base de datos por separado .
Eso es todo.
La raíz del problema de inyección SQL está en la mezcla del código y los datos.
De hecho, nuestra consulta SQL es un programa legítimo . Y estamos creando dicho programa dinámicamente, agregando algunos datos sobre la marcha. Por lo tanto, los datos pueden interferir con el código del programa e incluso alterarlo, como lo muestra cada ejemplo de inyección SQL (todos los ejemplos en PHP / Mysql):
$expected_data = 1;
$query = "SELECT * FROM users where id=$expected_data";
producirá una consulta regular
SELECT * FROM users where id=1
mientras este código
$spoiled_data = "1; DROP TABLE users;"
$query = "SELECT * FROM users where id=$spoiled_data";
producirá una secuencia maliciosa
SELECT * FROM users where id=1; DROP TABLE users;
Funciona porque estamos agregando los datos directamente al cuerpo del programa y se convierte en una parte del programa, por lo que los datos pueden alterar el programa y, dependiendo de los datos pasados, tendremos una salida regular o una tabla users
eliminada.
Si bien en el caso de declaraciones preparadas no modificamos nuestro programa, permanece intacto.
Ese es el punto.
Estamos enviando un programa al servidor primero
$db->prepare("SELECT * FROM users where id=?");
donde los datos se sustituyen por alguna variable llamada parámetro o marcador de posición.
Tenga en cuenta que exactamente la misma consulta se envía al servidor, ¡sin ningún dato! Y luego enviamos los datos con la segunda solicitud, esencialmente separados de la consulta en sí:
$db->execute($data);
por lo que no puede alterar nuestro programa y hacer daño.
Bastante simple, ¿no es así?
Lo único que tengo que agregar que siempre se omite en todos los manuales:
Las declaraciones preparadas pueden proteger solo literales de datos , pero no se pueden usar con ninguna otra parte de consulta.
Entonces, una vez que tengamos que agregar, por ejemplo, un identificador dinámico , un nombre de campo, por ejemplo, las declaraciones preparadas no pueden ayudarnos. He explicado el asunto recientemente , así que no me repetiré.