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

¿Qué está sucediendo exactamente en el fondo que lo hace para que SQLParameter evite los ataques de Inección de SQL en una consulta .NET Parameterized? ¿Está simplemente eliminando a los personajes sospechosos o hay algo más?

¿Alguien ha revisado allí para ver lo que realmente llega a SQL Server cuando pasas entradas maliciosas?

Relacionado: ¿Se puede usar un SQLParameter en la instrucción SQL FROM?

Básicamente, cuando realiza un SQLCommand usando SQLParameters , los parámetros nunca se insertan directamente en la statement. En su lugar, se llama a un procedimiento almacenado del sistema llamado sp_executesql y se le da la cadena SQL y la matriz de parámetros.

Cuando se utilizan como tales, los parámetros se aíslan y se tratan como datos, en lugar de tener que analizarse sintácticamente (y posiblemente cambiarlos), de modo que lo que los parámetros contienen nunca se puede “ejecutar”. Simplemente obtendrá un gran error gordo que el valor del parámetro no es válido de alguna manera.

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 haría efectivamente la consulta SQL:

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

Esto indica que seleccione todos los clientes cuyo nombre de usuario esté en blanco ( '' ) o 1=1 , que es un booleano, lo que equivale a verdadero. Luego usa -- para comentar el rest 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 manera diferente, con un código como:

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

donde el nombre de usuario y la contraseña son variables que apuntan al nombre de usuario y la contraseña asignados asociados.

Ahora en este punto, puedes pensar, esto no cambia nada en absoluto. Seguramente podrías simplemente poner en el campo de nombre de usuario algo así como Nadie O 1 = 1 ‘-, haciendo la consulta de manera efectiva:

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

Y esto 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 lo que 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 de Nobody OR 1=1'-- y una contraseña en blanco, que debería aparecer como falsa.

Sin embargo, esta no es una solución completa, y la validación de entrada aún deberá hacerse, ya que esto no afectará a otros problemas, como los ataques xss , ya que aún se puede poner javascript en la base de datos. Luego, si esto se lee en una página, se mostraría como javascript normal, dependiendo de cualquier validación de salida. Entonces, realmente, lo mejor que se puede hacer es usar 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

“Las colecciones de parámetros como SqlParameterCollection proporcionan comprobació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 lo trata como código ejecutable. Una ventaja adicional de usar una colección de parámetros es que usted puede aplicar verificaciones 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

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

SqlParameters , pero no se olvide de desbordamiento, subdesbordamiento y parámetros no validados. Por ejemplo, si el método es “proc buy_book (@price money )”, un atacante malintencionado intentará engañar a la aplicación para que se ejecute con @price establecido en 0.01 , o si intenta hacer que la aplicación haga algo interesante al enviar algo que cause un desbordamiento Los desbordamientos de Sql no suelen ser interesantes (es decir, solo causan excepciones, es poco probable que puedas escribir en la memoria adyacente)