← Curso IA na prática para Programadores: do prompt ao pull request 22 aulas
Depurar por evidência e revisar por risco

Falso positivo de segurança e a otimização que piora

Armadilha 7 min de leitura

Três achados que parecem graves e não são, e três "otimizações" que deixam o código pior — com o critério para separar em cada caso.

Aceitar um falso positivo custa caro de um jeito silencioso: você muda código que estava certo, adiciona complexidade sem motivo e treina o time a acreditar em achados sem evidência.

Ao final desta aula você consegue
  • Reconhecer os falsos positivos mais comuns em segurança.
  • Exigir medição antes de aceitar sugestão de performance.
  • Responder a um achado com evidência em vez de obediência.

Três falsos positivos clássicos de segurança

O achadoPor que costuma ser falsoO que confirma de verdade
"Injeção de SQL" em query com nome de coluna dinâmicoSe a coluna vem de uma lista fechada no código, não há entrada não confiávelRastrear a origem do valor até o request
"Uso de MD5 é inseguro"MD5 para checksum de arquivo ou chave de cache não é uso criptográficoVer se o valor protege algo ou só identifica
"XSS" em template que já escapa por padrãoVários motores escapam automaticamente; o achado ignora issoTestar com payload real no ambiente
O achado
BLOQUEANTE — Injeção de SQL em ordenacao():
$sql .= " ORDER BY $coluna $direcao";

Variável concatenada diretamente na query.

Parece grave e é um padrão que realmente costuma ser grave.

O código completo
const COLUNAS = ['nome', 'criado_em', 'valor'];

$coluna  = in_array($req['ordenar'], COLUNAS, true)
    ? $req['ordenar'] : 'criado_em';
$direcao = strtoupper($req['dir']) === 'ASC' ? 'ASC' : 'DESC';

$sql .= " ORDER BY $coluna $direcao";

O valor só pode ser um de quatro literais definidos no código. Não há caminho da entrada do usuário até a query.

A diferença: O achado olhou a linha; o risco depende das três linhas anteriores. É o limite estrutural de revisar por trecho: quem revisa precisa rastrear a origem do valor, e é isso que o pedido da aula anterior chama de "cenário concreto de falha".

Falso positivo não significa código bom

No exemplo acima, o código é seguro e ainda assim melhoraria com a lista de colunas e a ordenação centralizadas — porque a próxima pessoa que mexer pode não repetir a validação.

Recusar o achado como bloqueante e aceitá-lo como sugestão de manutenção é uma resposta melhor que qualquer um dos extremos.

Três otimizações que pioram

Sugestão: "adicione um índice em status"
CREATE INDEX idx_status ON pedidos(status);

A coluna tem 3 valores distintos em 8 milhões de linhas. O otimizador vai ignorar o índice, e você paga escrita mais lenta e espaço em disco por nada.

O que medir antes
EXPLAIN SELECT ... WHERE status = 'pendente' AND criado_em > ?;

-- Se o filtro real combina status com data, o índice útil
-- é composto, na ordem em que a query filtra:
CREATE INDEX idx_status_data ON pedidos(status, criado_em);

Índice que o otimizador realmente usa, escolhido a partir da query real e não do nome da coluna no WHERE.

A diferença: Sugestão de índice sem EXPLAIN é palpite. Índice tem custo permanente de escrita — aceitar um que não é usado é piorar o sistema com aparência de melhoria.

  • Micro-otimização que troca clareza por nada: substituir um laço legível por uma expressão encadeada de três níveis que roda 2% mais rápido em código que executa dez vezes por dia.
  • Cache adicionado sem política de invalidação: resolve a lentidão hoje e cria um bug de dado velho na semana que vem, que é muito mais caro de diagnosticar.
  • Paralelização sem medir onde está o tempo: se 90% do tempo é uma query, paralelizar a formatação da resposta não muda nada além do risco.
Respondendo a um achado — em vez de obedecer
Você reportou este achado:
[cole o achado]

Antes de eu aceitar, responda:
1) Qual é o caminho completo do dado não confiável até o ponto vulnerável?
   Cite cada linha do trecho abaixo que faz parte desse caminho.
2) Escreva a entrada exata que exploraria isso.
3) O que no código impede essa entrada de chegar lá? Se nada impede, mostre.
4) Se for performance: qual medição sustenta a sugestão e qual seria o
   ganho estimado em números?

Se você não conseguir responder 1 e 2 com precisão, retire o achado.

Código completo do contexto:
[cole as funções envolvidas, não só a linha]

Colar o contexto completo é metade da solução: a maioria dos falsos positivos de segurança vem de revisar uma linha sem ver a validação que está três linhas acima.

ArmadilhaO custo de treinar o time a obedecer

Quando achados são aceitos sem verificação, duas coisas acontecem juntas. O código acumula complexidade defensiva desnecessária. E as pessoas param de distinguir achado real de ruído — o que faz um achado grave passar despercebido no meio de vinte irrelevantes.

A regra que sustenta isso: nenhum achado vira mudança sem cenário concreto de falha ou medição. Vale para achado de ferramenta, de IA e de colega.

Como perceber: Alguém no time diz "melhor mudar, vai que" sobre um achado que ninguém conseguiu reproduzir.

Checagem antes de seguir
  • Todo achado de segurança tem o caminho do dado rastreado até a origem.
  • Existe uma entrada concreta que exploraria a falha.
  • Toda sugestão de performance tem medição antes e estimativa de ganho.
  • Nenhum índice foi criado sem EXPLAIN.
  • Nenhum cache foi adicionado sem política de invalidação escrita.
Em uma frase
  • Sem cenário reproduzível ou medição, um achado é hipótese — e hipótese não vira commit.

Comentários e dúvidas

Inscreva-se grátis para comentar, tirar dúvidas, marcar seu progresso e emitir o certificado ao fim do curso.

Inscrever-se grátis com Google

Ainda não há comentários nesta aula.