2009-04-09 12 views
25

Hay un comentario en otra pregunta que dice lo siguiente:..¿Por qué usar una declaración preparada de mysql es más segura que usar las funciones de escape comunes?

"Cuando se trata de consultas de bases de datos, siempre tratar de utilizar preparados consultas parametrizadas El mysqli y bibliotecas PDO soportan esta Este es infinitamente más seguro que usar las funciones de escape como mysql_real_escape_string ".

Source

Por lo tanto, lo que quiero preguntar es: ¿Por consultas con parámetros están preparados más seguro?

Respuesta

42

Un punto importante que creo que la gente 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, una gotcha es con bibliotecas de abstracción de base 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.

+0

Gracias por explicar :) –

+0

Así que es más rápido pero la seguridad es la misma? Quiero decir que no puedes estar más seguro que completamente seguro. También me gustaría alguna prueba de las teorías de la velocidad. –

7

Por un lado, está dejando escapar caracteres peligrosos a la base de datos, que es mucho más seguro 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!

+0

Pero ¿cómo sabe la base de datos la diferencia entre lo que es peligroso y entre lo que yo realmente quiero que haga? –

+0

Bueno, sabe qué caracteres son malos, por lo que debe anteponer el carácter de escape '\' en MySQL antes del carácter malvado. Esto sigue haciendo la consulta tal como está, pero no respetará ningún carácter especial que aparezca en un enlace. – alex

+0

Además, debe especificar los 'enlaces' por separado (no concatenados en la consulta), y simplemente inserte un marcador de posición en la consulta donde debería aparecer. La base de datos (creo, ¿tal vez lo hace DOP?) Luego escapa de los caracteres dentro de los enlaces. – alex

0

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

5

No estoy muy versado en la seguridad, pero aquí es una explicación que espero que le ayudará a:

Digamos que usted tiene una declaración como:

seleccionar [número entero] de mibd

Pretend 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 lo ejecute, insertará el número en el espacio reservado para su declaración preparada.

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

+0

Ese es un buen ejemplo, gracias. –

2

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.

1

La función no es segura debido a este exploit http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string. Es por eso que se prefieren las declaraciones preparadas y también mejora el rendimiento.

+0

Creo que si estoy leyendo ese blog vinculado correctamente, él tiene problemas con addslashes siendo inseguro, no mysql_real_escape_string. Él dice al final que esta última es una opción válida, si las personas recuerdan hacerlo, pero las personas tienden a olvidarse de llamarlo. Usar declaraciones preparadas ayuda con ese problema de memoria. –

+0

Este es un enlace interesante también, que apunta a un posible problema con mysql_real_escape_string, aunque oscuro: http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html –

1

Las declaraciones preparadas resuelven un fundamental problem of application security que no hace mero saneamiento de datos: dan como resultado 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 maneras de ser inseguro.)

Cuestiones relacionadas