IRONSOFTWAREHOME

O que é injeção de SQL e como posso evitá-la em C#?

O que é injeção de SQL e como posso evitá-la em C#?

Tim Corey

34m 33s

A injeção de SQL é uma técnica de injeção de código que permite que invasores enviem código SQL malicioso para o seu servidor de banco de dados por meio da entrada do usuário. Em seu vídeo " O que é SQL Injection e como posso evitá-la em C#? ", Tim Corey demonstra exatamente como as vulnerabilidades de SQL Injection aparecem em código real, mostra vários exemplos de ataques de SQL Injection bem-sucedidos (incluindo ataques baseados em UNION e ataques destrutivos) e apresenta técnicas práticas de prevenção de SQL Injection que você pode aplicar em C#. Este artigo segue o passo a passo do Tim para que você possa ver exatamente os problemas e soluções que ele mostra.

Aplicativo de demonstração e por que isso é importante.

Tim começa com um pequeno aplicativo de demonstração WPF vinculado a um InjectableDB local (tabelas People e Secrets). A caixa de pesquisa do aplicativo, semelhante a um formulário da web, recebe a entrada do usuário (um sobrenome) e constrói uma consulta SQL para retornar o ID, o nome e o sobrenome. Ele "funciona" — digite Corey e você obtém Tim Corey — mas Tim enfatiza o ponto central: "Só porque um aplicativo funciona não significa que é seguro." Um aplicativo web funcionando ainda pode ter vulnerabilidades de injeção SQL quando a entrada fornecida pelo usuário é inserida diretamente em instruções SQL por concatenação de strings ou SQL dinâmico.

Código inseguro — concatenação de strings e SQL dinâmico

Tim demonstra o padrão inseguro exato que muitos desenvolvedores utilizam:

var sql = $"SELECT * FROM People WHERE LastName = '{searchText}'";
var results = connection.Query<Person>(sql);

Esta consulta original utiliza concatenação de strings para criar uma instrução SQL. Tim alerta: se você encontrar código que injeta entradas do usuário diretamente em consultas SQL, pare — isso é uma vulnerabilidade de injeção de SQL. Os atacantes podem criar entradas maliciosas que alteram a estrutura dos seus comandos SQL ou até mesmo executam instruções SQL maliciosas adicionais.

Como um atacante explora isso — UNION e DROP

Para demonstrar como funciona um ataque de injeção de SQL, Tim reproduz consultas no SQL Server e, em seguida, cria injeções usando UNION ALL e comentários SQL (--) para ocultar caracteres finais. Exemplos de payloads maliciosos que Tim demonstra:

  • Injeção de SQL baseada em UNION para ler outras tabelas:

    UNION ALL SELECT ID, Username AS FirstName, Password AS LastName FROM Secrets;
    Text

    Isso mistura os resultados de Secrets com o conjunto de resultados original do SELECT, expondo dados confidenciais como nomes de usuário e senhas.

  • Injeção destrutiva para excluir tabelas:

    DROP TABLE DemoTable;
    Text

    Isso executa uma segunda instrução SQL (DROP TABLE) finalizando a primeira instrução com um ponto e vírgula e, em seguida, adicionando o comando destrutivo. Tim mostra que a tabela desapareceu — o banco de dados foi modificado por um comando SQL malicioso.

A questão levantada por Tim é a seguinte: os atacantes não precisam saber os nomes das tabelas ou colunas com antecedência — eles podem enumerar os nomes das tabelas ou colunas nos servidores de banco de dados, ou simplesmente tentar técnicas baseadas em análise de dados ou em tempo real para descobrir o comportamento.

Correção 1 — Consultas parametrizadas

A primeira e principal defesa de Tim é parar de construir strings SQL com dados do usuário. Substitua o SQL dinâmico por consultas parametrizadas:

string sql = "SELECT * FROM People WHERE LastName = @LastName";
var results = connection.Query<Person>(sql, new { LastName = searchText });

Tim explica que a parametrização (uso no estilo prepared statement) significa que o banco de dados trata a entrada fornecida pelo usuário estritamente como dados — SQL malicioso se torna apenas um valor de string e não pode alterar a estrutura do SQL. Isso impede muitos ataques comuns de injeção de SQL, incluindo payloads baseados em union e anexados; Comandos DROP TABLE.

Ele também recomenda combinar a parametrização com a validação mínima de entrada: higienizar ou bloquear caracteres improváveis ​​em um sobrenome (por exemplo, ponto e vírgula ou marcadores de comentário --) enquanto permite caracteres legítimos como apóstrofos (O'Reilly). Consultas parametrizadas e limpeza de entrada oferecem proteção substancial contra ataques de injeção de SQL.

Correção 2 — Procedimentos armazenados

Em seguida, Tim mostra dois procedimentos armazenados: um procedimento armazenado inseguro que concatena SQL dentro do procedimento e depois o executa, e um procedimento armazenado seguro que usa parâmetros diretamente.

  • O procedimento armazenado inseguro constrói uma string @sql a partir do parâmetro e a executa — ainda vulnerável a injeção.

  • O procedimento armazenado seguro executa SELECT ... WHERE LastName = @LastName e executa com o parâmetro — seguro.

Tim esclarece: procedimentos armazenados não são uma solução automática se você ainda construir SQL dinâmico dentro deles. Mas, quando usadas corretamente (sem SQL dinâmico), as stored procedures ajudam a centralizar as instruções SQL, facilitando a parametrização e a auditoria de consultas. Os procedimentos armazenados também podem ajudar a simplificar a prevenção de injeção de SQL em seu aplicativo.

Não confie em nenhum dado — nem mesmo em dados de banco de dados.

Um ponto importante, e muitas vezes ignorado, que Tim levanta: você não deve confiar cegamente nos dados recuperados do seu próprio banco de dados SQL. Os atacantes às vezes inserem cargas maliciosas em colunas (uma "bomba-relógio") que serão posteriormente concatenadas em SQL dinâmico por outro processo. Tim insiste: use sempre parâmetros e higienize os dados em cada etapa — seja por meio de um formulário da web, um upload de arquivo ou seu próprio banco de dados — para que entradas maliciosas não se tornem posteriormente uma via de injeção.

Dica extra — princípio do menor privilégio e limitação de privilégios em bancos de dados.

Além das correções de código, Tim recomenda uma configuração defensiva: limite os privilégios de banco de dados para as contas do seu aplicativo. Na demonstração, a conexão utiliza uma conta de administrador por meio de segurança integrada — o que é perigoso. Em vez disso, utilize o princípio do menor privilégio:

  • Crie uma conta de banco de dados para o aplicativo com apenas os direitos necessários.

  • Se você usar procedimentos armazenados, conceda a essa conta apenas a permissão EXECUTE em procedimentos armazenados específicos e nada mais.

  • Não conceda privilégios de administrador amplos às contas de aplicativos, que permitam executar comandos como DROP TABLE, listar todas as tabelas ou ler outros bancos de dados.

Isso reduz o impacto de um ataque de injeção de SQL bem-sucedido — mesmo que a injeção seja possível, o invasor não poderá fazer mais do que a conta permite.

Tim também observa que o Entity Framework complica isso: o EF geralmente requer permissões elevadas (migrações, alterações de esquema). Se você usa o EF em produção, planeje suas permissões e implantação com cuidado.

Resumo — parar, parametrizar, higienizar, limitar

Tim conclui seu vídeo com uma lista de verificação clara para evitar injeção de SQL em aplicações C#:

  1. Pare de criar instruções SQL com concatenação de strings ou SQL dinâmico que inclua entrada do usuário.

  2. Utilize consultas parametrizadas/padrões de instruções preparadas para que os dados do usuário sejam sempre tratados como dados.

  3. Limpe a entrada quando apropriado (bloqueie ponto e vírgula, comentários SQL e caracteres inesperados).

  4. Prefira procedimentos armazenados seguros (sem SQL dinâmico em seu interior) para centralizar a lógica de consulta.

  5. Aplique o princípio do menor privilégio às contas de banco de dados — limite o que o usuário do banco de dados do aplicativo pode fazer.

  6. Analise o código (especialmente os locais que constroem SQL dinamicamente) e teste em busca de falhas de injeção de SQL.

Último aviso de Tim: o manuseio inadequado de entradas de usuário, SQL dinâmico e privilégios excessivos de banco de dados podem levar a violações graves — vazamento de dados confidenciais, tabelas destruídas ou exfiltração de dados não detectada e de longa duração. Considere a prevenção de injeção de SQL como um requisito fundamental de segurança, não como um mero aprimoramento opcional.

Earn More by Sharing What You Love

Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Let's Stay in Touch!

Join our newsletter, you’ll get exclusive access on article updates. We value your privacy

Key in blue circle

Obtenha sua chave de avaliação gratuita de 30 dias instantaneamente.

Your trial license will be sent to your email address

Sem limitações. 100% desbloqueado. Sem cartão de crédito.

bullet_checkedNão é necessário cartão de crédito nem criação de conta.Sem limitações. 100% desbloqueado. Sem cartão de crédito.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Agende sua consulta sem compromisso.
Preencha o formulário abaixo ou envie um e-mail para sales@ironsoftware.com
Os seus dados serão sempre mantidos em sigilo.
Aprovado por milhões de engenheiros em todo o mundo.
Logotipos dos clientes da Iron Software
Obtenha sua chave de avaliação gratuita de 30 dias instantaneamente.
Não é necessário cartão de crédito nem criação de conta.