> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.squarecloud.app/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# SQL injection: O que é e como se proteger?

## O que é SQL Injection?

O SQL Injection (SQLi) continua no topo das vulnerabilidades mais perigosas da web por um motivo simples: ele é fácil de explorar e devastador para o negócio. O ataque acontece quando a aplicação aceita dados do usuário e, em vez de tratá-los apenas como informação, acaba concatenando tudo direto na string da consulta SQL. Com isso, o banco interpreta o texto malicioso como se fosse uma ordem do próprio sistema.

Se o seu sistema junta variáveis de formulários ou URLs direto na query, você basicamente abriu a porta para que qualquer um acesse, modifique ou apague seus dados sensíveis.

## O ataque na vida real

Pensando em um sistema de autenticação comum, a aplicação recebe o e-mail digitado e monta a busca. Se um atacante preencher o campo de e-mail com o seguinte valor:

`'admin@exemplo.com' OR '1'='1'`

A query processada pelo servidor vai ficar assim:

```sql
SELECT * FROM usuarios WHERE email = 'admin@exemplo.com' OR '1'='1' AND senha = '...';
```

Como a condição `'1'='1'` é sempre verdadeira, o banco de dados ignora o restante da validação. O atacante consegue burlar a checagem da senha e ganha acesso direto à conta do administrador.

## Como proteger seu código passo a passo

A regra de ouro do desenvolvimento seguro é universal: **nunca confie no que vem do usuário**. Abaixo, veja como aplicar as principais defesas usando Node.js e Python.

### Consultas Parametrizadas (Prepared Statements)

Essa é a linha de defesa mais importante. Em vez de montar strings dinâmicas, você define a estrutura da query primeiro e passa os dados do usuário como argumentos isolados. O driver do banco de dados garante que esses parâmetros sejam tratados estritamente como valores textuais, neutralizando qualquer comando oculto.

#### Exemplo em JavaScript (Node.js + pacote `pg`)

```javascript
// DO JEITO ERRADO: Concatenação perigosa
const query = `SELECT * FROM usuarios WHERE email = '${req.body.email}'`;
const result = await pool.query(query);

// DO JEITO CERTO: O driver isola o conteúdo de $1
const query = 'SELECT * FROM usuarios WHERE email = $1';
const values = [req.body.email];
const result = await pool.query(query, values);
```

#### Exemplo em Python (driver `psycopg2`)

```python
# DO JEITO ERRADO: Formatação de string gera a query antes do envio
query = f"SELECT * FROM usuarios WHERE email = '{user_input}'"
cursor.execute(query)

# DO JEITO CERTO: Os dados vão separados da estrutura da query
query = "SELECT * FROM usuarios WHERE email = %s"
cursor.execute(query, (user_input,))
```

*Nota: Mesmo que o Python use `%s` ou `?` no texto da query, isso não é uma interpolação comum de strings. O driver envia o comando e os parâmetros em canais separados para o banco.*

### Validação e Sanitização da Entrada

Barrar o problema antes mesmo que ele chegue perto do banco de dados economiza processamento e aumenta a segurança. Garanta que o dado recebido segue o formato esperado pela aplicação.

#### Validação em Node.js
```javascript
// Forçando a conversão para garantir um número inteiro na rota
const userId = parseInt(req.params.id, 10);

if (isNaN(userId)) {
    return res.status(400).json({ error: "ID inválido." });
}
```

#### Validação em Python
```python
import re

# Checando o formato do e-mail com expressão regular antes de usar na busca
email_pattern = r"^[\w\.-]+@[\w\.-]+\.\w+$"

if not re.match(email_pattern, user_input):
    raise ValueError("Formato de e-mail inválido.")
```

### Ecossistema de ORMs Atualizados

Ferramentas de ORM modernas lidam com a parametrização de forma nativa por baixo dos panos na maior parte das chamadas.

* **No ecossistema JS (Sequelize, Prisma):** Consultas estruturadas via `User.findOne({ where: { email } })` já nascem protegidas.
* **No ecossistema Python (SQLAlchemy, Django ORM):** Métodos como `User.objects.filter(email=user_input)` barram o SQLi automaticamente.

Fique atento se precisar escrever queries brutas (raw SQL) dentro desses frameworks. Funções como `db.execute("SELECT...")` perdem a proteção automática e exigem parametrização manual idêntica aos exemplos anteriores.

Substituir a concatenação de strings por consultas parametrizadas resolve a imensa maioria dos riscos de SQL Injection. Unir essa prática com a validação rigorosa dos payloads recebidos blinda o ecossistema e garante a integridade dos dados da aplicação.