¿Cómo evito este tipo de ataque de inyección SQL?

16

Nuestra compañía ha estado usando varias herramientas (Veracode, Appscan, etc.) para verificar que nuestras aplicaciones cumplan con los requisitos mínimos de seguridad. He heredado una aplicación heredada que tiene varios defectos. Me las arreglé para mitigar la mayoría de las vulnerabilidades, pero tengo problemas para solucionar el siguiente porque simplemente no sé lo que está haciendo. En nuestro informe, parece que está cambiando una de nuestras variables POST a

25%27+having+1%3D1--+

¿Qué es esto y qué está haciendo efectivamente? ¿Qué puedo hacer para evitar este tipo de ataque?

    
pregunta Jeff 11.12.2012 - 17:40
fuente

3 respuestas

26

Cuando esta cadena se decodifica de su forma codificada en url, se convierte en la siguiente:

25' having 1=1--

Esta cadena, cuando se coloca como está en, por ejemplo, la siguiente función de consulta de base de datos (PHP):

mysql_query("SELECT * FROM users WHERE username = '$username'");

Se convierte en esto:

mysql_query("SELECT * FROM users WHERE username = '25' having 1=1--'");

Note aquí que el% 27 (') rompe el argumento en la cláusula WHERE y continúa la parte ejecutable de la declaración. El - después de 1 = 1 hace que el resto de la declaración sea un comentario que no se ejecuta.

Se supone que la instrucción HAVING en SQL se usa en consultas que usan el operador GROUP BY, y debe fallar en consultas que no lo hacen. Mi conjetura aquí es que esta cadena se está utilizando para verificar simplemente la presencia de una variable no saneada que se coloca en una consulta ejecutada.

Para evitar este tipo de ataque, sugeriría usar una buena función de saneamiento de entrada o consultas parametrizadas. La implementación de esto depende del entorno de programación en cuestión.

Adición : el uso normal de 1 = 1 en las consultas de inyección SQL es hacer que todas las filas se devuelvan, anulando cualquier otra condición DÓNDE. Un ejemplo de entrada podría ser:

a' OR 1=1 --

Cuando se inserta como el parámetro $ password en una consulta como:

SELECT * FROM users WHERE username = '$username' AND password = '$password'

La declaración se convierte en:

SELECT * FROM users WHERE username = 'mark' AND password = 'a' OR 1=1 --

El conjunto de datos resultante incluirá todas las entradas en la tabla de 'usuarios', ya que 1 = 1 siempre es verdadero.

    
respondido por el mckiethanks 11.12.2012 - 18:08
fuente
6

lo que estás viendo es un vector de ataque de inyección SQL bastante estándar. El código que está agregando puede modificar las sentencias de SQL si la aplicación no maneja correctamente la entrada (pero supongo que lo resolvió a partir del título). Hay una buena descripción del problema que menciona este vector en este documento de NGS / NCC.

En términos de mitigar el problema, deberá asegurarse de que la entrada a la aplicación se valide o escape de manera adecuada para que no pueda modificar las consultas SQL subyacentes a la base de datos.

Un buen lugar para comenzar con esto sería Cheetsheet de Inyección de SQL OWASP

    
respondido por el Rоry McCune 11.12.2012 - 18:08
fuente
1

La alternativa a una consulta parametrizada es escapar de la entrada. La forma en que lo haga correctamente dependerá de su plataforma y base de datos. Por ejemplo, en PHP y con la base de datos mysql use mysql_real_escape_string (). Además, si hace esto, siempre debe usar comillas simples en el SQL, incluso para los números.

Puede pensar que solo puede reemplazar comillas simples en una cadena para hacerlo seguro, pero eso no es suficiente. Las comillas simples se pueden representar de otras maneras. Más detalles aquí: Explotaciones de caracteres multibyte - PHP / MySQL

    
respondido por el Sarel Botha 11.12.2012 - 23:14
fuente

Lea otras preguntas en las etiquetas