2011-02-03 20 views

Respuesta

54

Básicamente, cuando se realiza una SQLCommand usando SQLParameters, los parámetros se nunca se insertan directamente en el comunicado. 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 analizarlos para excluirlos (y posiblemente cambiarlos), por lo que los parámetros que contienen nunca se pueden "ejecutar". Simplemente obtendrá un gran error gordo que el valor del parámetro no es válido de alguna manera.

+1

También obtendrá un error por intentar utilizar variables en lugares donde SQL (TSQL y en este caso) no es compatible con las variables. IE: cláusula 'FROM', un parámetro único para representar una lista separada por comas en una cláusula' IN', etc. –

+0

No creo que esto responda la pregunta. Puede invocar un procedimiento almacenado utilizando la clase SQLParameter, que pasa los parámetros al procedimiento, pero no llama a sp_executesql. ¿Qué sucede con los valores de los parámetros en una cadena sql concatenada? – Ian

9

"colecciones de parámetros tales como SqlParameterCollection proporcionar la comprobación de tipos y validación de la longitud Si se utiliza una colección de parámetros, de entrada se trata como un valor literal, y SQL Server no lo trata como código ejecutable.. Un beneficio adicional de usar una colección de parámetros es que 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

4

Al utilizar consultas parametrizadas, la superficie de ataque se reduce a monkeying alrededor con los parámetros.

Utilice SqlParameters, pero no olvide 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 establecida en 0.01, o intentando que la aplicación haga algo interesante al enviar algo que provoque un desbordamiento. Sql desbordamientos tienden a no ser interesante (es decir, que sólo causan excepciones, es poco probable que sea capaz de escribir en la memoria adyacente)

21

Un fácil de entender, y una respuesta más general es la siguiente:

Imagínese una consulta SQL dinámico:

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

una inyección SQL simple sería sólo para poner el nombre de usuario en tan ' OR 1=1--

Esto va en detrimento de 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 valor lógico, lo que equivale a verdad. A continuación, usa -- para comentar el resto de la consulta. Por lo tanto, esto imprimirá la tabla completa del cliente, o le permitirá hacer lo que quiera con ella.

Ahora consultas con parámetros hacerlo 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 nombre de usuario y la contraseña son variables que apuntan al nombre de usuario y la contraseña asociada inputed.

Ahora en este punto, puede pensar, esto no cambia nada en absoluto. Sin duda, aún se podía sólo hay que poner en el campo de nombre de usuario algo así como nadie OR 1 = 1' -, haciendo efectiva la consulta:

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

Y esto parece como un argumento válido. Pero, estarías equivocado.

La manera 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 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 ser falso.

Sin embargo, esta no es una solución completa, y la validación de entrada aún deberá realizarse, ya que esto no afectará a otros problemas, como los ataques , ya que aún podría colocar 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

+0

Me encanta como lo explicaste :-) limpio y al grano. – Sujith