FlawOpen

flawopen.com/SQL Injection/Escapar aspas basta?

Escapar aspas impede SQL Injection?

CWE-89: SQL InjectionReference page
Resposta curta

Geralmente, não. Uma função de escaping depende do banco, do charset da conexão, do modo SQL e do contexto exato das aspas. Consultas parametrizadas mantêm valores fora da sintaxe SQL por meio da API do driver. Use parâmetros para valores; para identificadores dinâmicos que não aceitam parâmetros, escolha uma opção de uma allowlist controlada pela aplicação.

Por que o escaping é frágil na prática

O charset da conexão afeta o escaping

Escaping não é uma simples substituição de texto. Por exemplo, o MySQL documenta que mysql_real_escape_string() usa o charset da conexão e que SET NAMES não atualiza o estado da biblioteca cliente usado por essa função. Uma divergência de charset pode invalidar as premissas sobre o texto escapado. Prefira APIs parametrizadas; se código legado ainda precisar escapar, use a API do driver com charset configurado pela função suportada e trate os erros.

Uma chamada esquecida compromete a defesa

O escaping precisa ser aplicado corretamente em cada ponto de interpolação, com driver, charset, modo SQL e contexto de string literal adequados. APIs parametrizadas deixam explícita a separação entre valor e dado na chamada e evitam montar manualmente uma string entre aspas.

Escapar aspas não cobre todos os contextos SQL

Escapar aspas trata apenas caracteres dentro de uma string literal específica. Isso não constrói com segurança expressões como nome de coluna, tabela, palavra-chave ou direção de ordenação, nem protege entrada usada em expressões numéricas sem aspas. Vincule valores e mapeie a estrutura dinâmica para opções fixas controladas pela aplicação.

VULNERABLE
// A entrada do usuário é interpolada na sintaxe SQL
query = f"SELECT id FROM users WHERE name = '{name}'"
cursor.execute(query)
HARDENED
// O driver vincula name como um valor de dados
cursor.execute(
    "SELECT id FROM users WHERE name = ?",
    (name,),
)

O que a vinculação de parâmetros faz diferente

Uma consulta parametrizada passa a estrutura SQL e os valores como entradas separadas pela API do banco. Drivers podem usar prepared statements nativos ou outra implementação segura; não presuma uma sequência específica no protocolo. A propriedade de segurança é tratar o valor como dado, não como sintaxe SQL a ser analisada novamente. Na API Python DB-API, por exemplo, use o placeholder do driver e passe os valores em separado; nunca monte a consulta com formatação de strings.

Checklist de engenharia

Perguntas frequentes

Escaping ainda pode ser a ferramenta certa?

Para identificadores ou fragmentos SQL que não aceitam parâmetros, use apenas uma API de quoting suportada pelo driver junto a uma allowlist fixa da aplicação. Não aplique escaping genérico a valores arbitrários.

Se a função de escaping do driver é mantida, ela é segura?

Uma função mantida pelo driver pode ajudar no contexto documentado, mas continua dependente do banco, das configurações da conexão, do contexto de quoting e do uso correto em cada ponto. Consultas parametrizadas são o padrão mais seguro para valores.

Referências

Veja também SQL Injection (CWE-89): como funciona e como evitar em todas as linguagens — flawopen.com Usar um ORM basta para prevenir SQL Injection? Knex.js é seguro contra SQL Injection? MyBatis ${} vs #{}: evitar SQL Injection MySQLi vs PDO: prepared statements seguros NHibernate protege contra SQL Injection? MongoDB NoSQL Injection: filtros de consulta seguros