Eficiência e segurança com consultas parametrizadas: prevenindo SQL Injection
Published: 2022-11-15 15:32:39

O que é uma consulta parametrizada e por que ela é indicada como forma para evitar SQL Injection?

Preparei esse conteúdo que traz um resumo sobre os benefícios desse método, mostrando como funciona e trazendo alguns exemplos tirados da OWASP.

## SQL Injection

Os ataques SQL Injection geralmente são baseados na manipulação maliciosa de campos ou parâmetros, fornecendo trechos de sintaxe SQL que serão inseridos em comando(s) para o banco de dados.

O uso de comandos SQL, na maioria das linguagens de programação, pode ser parametrizado com variáveis de ligação (bind variables).

A consulta parametrizada é um mecanismo muito importante para trazer segurança e eficiência ao uso de consultas SQL.

## Entendendo conceitos
Toda instrução SQL para ser processada por um servidor de banco de dados envolve as seguintes fases:

**Prepare**
Preparação da instrução SQL; validação de sintaxe e semântica; e montagem do plano de execução.

**Execute**
Execução efetiva da instrução SQL no banco de dados.

**Fetch**
Recuperação de cada linha retornada, apenas quando se trata de uma consulta.

**Vejamos um exemplo de uma instrução SQL comum:**

```
SELECT * FROM tabela WHERE coluna = valor
```

Nesse caso, valor é uma expressão que pode envolver constantes, outras colunas, ou ainda variáveis de ligação. 

A bind variable ou variável de ligação funciona como um parâmetro da instrução SQL, sendo um elo de ligação entre o servidor de banco de dados e o ambiente de programação ou interface de acesso que o utiliza, para a passagem de valores dinâmicos a cada execução do SQL.

## Ganhando eficiência

As variáveis de ligação (bind) são definidas na fase de preparação de uma instrução SQL. 

Essas variáveis permitem que uma instrução SQL seja preparada uma única vez pelo banco de dados e executada inúmeras vezes, mesmo com valores diferentes para estas variáveis. 

Esta “economia” da fase de preparação a cada execução representa um ganho de eficiência, no que tange tempo e recursos, na aplicação e no servidor de banco de dados.

## Trazendo segurança

Utilizar Prepared Statement para fornecer valores dinâmicos, os parâmetros, nas instruções de banco de dados também é uma solução para validação e segurança.

Valores atribuídos através de variáveis de ligação dispensam tratamento de caracteres especiais em strings e eliminam a possibilidade de uma SQL Injection. 

Além disso, a atribuição envolve validação do tipo de dados do valor fornecido, também útil para consistência de números e datas.

## Exemplos da OWASP

A OWASP possui um documento importante para desenvolvedores entenderem como prevenir SQL Injection, [veja aqui](https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html). Nesse documento são apresentados alguns exemplos de código utilizando esse método, como podem ver a seguir:

**Exemplo de prepared statement para Java:**

```
// This should REALLY be validated too
String custname = request.getParameter("customerName");
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement( query );
pstmt.setString( 1, custname);
ResultSet results = pstmt.executeQuery( );
```

**Exemplo de prepared statement em C#**

```
String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
try {
  OleDbCommand command = new OleDbCommand(query, connection);
  command.Parameters.Add(new OleDbParameter("customerName", CustomerName Name.Text));
  OleDbDataReader reader = command.ExecuteReader();
  // …
} catch (OleDbException se) {
  // error handling
}
```

Além disso, outras medidas são muito importantes e também devem ser usadas sempre pelo desenvolvedor tais como: Stored Procedures; Allow-list Input Validation; Escaping All User-Supplied Input. Todas as medidas são explicadas com detalhes na documentação OWASP.

## Importância da codificação segura

Portanto, há grandes vantagens no uso de consultas parametrizadas e prepared statement, tanto para eficiência quanto para segurança.

A codificação segura ajuda a eliminar vulnerabilidades comuns, como SQL Injection, em suas aplicações logo no início. Então sempre bom recomendar seguir as melhores práticas e diretrizes de segurança.

Além disso, otimiza a segurança desde o início como parte da abordagem Shift-Left.

Referências:
https://bit.ly/3eu76go
http://www.mhavila.com.br/topicos/bd/sqlbind.html