statement query prepared example bind_param php mysql security sql-injection prepared-statement

php - query - ¿Por qué es más seguro usar una declaración preparada de mysql que usar las funciones de escape comunes?



sql pdo php (7)

Hay un comentario en otra pregunta que dice lo siguiente:

"Cuando se trata de consultas a bases de datos, siempre intente utilizar consultas parametrizadas preparadas. Las bibliotecas mysqli y PDO son compatibles con esto. Esto es infinitamente más seguro que usar funciones de escape como mysql_real_escape_string".

Source

Entonces, lo que quiero preguntar es: ¿Por qué las consultas parametrizadas preparadas son más seguras?


En el mejor de los casos, podría no serlo, pero al menos igualmente seguro; y por qué tomar la oportunidad?



Las declaraciones preparadas resuelven un problema fundamental de la seguridad de la aplicación que el mero saneamiento de los datos no hace: resultan en una separación completa de los datos y las instrucciones . Cuando los dos se confunden, la inseguridad es el resultado. Esto es cierto tanto para inyección SQL como para desbordamientos de búfer.

(Hay otras formas de ser inseguro).


No soy extremadamente versado en seguridad pero aquí hay una explicación que espero te ayude:

Digamos que tienes una declaración como:

seleccione [entero] de mydb

Imagina cuando lo preparas, la declaración se compila en bytes en nuestra implementación de sql imaginaria.

01 00 00 23 Opcode for select Prepared bytes number of "mydb" for your integer

Ahora cuando ejecutas, insertarás el número en el espacio reservado para tu declaración preparada.

Compárelo si solo usa escape, posiblemente podría insertar tanto galimatías allí y tal vez causar que se desborde la memoria, o algún comando bizarro sql que olvidaron escapar.


Por un lado, está dejando el escape de personajes peligrosos a la base de datos, que es mucho más segura que usted, el humano.

... no se olvidará de escapar, o perderá ningún carácter especial que pueda usarse para inyectar algún SQL malicioso. ¡Sin mencionar, posiblemente podrías obtener una mejora en el rendimiento para arrancar!


Porque con las declaraciones preparadas, no puede olvidarse de escapar del contenido. Entonces no hay forma de introducir inseguridad.

mysql_real_escape_string es tan seguro como las declaraciones preparadas SI recuerda usar mysql_real_escape_string cada vez que llama a mysql_query, pero es fácil de olvidar.


Un punto importante que creo que la gente de aquí falta es que con una base de datos que admite consultas parametrizadas, no hay ''escapando'' de qué preocuparse. El motor de base de datos no combina las variables vinculadas en la declaración SQL y luego analiza todo; Las variables enlazadas se mantienen separadas y nunca se analizan como una declaración SQL genérica.

De ahí viene la seguridad y la velocidad. El motor de la base de datos sabe que el marcador de posición contiene solo datos, por lo que nunca se analiza como una declaración SQL completa. La aceleración se produce cuando preparas una declaración una vez y luego la ejecutas muchas veces; el ejemplo canónico es insertar múltiples registros en la misma tabla. En este caso, el motor de la base de datos necesita analizar, optimizar, etc. solo una vez.

Ahora, uno tiene que ver con las bibliotecas de abstracción de bases de datos. A veces lo falsifican simplemente insertando las variables enlazadas en la declaración SQL con el escape apropiado. Aún así, eso es mejor que hacerlo tú mismo.