Como é que as consultas parametrizadas ajudam contra a injecção de SQL?

em ambas as consultas 1 e 2, o texto da caixa de texto é inserido na base de dados. Qual é o significado da consulta parametrizada aqui?

1.>-------------

SqlCommand cmd = new SqlCommand("INSERT INTO dbo.Cars " +"VALUES(@TagNbr);" , conn);

cmd.Parameters.Add("@TagNbr", SqlDbType.Int);

cmd.Parameters["@TagNbr"].Value = txtTagNumber.Text;

2.>--------------

int tagnumber = txtTagNumber.Text.ToInt16(); /* EDITED */

INSERT into Cars values(tagnumber.Text); /* then is it the same? */

Também, aqui eu usaria validação de Expressão Regular para parar a inserção de caracteres ilegais.

Author: Nondeterministic narwhal, 2011-03-29

6 answers

As consultas parametrizadas substituem adequadamente os argumentos antes de executar a consulta SQL. Ele remove completamente a possibilidade de entrada" suja " alterando o Significado de sua consulta. Isto é, se a entrada contém SQL, ela não pode se tornar parte do que é executado porque o SQL nunca é injetado na declaração resultante.

 41
Author: OJ., 2011-03-29 05:54:26

A injecção de Sql acontece quando um possível parâmetro tem sql dentro dela e as cadeias de caracteres não são tratadas como deveriam ser

Eg:

var sqlquerywithoutcommand = "select * from mytable where rowname =  '" + condition+''";

E a condição é uma string que vem do usuário no pedido. Se a condição é maliciosa diga eg:

var sqlquerywithoutcommand = "select * from mytable where rowname =  '" + "a' ;drop table  mytable where '1=1"+"'";
Podes acabar a fazer scripts maliciosos.

Mas usando parâmetros, a entrada será limpa de todos os caracteres que possam escapar dos caracteres...

Você pode ser assegurado não importa o que vem nele não será capaz de executar programas de injeção.

Se usar o objecto de comando com parâmetros, o sql realmente executado parecerá com este

select * from mytable where rowname = 'a'';drop table mytable where 1=1'''

In essense it will be looking for a row with rowname = a'; drop table mytable where 1=1' e não executar o programa restante

 15
Author: Mulki, 2011-03-29 06:19:02

Imagine uma consulta SQL dinâmica

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

Então uma simples injecção de sql seria apenas para colocar o nome de Utilizador em {[4] } isto faria efectivamente a consulta sql:

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

Isto diz para seleccionar todos os clientes onde o seu nome de Utilizador está em branco (") ou 1=1, que é um booleano, equiparando-se ao verdadeiro. Então ele usa -- para comentar fora o resto da consulta. Então isto vai imprimir tudo mesa de clientes, ou fazer o que você quiser com ele, se entrar, ele irá entrar com os privilégios do primeiro utilizador, que muitas vezes pode ser o administrador.

Agora, as consultas parametrizadas fazem-no de forma diferente, com um código como:
sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?'
Parâmetros.adicionar parâmetros ("utilizador", utilizador).adicionar ("passe", senha)

Onde o nome de utilizador e a senha são variáveis que apontam para o associado utilizador e senha introduzidos

Neste momento, podes estar a pensar que isto não muda nada. de todo. De certeza que ainda podes colocar o nome de utilizador campo algo como ninguém ou 1=1'--, efetivamente fazendo a consulta:
sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND
Pass=?'
E isto parece um argumento válido. Mas, estarias errado. A forma como as consultas parametrizadas funcionam, é que o sqlQuery é enviado como um consulta, e a base de dados sabe exatamente o que esta consulta fará, e só então ele irá inserir o nome de usuário e senhas meramente como valores. Isso significa que eles não podem efetuar a consulta, porque a base de dados já sabe o que a consulta vai fazer. Então em este caso iria procurar um nome de utilizador de "Nobody OR 1=1'--" e uma senha em branco, que deverá vir falso.

Extraído de

 3
Author: Ruben Steins, 2016-12-21 21:29:38
As consultas parametrizadas tratam de tudo. porquê dar-se ao trabalho?

Com consultas parametrizadas, para além da injecção geral, terá todos os tipos de dados tratados, números (int e float), cadeias de caracteres (com aspas incorporadas), datas e horas (sem problemas de formatação ou problemas de localização quando .ToString() não é chamado com a cultura invariante e seu cliente se move para uma máquina com e formato de data inesperado).

 1
Author: Cade Roux, 2011-03-29 06:01:25

As consultas parametrizadas permitem ao cliente passar os dados separadamente formam o texto da consulta. Onde na maioria livre de texto você faria validação + escapando. Claro que a parametrização não ajuda contra outro tipo de injeção, mas como o parâmetro é passado separadamente, eles não são usados como Consulta de texto de execução.

Uma boa analogia seria o bit de execução "recente" usado com a maioria dos modernos processadores e sistemas operacionais para proteger do excesso de buffer. Ainda permite a buffer overflow, mas evitar a execução dos dados injetados.

 1
Author: dvhh, 2011-03-29 06:11:02
É compreensível que se sinta assim.
sqlQuery = "select * from users where username='+username+';"

Vs

sqlQuery = "select * from users where username=@username;"

Ambas as perguntas acima parecem fazer a mesma coisa.Mas na verdade não.

O primeiro usa a entrada para uma consulta, o segundo decide sobre a consulta, mas apenas substitui as entradas como é durante a execução da consulta.

Para ser mais claro, os valores dos parâmetros estão localizados em algum lugar na pilha onde a memória das variáveis é armazenada e é usada para pesquisa quando necessario.

Então, se nós fôssemos dar ' OR '1'='1 como a entrada do nome de usuário, o ex-seria dinamicamente construir uma nova consulta ou consultas como parte da string da consulta sql sqlQuery qual é então executada.

Enquanto na mesma entrada, esta última iria procurar por ' OR '1'=' no campo username da tabela users com aestaticamente a pesquisa indicada no texto da pesquisasqlQuery

Só para consolidá-lo, é assim que você usa os parâmetros para fazer a consulta:

SqlCommand command = new SqlCommand(sqlQuery,yourSqlConnection);

SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "@username";
parameter.Value = "xyz";

command.Parameters.Add(parameter);
 1
Author: ant_1618, 2016-04-11 12:45:47