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 xss, 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
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. –
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