¿Cómo previene SQLParameter la inyección SQL?

Resuelto Abe Miessler asked hace 13 años • 4 respuestas

¿Qué sucede exactamente en segundo plano que hace que SQLParameter impida los ataques de inyección SQL en una consulta parametrizada .NET? ¿Se trata simplemente de eliminar cualquier personaje sospechoso o hay algo más?

¿Alguien ha comprobado qué llega realmente a SQL Server cuando pasa una entrada maliciosa?

Relacionado: ¿Puedes usar un SQLParameter en la declaración SQL FROM?

Abe Miessler avatar Feb 04 '11 04:02 Abe Miessler
Aceptado

Básicamente, cuando realiza un SQLCommanduso SQLParameters, los parámetros nunca se insertan directamente en la declaración. En su lugar, se llama a un procedimiento almacenado del sistema sp_executesqly se le proporciona la cadena SQL y la matriz de parámetros.

Cuando se usan como tales, los parámetros se aíslan y se tratan como datos, en lugar de tener que analizarse fuera de la declaración (y por lo tanto posiblemente cambiarla), por lo que lo que contienen los parámetros nunca se puede "ejecutar". Recibirá un gran error indicando que el valor del parámetro no es válido de alguna manera.

KeithS avatar Feb 03 '2011 21:02 KeithS

Una respuesta más fácil de entender y más general es la siguiente:

Imagine una consulta SQL dinámica:

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password

Una simple inyección de SQL sería simplemente poner el nombre de usuario como' OR 1=1--

Esto efectivamente haría que la consulta SQL:

sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password

Esto dice seleccionar todos los clientes donde su nombre de usuario esté en blanco ( '') o 1=1, que es un booleano, lo que equivale a verdadero. Luego se utiliza --para comentar el resto de la consulta. Esto imprimirá toda la tabla de clientes o le permitirá hacer lo que quiera con ella.

Ahora las consultas parametrizadas lo hacen de forma diferente, con código como:

sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?' parameters.add("User", username) parameters.add("Pass", password)

donde nombre de usuario y contraseña son variables que apuntan al nombre de usuario y contraseña ingresados ​​asociados.

Ahora bien, llegados a este punto, podrías pensar que esto no cambia nada en absoluto. Seguramente todavía podrías poner en el campo de nombre de usuario algo como Nadie O 1=1'--, haciendo efectivamente la consulta:

sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'

Y este parecería un argumento válido. Pero estarías equivocado.

La forma en que funcionan las consultas parametrizadas es que la consulta SQL se envía como una consulta, y la base de datos sabe exactamente qué hará esta consulta, y solo entonces insertará el nombre de usuario y las contraseñas simplemente como valores. Esto significa que no pueden afectar la consulta porque la base de datos ya sabe lo que hará la consulta. Entonces, en este caso buscaría un nombre de usuario Nobody OR 1=1'--y una contraseña en blanco, lo que debería resultar falso.

Sin embargo, esta no es una solución completa y aún será necesario realizar la validación de entrada, ya que esto no afectará otros problemas, comoxssataques, ya que aún podría poner javascript en la base de datos. Luego, si esto se lee en una página, se mostrará como JavaScript normal, dependiendo de cualquier validación de salida. Entonces, realmente lo mejor que se puede hacer es seguir usando la validación de entrada, pero usando consultas parametrizadas o procedimientos almacenados para detener cualquier ataque SQL.

Fuente: http://www.lavamunky.com/2011/11/why-parameterized-queries-stop-sql.html

anaik avatar May 21 '2015 07:05 anaik

"Las colecciones de parámetros como SqlParameterCollection proporcionan verificación de tipos y validación de longitud. Si usa una colección de parámetros, la entrada se trata como un valor literal y SQL Server no la trata como código ejecutable. Un beneficio adicional de usar una colección de parámetros es que puede imponer controles de tipo y longitud. Los valores fuera del rango desencadenan una excepción. Este es un buen ejemplo de defensa en profundidad".

http://msdn.microsoft.com/en-us/library/ff648339.aspx

Dave Brace avatar Feb 03 '2011 21:02 Dave Brace

Cuando se utilizan consultas parametrizadas, la superficie de ataque se reduce a jugar con los parámetros.

Utilice SqlParameters, pero no se olvide del desbordamiento, el desbordamiento insuficiente y los parámetros no validados. Por ejemplo, si el método es "proc buy_book (@price money)", un atacante malintencionado intentaría engañar a la aplicación para que se ejecute con @priceset to 0.01o intentar que la aplicación haga algo interesante enviando algo que provoque un desbordamiento. Los desbordamientos de SQL tienden a no ser interesantes (es decir, solo causan excepciones, es poco probable que puedas escribir en la memoria adyacente)

MatthewMartin avatar Feb 03 '2011 22:02 MatthewMartin