1. O que é um ataque de injeção SQL?
O chamado ataque de injeção de SQL significa que o invasor insere comandos SQL no campo de entrada de um formulário da Web ou na string de consulta de uma solicitação de página e engana o servidor para que execute comandos SQL maliciosos. Em alguns formulários, a entrada do usuário é usada diretamente para construir (ou afetar) comandos SQL dinâmicos ou como parâmetros de entrada para procedimentos armazenados. Esses formulários são particularmente vulneráveis a ataques de injeção de SQL. Os processos comuns de ataque de injeção de SQL incluem:
⑴ Um aplicativo Web ASP.NET possui uma página de login. Essa página de login controla se o usuário tem o direito de acessar o aplicativo.
⑵ O conteúdo inserido na página de login será usado diretamente para construir comandos SQL dinâmicos ou usado diretamente como parâmetros de procedimentos armazenados. Aqui está um exemplo de um aplicativo ASP.NET construindo uma consulta:
System.Text.StringBuilder query = new System.Text.StringBuilder(
"SELECIONE * de Usuários WHERE login = '")
.Append(txtLogin.Text).Append("' AND senha='")
.Append(txtPassword.Text).Append("'");
⑶ O invasor insere algo como "' ou '1'='1" nas caixas de entrada de nome de usuário e senha.
⑷ Depois que o conteúdo inserido pelo usuário é enviado ao servidor, o servidor executa o código ASP.NET acima para construir um comando SQL para consultar o usuário. No entanto, como o conteúdo inserido pelo invasor é muito especial, o comando SQL final. torna-se: SELECT * from Users WHERE login = '' ou '1'='1' AND password = '' ou '1'='1'.
⑸ O servidor executa uma consulta ou processo armazenado para comparar as informações de identidade inseridas pelo usuário com as informações de identidade salvas no servidor.
⑹ Como o comando SQL foi modificado pelo ataque de injeção e não pode autenticar verdadeiramente a identidade do usuário, o sistema autorizará incorretamente o invasor.
Se um invasor souber que o aplicativo usará o conteúdo inserido no formulário diretamente para consultas de verificação de identidade, ele tentará inserir algumas strings SQL especiais para adulterar a consulta e alterar sua funcionalidade original e enganar o sistema para que conceda permissões de acesso.
Dependendo do ambiente do sistema, o dano que um invasor pode causar também é diferente, o que é determinado principalmente pelas permissões de segurança da aplicação para acessar o banco de dados. Se a conta do usuário tiver direitos de administrador ou outros direitos relativamente avançados, o invasor poderá realizar várias operações nas tabelas do banco de dados que desejar, incluindo adicionar, excluir ou atualizar dados, ou até mesmo excluir diretamente a tabela.
2. Como prevenir?
Felizmente, não é particularmente difícil impedir que aplicativos ASP.NET sejam invadidos por ataques de injeção de SQL. Tudo o que você precisa fazer é filtrar todo o conteúdo de entrada antes de usar o conteúdo de entrada do formulário para construir o comando SQL. A filtragem de entrada pode ser feita de várias maneiras.
⑴ Para situações em que as consultas SQL são construídas dinamicamente, as seguintes técnicas podem ser usadas:
Primeiro: Substitua aspas simples, ou seja, altere todas as aspas simples para duas aspas simples para evitar que invasores modifiquem o significado dos comandos SQL. Olhando novamente para o exemplo anterior, "SELECT * from Users WHERE login = ''' or ''1''=''1' AND password = ''' or ''1''=''1'" obviamente obterá os mesmos resultados diferentes "SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'".
Segundo: Remova todos os hífens no conteúdo de entrada do usuário para evitar que invasores construam consultas como "SELECT * from Users WHERE login = 'mas' -- AND password =''", porque o sufixo de tais consultas Metade dele foi comentado fora e não é mais válido. O invasor só precisa saber um nome de login de usuário legal e não precisa saber a senha do usuário para obter acesso com êxito.
Terceiro: Limite as permissões da conta do banco de dados usada para executar consultas. Use diferentes contas de usuário para realizar operações de consulta, inserção, atualização e exclusão. Ao isolar as operações que podem ser realizadas por diferentes contas, evita que o local originalmente utilizado para executar o comando SELECT seja utilizado para executar o comando INSERT, UPDATE ou DELETE.
⑵ Use procedimentos armazenados para executar todas as consultas. A forma como os parâmetros SQL são passados impedirá que invasores usem aspas simples e hifens para realizar ataques. Além disso, também permite que as permissões do banco de dados sejam restritas para permitir a execução apenas de procedimentos armazenados específicos. Todas as entradas do usuário devem estar em conformidade com o contexto de segurança do procedimento armazenado chamado, de modo que seja difícil ocorrer ataques de injeção.
⑶ Limite o comprimento da entrada do formulário ou da string de consulta. Se o nome de login do usuário tiver no máximo 10 caracteres, não aceite mais de 10 caracteres inseridos no formulário. Isso aumentará muito a dificuldade para invasores inserirem códigos prejudiciais em comandos SQL.
⑷ Verifique a legalidade da entrada do usuário e certifique-se de que o conteúdo de entrada contenha apenas dados legais. A inspeção de dados deve ser realizada tanto no lado do cliente quanto no servidor - a validação do lado do servidor é realizada para compensar a frágil segurança do mecanismo de validação do lado do cliente.
Do lado do cliente, é perfeitamente possível que um invasor obtenha o código-fonte da página web, modifique o script que verifica a legalidade (ou exclua o script diretamente) e, em seguida, envie o conteúdo ilegal ao servidor por meio do formulário modificado. Portanto, a única maneira de garantir que a operação de verificação foi realmente executada é realizar a verificação também no lado do servidor. Você pode usar muitos dos objetos de validação integrados, como RegularExpressionValidator, que pode gerar automaticamente scripts do lado do cliente para validação e, claro, também pode inserir chamadas de método do lado do servidor. Se você não conseguir encontrar um objeto de validação pronto, você mesmo poderá criar um por meio do CustomValidator.
⑸ Criptografe e salve o nome de login do usuário, senha e outros dados. Criptografar os dados inseridos pelo usuário e depois compará-los com os dados salvos no banco de dados equivale a “esterilizar” os dados inseridos pelo usuário. Os dados inseridos pelo usuário não têm mais nenhum significado especial para o banco de dados, por isso evita. invasores injetem comandos SQL. A classe System.Web.Security.FormsAuthentication possui um HashPasswordForStoringInConfigFile, que é muito adequado para higienizar dados de entrada.
⑹ Verifique a quantidade de registros retornados pela consulta que extraiu os dados. Se o programa exigir apenas o retorno de um registro, mas o registro real retornado tiver mais de uma linha, isso será tratado como um erro.