Olá pessoal, neste artigo mostrarei como prevenir ataques de SQL Injection em aplicações ASP.NET.

Acompanhem o passo-a-passo:

Conceito – A Injeção de SQL, ou SQL Injection, é um tipo de ameaça séria de segurança, que se aproveita de falhas em sistemas (não é exclusivo pra web) que interagem com bases de dados via SQL. Dito isto, o SQL Injection ocorre quando o usuário mal intencionado consegue inserir uma série de instruções SQL dentro de uma consulta através da manipulação das entradas de dados (alterações em um textbox, por exemplo) de uma aplicação. Fonte: Wikipedia.

Prática – Feito uma breve explicação do SQL Injection, vamos a um exemplo prático. Crie uma aplicação em ASP.NET com o nome ExemploSQLInjection. Neste exemplo, irei utilizar o banco Clientes, onde tenho as tabelas Registros e Usuarios:


Vá ao modo Design e arraste um TextBox, um Button e um GridView, para que sua página fique da seguinte forma:


Dê o nome ao ID do botão de btnConsultar e ao Grid de dgvResultado.

Agora vá a página de códigos e crie o método para o botão Consultar:

private void Consultar()

    {

        try

        {

            //Crio a variável que irá armazenar a string de conexão

            string strConn = @"Data Source=WELLINGT-45545B\SQLEXPRESS;Initial Catalog=Clientes;

                                                       Integrated Security=True;Pooling=False";

           

            //Crio a conexão por meio do using, que me garante que após o uso, a conexão será fechada

            using (SqlConnection objConn = new SqlConnection(strConn))

            {

                //Passo a instrução SQL por meio do SqlCommand e concateno

                //meu Where com o que o usuário digitar no TextBox

                SqlCommand objCmd = new SqlCommand("SELECT CODIGO, NOME FROM REGISTROS WHERE CODIGO = " +

                                                                          txtConsultar.Text, objConn);

 

                //Instancio o DataTable passando como parâmetro o SqlCommand

                SqlDataAdapter objDtAdapter = new SqlDataAdapter(objCmd);

 

                //Instancio o DataSet

                DataSet ds = new DataSet();

 

                //Uso o método Fill do DataAdapter, passando como parâmetro o DataSet e minha Tabela

                objDtAdapter.Fill(ds, "REGISTROS");

 

                //Uso o método DataSource de meu GridView, que receberá meu DataSet e chamo o DataBind

                dgvResultado.DataSource = ds;

                dgvResultado.DataBind();

            }

        }

        catch (Exception ex)

        {

            throw new Exception(ex.Message.ToString());

        }

    }

Lembrando que o intuito deste artigo não é o de explicar a conexão com o banco e sim o que torna vulnerável uma aplicação por meio de SQL Injection.

Volte ao modo Design, dê dois cliques no botão Consultar e chame o método recém-criado. Salve e compile o projeto. Digite 01 no TextBox e veja:


O Grid é populado com os dados do Registro1. O problema é que, como ele busca o que for digitado no TextBox, se um usuário mal intencionado digitar a seguinte instrução, olha o resultado:


Fazendo isso, consigo descobrir as senhas da tabela Usuarios pois da forma como está, nossa consulta concatena tudo o que for digitado no TextBox.

Se quiser, podemos até excluir tabelas dessa forma. Dito isso, podemos concluir que nossa instrução SQL não foi feita da melhor forma, já que está vulnerável a ataques.

Para resolver isso, devemos usar a consulta parametrizada. Como o próprio nome diz, com ela nós criamos uma variável que é representada por um parâmetro, que será associado ao valor digitado no TextBox.

Para entendermos melhor, altere a instrução e adicione a seguinte linha após a instrução:

//Passo a instrução SQL por meio do SqlCommand e uso parametrização para evitar SQLInjection

                SqlCommand objCmd = new SqlCommand("SELECT CODIGO, NOME FROM REGISTROS WHERE " +

                                                                  "CODIGO = @CODIGO", objConn);

 

                //Uso o método AddWithValue, que recebe meu parâmetro @Codigo e meu TextBox

                objCmd.Parameters.AddWithValue("@CODIGO", txtConsultar.Text);

Como vocês podem perceber, o que mudei apenas foi usar o @Codigo, e o método AddWithValue, que recebe justamente esse parâmetro junto com o que for digitado no TextBox. Dessa forma, estamos evitando vulnerabilidades em nossa aplicação.

Compile novamente e tente digitar a instrução que usamos para fazer um Select na tabela Usuarios:


Ao fazer isso e clicar no botão Consultar, será disparado um erro de falha de conversão:


Dessa forma evitamos o uso de SQL Injection em nossa aplicação. Por isso, é altamente recomendado sempre usar parâmetros em instruções SQL.

Assim finalizo o artigo.

Para quem se interessar, disponibilizo o código fonte desse projeto aqui.

Faço este artigo com base na videoaula de Bruno Belizário, do Portal Linha de Código, mediante autorização do mesmo.

Quaisquer dúvidas mandem emails para wellingtonbalbo@gmail.com ou deixem nos comentários deste artigo que responderei o mais rápido possível.

Até o próximo artigo!