Cuidados de segurança importantes ao utilizar Dapper

Renato Groffe
Feb 4, 2018 · 5 min read

Utilizado com frequência em aplicações .NET que exijam uma maior performance no acesso a bases relacionais, o Dapper é um micro-ORM que apresenta compatibilidade com o .NET Full (para projetos voltados a ambientes Windows) e o .NET Core (este último multiplaforma, o que viabilizou seu uso em Windows, Linux e Mac simultaneamente).

Já abordei inclusive sua utilização em posts anteriores:

Dapper: exemplos de utilização em ASP.NET Core e .NET Full

Dapper: exemplos em .NET Core 2.0 e ASP.NET Core 2.0

Dapper: relacionamentos Um-para-Um e Um-para-Muitos (exemplos em ASP.NET Core)

Dapper + .NET Core 2.0: exemplos utilizando PostgreSQL e MySQL

Este framework foi também tema de um hangout do Canal .NET no segundo semestre de 2017 (foram discutidos na mesma ocasião o uso de Entity Framework e NHibernate):

Por mais que não conte com todos os recursos típicos de um ORM convencional como o Entity Framework e o NHibernate, ainda assim o Dapper é uma solução de utilização relativamente simples. E é justamente esta simplicidade que pode levar desenvolvedores descuidados a implementar aplicações com falhas de segurança.

Por envolver o acesso a dados provenientes de bases relacionais a adoção do Dapper traz um problema comumente associado a este tipo de prática: a possibilidade de ataques de injeção de SQL (SQL Injection).

Nesta vulnerabilidade típica do uso de tecnologias relacionais comandos SQL são inseridos juntamente com parâmetros em URLs ou, até mesmo, durante o preenchimento de campos de um formulário. Tais instruções SQL podem tanto retornar informações de maneira indevida, quanto produzir resultados indesejáveis como a exclusão de estruturas de um banco de dados ou alterações não planejadas.

O exemplo a seguir traz uma consulta numa base SQL Server a uma tabela contendo informações sobre cidades , utilizando como filtro o estado destas localidades. Importante destacar que o método Query é uma extensão disponibilizada pelo próprio Dapper, com sua utilização acontecendo em conjunto com instâncias de classes que implementam IDbConnection (estrutura básica para conexão a bancos relacionais no ADO.NET):

A seguir temos uma variação deste conjunto de instruções, empregando desta vez interpolação de strings na passagem do parâmetro que filtrará as cidades localizadas em um estado específico:

Em ambos os exemplos apresentados há a possibilidade de injeção de instruções SQL. Embora algo simples a ser evitado, a geração de comandos SQL por meio da concatenação de strings com parâmetros representa um hábito comum entre muitos desenvolvedores. E como impedir que situações indesejadas ocorram? As seções a seguir trazem recomendações simples e bastante eficientes neste sentido.


Restringindo o acesso a um banco de dados

Está utilizando o Dapper em uma API REST que processará apenas requisições do tipo GET? O acesso a bancos de dados relacionais com um login com permissões somente para leitura evitará maiores problemas.

Haverá gravação e/ou exclusão de dados? O login em questão também deverá possuir permissão para a execução de operações como INSERT, UPDATE e DELETE.

Considerando uma tentativa de injeção de SQL na aplicação ASP.NET Core que faz uso das instruções C# apresentadas anteriormente, uma URL poderia conter o seguinte caminho e parâmetros:

/Cidades?estado=SP’;DROP%20TABLE%20dbo.Cidades;SELECT%201%20WHERE%20'’%20=%20'

ao invés de simplesmente /Cidades?estado=SP

Qual seria a consequência de se processar esta requisição, levando em conta o exemplo de consulta a cidades? A concatenação de strings produziria 3 instruções:

SELECT * FROM dbo.Cidades WHERE Estado = ‘SP’;DROP TABLE dbo.Cidades;SELECT 1 WHERE ‘’ = ‘’

Caso o usuário empregado na string de conexão possua direitos para a execução de um comando DROP TABLE, a tabela dbo.Cidades deixará então de existir.


Passagem de parâmetros

Além de comandos que podem alterar a estrutura e/ou modificar dados de uma base, há ainda a possibilidade de acesso a dados restritos ou que não façam sentido dentro de um determinado contexto.

Retomando o exemplo de consulta a cidades, a URL apresentada a seguir traz novamente um caso de SQL Injection. Desta vez uma condição forçará a exibição de dados de 2 estados diferentes (a ideia era restringir isto a apenas uma unidade federativa):

/Cidades?estado=SP’%20OR%20Estado%20=%20'MG

Como resultado disto seria produzida a seguinte instrução SQL:

SELECT * FROM dbo.Cidades WHERE Estado = ‘SP’ OR Estado = ‘MG’

E em tela apareceriam dados de 2 estados:

Uma consulta a dados financeiros que passasse por este mesmo tipo de problema poderia resultar em uma grave falha de segurança, sem sombra de dúvidas. E como evitar isto?

Recomenda-se que a passagem de parâmetros em Dapper faça uso de objetos anônimos. Cada nome de parâmetro será precedido pelo caracter @ (arroba), com as propriedades do objeto anônimo possuindo a mesma nomenclatura utilizada em sua expressão SQL (sem @, obviamente). O exemplo a seguir ilustra esta prática:

Uma outra solução ao fazer pesquisas cujo filtro seja a chave-primária de uma tabela é o Dapper.Contrib, um framework criado pelo time responsável pelo próprio Dapper e que simplifica a implementação de operações de CRUD.

Será necessário indicar ao Dapper.Contrib a tabela/view à qual uma classe se refere, além de sua primary key (com o atributo ExplicitKey para campos preenchidos via aplicação; no caso de uma chave auto-incremento usar o atributo Key). Um exemplo disso está na definição da classe Estado:

Já na listagem seguinte uma consulta aos dados de um estado foi realizada via Dapper.Contrib, através de uma chamada ao método Get (o qual receberá como parâmetro a sigla do estado):


Aproveito este post para deixar aqui também um convite. Entre os dias 3 e 5 de Dezembro/2018 acontecerá o DevWeek 2018, o evento de final de ano do Canal .NET voltado a desenvolvedores de software.

Serão 9 palestras noturnas, gratuitas e online ao longo de 3 dias, cobrindo diversas tecnologias e temas de destaque na área de software (sobretudo .NET e Microsoft Azure).

Para efetuar sua inscrição acesse e faça sua inscrição pelo Meetup, a transmissão será via YouTube e a grade será divulgada em breve.

Ainda não segue o Canal .NET nas redes sociais? Faça sua inscrição então, para ficar por dentro de novidades sobre eventos, tecnologias Microsoft e outros conteúdos gratuitos:

Renato Groffe

Written by

Microsoft Most Valuable Professional (MVP), Multi-Plataform Technical Audience Contributor (MTAC), Software Engineer, Technical Writer and Speaker

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade