Desenvolvimento - ASP. NET

Usando parameter ao invés de aspas no ASP.NET

Veja nesse artigo como usar o parameter ao invés de aspas no asp.net e como enviar comandos para o banco de dados da maneira correta, ou seja, evitando o inject SQL e invasões em seu sistema ou site.

por Mauricio Junior



Caro(a) Leitor(a), hoje eu vou mostrar e explicar como enviar comandos para o banco de dados da maneira correta, ou seja, evitando o inject SQL e invasões em seu sistema ou site. Quando o desenvolvedor usa aspas duplas ou simples, o usuário mal intencionado pode colocar parâmetros em seus campos que anulam sua pesquisa, login e muito mais, por exemplo: Se na tela do seu site tem o campo de usuário, senha e o botão para entrar em uma área restrita; qualquer usuário pode colocar aspas simples e duplas como ‘x=x’ onde anulam o select com where.

Ao invés de pesquisar pelo usuário e senha no banco de dados, o select vai verificar se x é igual a x, cujo muitas vezes autentica. O mesmo comando pode acontecer com o campo de senha.

Utilizado:

  • Ferramenta Visual Studio
  • Linguagem C#
  • Plataformas: ASP.NET e Desktop

Comando do básico, veja o diagrama 1 de um sistema imaginário. Veja o diagrama abaixo:

Diagrama

Figura 1: Diagrama

Imagine que o seu site esteja utilizando essas camadas desenhadas na imagem 1. Temos o layout caracterizado pela primeira camada, temos a camada de regra de negócio e a camada de dados que acessa o banco de dados.

O “parameter” que estou falando hoje está na camada de dados responsável por acessar o banco de dados. Note que nenhuma outra camada acessa o banco de dados a não ser a camada de acesso a dados.

Na camada layout existem dois campos do tipo TextBox que precisam de preenchimento, como por exemplo usuário e senha. Depois de preenchido, os dados são enviados e passam de camada a camada até chegarem na de dados. Ocomando SQL é preparado com o objetivo de enviar os dados para o banco de dados, pode ser SQL Server, Oracle, MySQL ou outros existentes no mercado.

Se na camada de dados, o desenvolvedor preparar o SELECT usando aspas simples, o código pode sofre grande perigo na mão de usuários mal intecionados. A listagem 1 mostra um exemplo simples usando aspas simples, dentro da camada de dados.

Listagem 1: SELECT usando aspas simples.

Private DataSet SelecionUsuario(string _email, string _senha){
conectaBanco();
string sql = "SELECT Nome, Email, Usuario FROM Usuarios WHERE Email = ‘” + _email + “’ AND Senha = ‘” + _senha + “’”
SqlCommand sqlc = new SqlCommand(sql);
sqlc.CommandType = CommandType.Text;

DataSet dtSet = new DataSet();
SqlDataAdapter dtAdapter = new SqlDataAdapter(sqlc);
dtAdapter.Fill(dtSet);
return dtSet;
}

O método na listagem 1 é bem simples e não muito legal. Passar parâmetros como mostrado no método pode ser não muito bom, seria melhor passar uma classe ao invés de parâmetros separados.. Note que a “string” sql possui duas condições, a primeira com e-mail e a segunda com a senha. A listagem 2 mostra o que a maioria dos desenvolvedores fazem na condição do WHERE antes de processar no banco de dados.

Listagem 2: Condição com aspas.

Where Email=’” + _email + “’ AND Senha = ‘” + _senha + “’”

Esse comando deve ser feito de forma diferente. Usar aspas está fora do padrão de segurança. Se você usar de maneira diferente, outra dica é; mude mais rápido possível. Não só na linguagem C# e sim em todas as linguagens disponíveis. Dentro das aspas são passados os valores vindos do método, ou seja, o valor que o usuário digitou na variável “_email” e “_senha”.

O resto do código está comum, usado por muitos desenvolvedores da linguagem C#. O grande problema é a condição do SELECT enviado para o banco de dados

A segunda dica aqui é a utilização de @ no lugar dos parâmetros com aspas, veja a listagem 3.

Listagem 3: Trocando aspas por arroba.

Where Email= @email + AND Senha = @senha

A diferença da listagem 2 para a listagem 3 é o uso do arroba no lugar de aspas e os valores não são passados no comando SELECT, são passados em outro momento e antes de enviar para o banco de dados. Existem várias maneiras de atribuir parâmetros e valores, seguem duas maneiras.

Listagem 4: Atribuindo valores com SQLParameter

sqlc.Parameters.Add(new SqlParameter("@email", _email));
sqlc.Parameters.Add(new SqlParameter("@senha", _senha));

Note que na listagem 4, o parâmetro @email foi atribuído com o valor _email que veio na assinatura do método. O mesmo passo aconteceu com o parâmetro senha. Essa é uma maneira de utilizar parameter. A variável sqlc é SQLCommand. A segunda maneira possui mais detalhes como identificação de cada informação. Listagem 5.

Listagem 5: Outra maneira usando SQLParameter

IDataParameter param1 = new SqlParameter();
param1.ParameterName = "@email";
param1.Value = _email;
param1.DbType = System.Data.DbType.String;
sqlc.Parameters.Add(param1);

IDataParameter param2 = new SqlParameter();
param2.ParameterName = "@senha";
param2.Value = _senha;
param2.DbType = System.Data.DbType.String;
sqlc.Parameters.Add(param2);

Para definir os parâmetros, usamos o objeto “IDataParameter” onde é definido o nome, valor e tipo. No final, os parâmetros são atribuídos no SQL Command. Usando uma das duas maneiras, se o usuário fizer alguma passagem de parâmetro com aspas simples ou duplas, o site não terá problema algum.

A melhor maneira para criar o método mostrado na listagem 1 é colocar “parameter” e não aspas. Segue a listagem 6 para melhor entendimento.

Private DataSet SelecionUsuario(string _email, string _senha){
conectaBanco();
string sql = "SELECT Nome, Email, Usuario FROM Usuarios WHERE Email = @email AND Senha = @senha”;
SqlCommand sqlc = new SqlCommand(sql);
sqlc.CommandType = CommandType.Text;
IDataParameter param1 = new SqlParameter();
param1.ParameterName = "@email";
param1.Value = _email;
param1.DbType = System.Data.DbType.String;
sqlc.Parameters.Add(param1);
	
IDataParameter param2 = new SqlParameter();
param2.ParameterName = "@senha";
param2.Value = _senha;
param2.DbType = System.Data.DbType.String;
sqlc.Parameters.Add(param2);
DataSet dtSet = new DataSet();
SqlDataAdapter dtAdapter = new SqlDataAdapter(sqlc);
dtAdapter.Fill(dtSet);
return dtSet;
}

Bom, espero que tenha entendido o que foi falado aqui. Eu fico por aqui, utilize sempre esta dica em seus sites ou aplicativos e procure não deixar brecha de segurança. Qualquer dúvida pode entrar em contato pelo site www.mauriciojunior.org.

Mauricio Junior

Mauricio Junior - Formado pela Faculdade Anhanguera, Especialista pela FGV (Fundação Getúlio Vargas), Pós-Graduação em Docência Superior e cursando Mestrado na UNB Engenharia Elétrica; . Tenho 29 anos e possuo sete livros publicados pela editora Ciência Moderna e sou editor do Linha de Código.
Sou Certificado Microsoft MCP, MCAD e MVP, faço parte da comunidade ASPNETI.COM, onde publico artigos, vídeos, ebooks e livros Publico artigos, vídeos e podcast em outras comunidades. Trabalho como Analista de Sistemas / Desenvolvedor na empresa ATP S/A.
Blog:
blog.mauriciojunior.org
Site pessoal: www.mauriciojunior.org