Como as consultas parametrizadas ajudam na injeção de SQL?

Nas duas consultas 1 e 2, o texto da checkbox de texto é inserido no database. 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? */ 

Além disso, aqui eu usaria a validação de Expressão Regular para interromper a inserção de caracteres ilegais.

Consultas parametrizadas fazem a devida substituição de argumentos antes de executar a consulta SQL. Remove completamente a possibilidade de input “suja” alterando o significado da sua consulta. Ou seja, se a input contiver SQL, ela não poderá se tornar parte do que é executado, porque o SQL nunca é injetado na instrução resultante.

injecção sql acontece quando um possível parâmetro tem sql dentro dele e as seqüências de caracteres não são tratadas como deveria ser

por exemplo:

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

e a condição é uma string proveniente do usuário na solicitação. Se a condição for maliciosa, por exemplo,

 var sqlquerywithoutcommand = "select * from mytable where rowname = '" + "a' ;drop table mytable where '1=1"+"'"; 

você pode acabar executando scripts maliciosos.

mas usando parâmetros, a input será limpa de quaisquer caracteres que possam escaping de caracteres de string …

Você pode ter certeza de que, não importa o que venha, não será possível executar scripts de injeção.

usando o object de comando com parâmetros o SQL realmente executado ficaria assim

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

no essense ele estará procurando por uma linha com rowname = a ‘; drop table mytable onde 1 = 1’ e não executando o script restante

Imagine uma consulta SQL dinâmica

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

Portanto, uma injeção simples de sql seria apenas colocar o nome de usuário como ' OR 1=1-- Isso efetivamente faria a consulta sql:

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

Isso indica selecionar todos os clientes onde o nome de usuário está em branco (”) ou 1 = 1, que é um valor booleano, igual a verdadeiro. Em seguida, ele usa – para comentar o resto da consulta. Então, isso apenas imprimirá toda a tabela de clientes ou fará o que quiser com ela, se efetuar login, fará o login com os privilégios do primeiro usuário, que muitas vezes pode ser o administrador.

Agora, as consultas parametrizadas fazem isso de maneira diferente, com código como:

 sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?' 

parameters.add (“Usuário”, nome de usuário) parameters.add (“Pass”, senha)

onde nome de usuário e senha são variables ​​que apontam para o nome de usuário e senha inseridos associados

Agora, neste momento, você pode estar pensando, isso não muda nada. Certamente você poderia apenas colocar no campo username algo como “Nobody OR 1 = 1” -, efetivamente fazendo a consulta:

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

E isso parece um argumento válido. Mas você estaria errado.

O modo como as consultas parametrizadas funcionam, é que o sqlQuery é enviado como uma consulta e o database sabe exatamente o que essa consulta fará, e somente então ele inserirá o nome de usuário e as senhas apenas como valores. Isso significa que eles não podem efetuar a consulta, porque o database já sabe o que a consulta fará. Portanto, nesse caso, ele procuraria por um nome de usuário "Nobody OR 1=1'--" e uma senha em branco, que deve aparecer como falsa.

Tirado de

Consultas parametrizadas lidam com tudo – por que se dar ao trabalho?

Com consultas parametrizadas, além da injeção geral, você obtém todos os tipos de dados manipulados, números (int e float), strings (com aspas incorporadas), datas e horas (sem problemas de formatação ou localização quando .ToString () não é chamado com a cultura invariável e seu cliente se move para uma máquina com formato de data inesperado).

Consultas parametrizadas permitem que o cliente passe os dados separadamente do texto da consulta. Onde na maior parte livre de texto você faria validação + escape. É claro que a parametrização não ajuda em outros tipos de injeção, mas como os parâmetros são passados ​​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 processadores modernos e do sistema operacional para proteger contra o estouro de buffer. Ele ainda permite o estouro de buffer, mas impede a execução dos dados injetados.

É perfeitamente compreensível por que alguém se sentiria 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 elas na verdade não.

O primeiro usa a input para uma consulta, o último decide a consulta, mas apenas substitui as inputs como ocorre durante a execução da consulta.

Para ser mais claro, os valores dos parâmetros estão localizados na pilha onde a memory das variables ​​é armazenada e é usada para pesquisa quando necessário.

Portanto, se dermos ' OR '1'='1 como input no nome de usuário, o primeiro construirá dinamicamente novas consultas ou consultas como parte da sqlQuery string de consulta sql, que é então executada.

Enquanto na mesma input, o último pesquisaria por ' OR '1'=' no campo username da tabela users com a consulta estaticamente especificada na query string sqlQuery

Apenas para consolidar, é 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);