¿Las citas de escape me protegen de la inyección de SQL?

3

Una pregunta de novato aquí.

Acabo de leer una breve introducción a la inyección de SQL en enlace

Dice encontrar una ruta de solicitud GET en la aplicación PHP para ver si es vulnerable o no.

Tengo un sitio web, con la siguiente URL de consulta.

http://example.com/get_stuff?query=hello&limit=50&offset=0

Estoy utilizando una consulta sin formato, por lo que, según el sitio, asumo que mi sitio web es vulnerable a la inyección de SQL.

Para probar esto, intento esto.

http://example.com/get_stuff?query=hello&limit=50'&offset=0

(agregar una comilla simple después del límite = 50)

Esto imprime el error, como se esperaba y como sugiere el sitio web, lo que significa que mi consulta es vulnerable.

Ahora, para proteger esto, quiero asegurarme de "escapar" de las citas en mis consultas. Estoy usando un marco PHP llamado CodeIgniter, en el que hay una función llamada $this->db->escape() .

Así que uso esta función de "escape" en el valor 50, pero ahora devuelve un error diciendo que "50" no es un número entero válido.

Bastante justo, la condición "LÍMITE" solo debería recibir un valor entero.

Pero mi pregunta es, ¿es segura mi consulta ahora "inyección SQL"?

    
pregunta ericbae 08.05.2013 - 02:07
fuente

4 respuestas

5

Su consulta es una inyección de primer orden tal vez, solo, tal vez, segura, dependiendo de cómo CodeIgniter haya mejorado desde la última vez que lo usé.

Seamos claros en esto: ninguna cantidad de desinfección le impedirá la inyección de SQL. La verdadera "mejor solución" para PHP es la parametrización, que le permite eliminar las variables de la consulta. De no ser así, sin embargo, el saneamiento adecuado puede ayudar. La última vez que verifiqué (hace tres años), CodeIgniter usó mysql_real_escape_string , que, si bien es un elemento disuasivo válido para la mayoría de los niños de script, no detendrá a un hacker experimentado.

Lo mejor que puedes hacer es leer cómo CodeIgniter realmente realiza el saneamiento / parametrización. Si solo es addslashes , evítalo como la plaga. Por cierto, hay muchas otras formas de realizar inyecciones de SQL; por ejemplo, puede utilizar la codificación de caracteres para pasar las comillas en la mayoría de las configuraciones de addslashes / mysql_escape_string . Hay muchos tutoriales sobre el tema.

    
respondido por el Sébastien Renauld 08.05.2013 - 02:14
fuente
5

No, las comillas / comillas dobles no garantizan que su aplicación web no sea vulnerable. También depende de las consultas SQL que haya utilizado. Ya he visto muchos ejemplos con addslashes() y escape() -como funciones como las que hacen las personas de esta manera:

SELECT * FROM a WHERE id > addslashes(user_input)

Por supuesto, esto es vulnerable, porque no necesita una comilla simple / comilla doble para realizar la inyección SQL. Es bueno mencionar que, en los mismos casos raros, addslashes podría omitir [ 1] .

La solución más recomendada para su problema de inyección de SQL es olvidarse de la concatenación de cadenas mientras crea las sentencias de SQL y eche un vistazo a las consultas preparadas / parametrizadas. Hablando de CodeIgniter, también debería estar interesado en la clase Active Record .

Si está 100% seguro, ese usuario siempre tiene que escribir un entero (como en su variable limit ), entonces puede intentar la conversión:

$limit = (int)$_GET['limit']

El uso de la conversión de esa manera lo protege de la inyección SQL (porque no hay manera de poner un valor no entero en su consulta SQL).

Ah, y no olvides que otras variables podrían ser vulnerables. Así que asegúrese de verificar query , offset y cualquier otra variable que controle el usuario. También es una buena práctica verificar el comportamiento de la aplicación web, cuando obtiene datos inesperados, en este caso podría ser una matriz en lugar de una cadena: get_stuff?query[]=hello&limit[]=50&offset[]=0

    
respondido por el p____h 08.05.2013 - 03:25
fuente
3

Lo que la mayoría de la gente no entiende es que las funciones de escape de cadenas de SQL solo están destinadas a valores designados para literales de cadenas de SQL . Esto significa que solo puede colocar dichos valores dentro de un literal de cadena SQL como '…' o "…" .

Estas funciones de escape de cadenas se utilizan para evitar que la entrada proporcionada por el usuario se interprete como algo distinto de un valor de cadena por error. Esto se hace reemplazando las comillas delimitadoras con secuencias de escape especiales para que no se interpreten como el delimitador final sino como una cita literal.

Ahora, si se pretende que su valor sea un valor entero en SQL como LIMIT requiere, el escape del valor con funciones de escape de cadena no funciona, ya que obviamente no es un literal de cadena sino un literal de entero.

Dado que no es una cadena, no hay comillas de delimitación que el atacante deba omitir. Y como la inyección ocurre en la cláusula LIMIT , un 50 UNION SELECT … inyectado podría ser posible para explotar exitosamente la vulnerabilidad.

Para solucionar esto, asegúrate de que los valores proporcionados por el usuario son los que esperas. En el caso de un valor entero, verifique si es realmente un valor entero, ya sea un valor del tipo entero o una representación de cadena válida del valor entero.

Además, hay bibliotecas que proporcionan una interfaz simple para las declaraciones parametrizadas y / o declaraciones preparadas donde la declaración y los valores de los parámetros se manejan por separado y los valores se convierten automáticamente al tipo adecuado.

En su caso, consulte ¿Cómo evitar la inyección de SQL en PHP?

    
respondido por el Gumbo 10.05.2013 - 19:36
fuente
-3

Para valores no enteros que he estado haciendo esto, puede que no sea el más rápido, pero me ha funcionado ... preg_replace("/[\"'%()@$.!&?_: #\/-]/","", mysql_real_escape_string($_GET['var']));

Aunque nunca he visto a nadie sugerir el uso de preg_replace, no veo ninguna manera de evitarlo para realizar un ataque de inyección

    
respondido por el Nisan 08.05.2013 - 06:18
fuente

Lea otras preguntas en las etiquetas