SQL Injection: Porque é que ainda é um problema em 2022?

Inês Sucena
labmm4a
Published in
7 min readNov 28, 2022

A comunidade afirma constantemente que SQL Injection é simples de resolver, mas a realidade é que ao fim de 20 anos de se saber da sua existência e como evitar, ainda continua a ser um problema presente.

De acordo com o OWASP, os ataques do tipo injeção são considerados o terceiro risco de segurança mais grave desde 2021, sendo que das aplicações testadas foram encontradas 274 000 ocorrências de injeções.

(fonte: imagem)

Neste sentido, torna-se cada vez mais relevante perceber como é que estes ataques podem ocorrer. Este conhecimento permite que se desenvolvam aplicações e sites que não sejam vulneráveis e consequentemente diminuir este problema.

Antes de explicar o que é uma injeção de SQL é importante compreender o que é SQL. SQL, significa “Structured Query Language” e é uma linguagem utilizada para fazer qualquer tipo de manipulação de registos de uma base de dados relacional. Ou seja, serve para criar, inserir, excluir e consultar as informações armazenadas na base, além de outras funções mais complexas como: gestão de utilizadores, permissões, gestão de bases de dados e gestão de recursos de uma base de dados. As Bases de Dados relacionais são baseadas em SQL, uma vez que armazenam as informações em estruturas como tabelas, permitindo que seja possível criar relações entre si. A linguagem SQL foi criada para facilitar a gestão dos dados armazenados em BD que seguem o padrão mencionado anteriormente.

O que é SQL Injection?

A injeção de SQL é um tipo de ataque de segurança cibernética que consiste na exploração de vulnerabilidades de sites ou aplicações através de entradas de dados. Os hackers tendem a utilizar os campos de inputs para inserir comandos de SQL de modo a induzir o sistema da BD a executar ações indesejadas, como mostrar, alterar ou mesmo apagar dados. Estes ataques podem, por exemplo, ocorrer em páginas de login quando é solicitado o username e/ou a password ao utilizador ou mesmo nos campos de pesquisa. O que acontece exatamente é que ao invés deste colocar a informação que é pedida, insere uma parte de uma query que, em conjugação com as queries implementadas no sistema, vão executar instruções para as quais não tinham sido construídas. Ou seja, utilizam uma query existente para através de SQL Injection provocar um outro tipo de comando, como se pode verificar no exemplo abaixo.

Figura 1 — exemplo prático de SQL Injection (fonte: w3schools).

A condição apresentada será sempre verdadeira o que vai permitir que o hacker tenha acesso a todos os users e passwords, porque o código existente no servidor gera um statement de SQL válido. Neste sentido, o hacker pretender aceder a esta informação, uma vez que o primeiro user de uma BD, por norma, é o administrador. Assim sendo, o objetivo principal do ataque consiste em ficar com o login do administrador.

Consequências

Os ataques provocam problemas em diversas dimensões, como para a entidade, para os utilizadores e a nível da BD. As consequências mais relevantes que os ataques podem provocar são:

  • Exposição de dados confidencias das entidades/empresas;
  • Comprometimento da privacidade dos utilizadores (revelação de dados privados e pessoais, como por exemplo, números de cartão de crédito);
  • Fornecimento do acesso administrativo do sistema ao hacker, caso a BD tenha privilégios administrativos;
  • Acesso geral ao sistema por parte do hacker (como por exemplo, se forem utilizados comandos de SQL fracos para a verificação de utilizadores ou passwords é possível aceder ao sistema sem utilizar as credencias de utilizador);
  • Comprometimento da integridade dos dados, uma vez que os ataques podem provocar alterações ou eliminar informação da BD, comprometendo consequentemente a integridade da entidade.

Classes e Tipos de SQL Injection

As SQL Injections são classificadas de acordo com os métodos que são usados para aceder aos dados e o potencial dano. Neste sentido podem ser divididas em três categorias: In-band SQLi, Inferential SQLi e Out-of-band SQLi.

1) In-band SQLi (Classic)

Tipo de ataque mais comum e fácil de aplicar, sendo que acontece quando o hacker consegue usar o mesmo canal para executar o ataque e obter os seus resultados. Esta classe pode ser subdividida em duas variantes deste método: Error-based SQLi e Union-based SQLi.

  • Error-based SQLi - ocorre quando o ataque é baseado em erros, ou seja, o hacker executa ações que fazem com que a BD produza mensagens de erro. E essas mensagens contêm informação acerca da estrutura da BD que pode ser usada como facilitador de acesso à mesma.
  • Union-based SQLi - esta técnica aproveita o operador UNION SQL, que junta várias instruções de SELECT, para obter uma única resposta HTTP, que contém dados que podem ser usados a favor do hacker, como podemos ver no exemplo abaixo.
Figura 2 — exemplo de de SQL Injection do tipo Union-based SQLi (fonte: Researchgate)

2) Inferential SQLi (Blind)

Este tipo de ataque depende da resposta e dos padrões comportamentais do servidor, logo é um processo mais demorado para executar. A execução corresponde ao envio de uma quantidade significativa de dados para o servidor de modo a conseguir obter uma resposta e um comportamento com o objetivo de aceder a mais informação sobre a sua estrutura. Os dois tipos de injeção de Inferential SQLi são: Blind-boolean-based SQLi e Blind-time-based SQLi.

  • Blind-boolean-based SQLi - técnica que consiste no envio de uma instrução para a base de dados que retornará sempre um valor, seja este verdadeiro ou falso, alterando ou mantendo o conteúdo da resposta HTTP dependendo da resposta que for adquirida. Este método permite ao hacker perceber através do HTTP se a resposta gerada é verdadeira ou não e assim concluir se a instrução inicial também o é, mesmo que não lhe tenha sido fornecida nenhuma informação da BD (ver exemplo abaixo).
Figura 3 — exemplo de SQL Injection do tipo Blind-boolean-based SQLi (fonte: Beagle Secutity)

Se o resultado obtido no segundo pedido for diferente do resultado feito no primeiro pedido, a página é vulnerável a SQL Injection.

  • Blind-time-based SQLi - quando o ataque é feito através do time, o hacker envia uma query para a BD provocando um tempo de espera até que esta consiga reagir. E é com base neste tempo que se consegue concluir se a resposta à query é verdadeira ou falsa. Quando é retornada a resposta é criado, com atraso ou imediatamente, uma resposta HTTP, permitindo assim ao hacker perceber se a query é verdadeira ou falsa. As técnicas de provocar um delay são diferentes dependendo da BD que está a ser utilizada. No caso da MySQL é utilizada a função sleep() como se pode verificar no exemplo abaixo.
Figura 4 — exemplo de SQL Injection do tipo Blind-time-based SQLi (fonte: Beagle Secutity)

Esta técnica permite recuperar dados através de testes sistemáticos a um caractere de cada vez.

3) Out-of-band SQLi

É apenas utilizado quando determinadas condições estão ativas, portanto é uma alternativa aos métodos mencionados anteriormente. É executado quando o hacker não consegue utilizar o mesmo canal para iniciar o ataque e obter a sua resposta, ou quando um servidor se encontra instável ou lento a nível do seu processamento. Ao invés disso, faz com que a base de dados envie a informação para um endpoint remoto em que tenha controlo, contudo, isto só é possível se o servidor tiver comandos que acionem os pedidos de DNS ou HTTP.

Figura 5 — Esquema do processo de SQL Injection de classe Out-of-band SQLi (fonte: Medium)

Porque é que SQL Injection ainda é um problema?

Apesar dos programadores continuarem a cometer falhas, múltiplas vezes, ao permitirem que existam vulnerabilidades no código, a culpa de SQL Injection ainda ser um problema atualmente, não é apenas deles.

O maior problema está no facto de as entidades não proporcionarem um ambiente em que incentivam à segurança, porque a segurança não é uma prioridade de negócio para as entidades. Esta filosofia faz com que os programadores não estejam tão conscientes da segurança, gerando assim falhas inconscientes e não intencionais, mas que contribuem para a manutenção do problema.

Outro motivo que leva a que existam falhas no código que permitem a execução de injeções, consiste no facto de serem dados prazos limitados que não permitem que se escreva código de alta qualidade. Isto porque, para se conseguir escrever código seguro é necessário tempo para que todas as vulnerabilidades possam ser testadas e descartadas.

Contudo, apenas quando a utilização de código seguro começar a evoluir e quando softwares, sistemas antigos e bibliotecas que continuam ativas forem atualizadas para que deixem de ser vulneráveis é que estes ataques vão deixar de ser um problema.

Soluções

Aquando a escrita do código deve-se ter em consideração as seguintes técnicas:

  • Usar prepared statements com queries parametrizadas;
  • Usar a validação de inputs permitidos;
  • “Escapar” todas as entradas fornecidas pelo utilizador;
  • Apesar de as mensagens de erro serem bastante úteis, estas devem ser desativadas ou reencaminhadas para um ficheiro com acesso restrito quando o site estiver online.

Existem ainda duas abordagens de testes de segurança: SAST (Static Application Security Testing) e DAST (Dynamic Application Security Testing), sendo que permitem detectar a possibilidade de existirem injeções de SQL. Estes testes são métodos automáticos, contudo também se pode usar o método manual que consiste em testar cada campo de forma manual.

--

--