Ponto Cego de Segurança.
Assistentes de IA produzem código funcional que silenciosamente omite os controles de segurança que um humano adicionaria por hábito — validação de entrada, autorização, codificação de saída, tratamento de segredos — porque "compila e retorna 200" parece estar pronto.
##Sinais e sintomas
Um revisor identifica um Ponto Cego de Segurança quando o código funciona no caminho feliz, mas os controles que um humano consciente de segurança adiciona por reflexo simplesmente não estão presentes. O modelo demonstra a funcionalidade, não a defesa. Sinais reveladores:
- Consultas / comandos concatenados como strings em vez de parametrizados (pontos de injeção de SQL/comando/LDAP).
- Entrada do usuário flui para a saída sem codificação (XSS refletido/armazenado) ou para
fs/child_process/fetchsem allow-list (path traversal, SSRF). - O endpoint autentica mas nunca autoriza — ele verifica quem você é, nunca se você pode acessar este registro (IDOR / autorização quebrada em nível de objeto).
- Segredos embutidos no código — chaves de API, tokens, senhas de banco de dados inline "para fazer funcionar."
- Controles ausentes por omissão: sem token CSRF, sem cabeçalhos de segurança, sem limite de taxa, criptografia fraca/legada (MD5, SHA-1,
Math.random()para tokens). - Teatro de comentários: um comentário
// validate inputou// TODO: add authfica onde deveria estar a verificação real. A OX Security encontrou comentários inline excessivos ("Comments Everywhere") em 90–100% do código gerado por IA que estudou; neste smell, esse comentário muitas vezes ocupa o lugar da lógica que falta.
// Handler Express gerado por IA — parece completo, entrega quatro brechas
app.get("/api/orders/:id", authMiddleware, async (req, res) => {
const apiKey = "sk_live_8f3b2a91c7d44e0f"; // 1. segredo embutido no código
const { rows: [order] } = await db.query(
`SELECT * FROM orders WHERE id = ${req.params.id}` // 2. injeção de SQL
);
res.send(`<h1>Order for ${order.customerName}</h1>`); // 3. XSS refletido
// 4. IDOR: authMiddleware comprova o login, nunca verifica order.userId === req.user.id
});
Quatro vulnerabilidades distintas, zero testes falhando — o smell é o que não está ali.
##Causas do problema
Por que os modelos produzem isso
- O alvo do treinamento é plausibilidade, não segurança. A predição do próximo token otimiza para a forma mais comum de escrever código, e os corpora públicos estão saturados de trechos de tutorial com consultas concatenadas e sem autorização. O post da OX Security sobre segurança no vibe coding diz sem rodeios: "A concatenação de strings é o que aparece com mais frequência nos dados de treinamento." No benchmark SusVibes da Carnegie Mellon, com 200 tarefas reais de desenvolvimento de funcionalidades, o SWE-Agent com Claude 4 Sonnet produziu soluções funcionalmente corretas em cerca de 61% das vezes, mas seguras em apenas cerca de 10,5%.
- "Pronto" é definido pelo caminho feliz. Um LLM otimiza para que a requisição visível funcione. Controles de segurança não produzem nenhum sinal positivo numa execução rápida — uma verificação ausente não faz nenhum teste falhar nem quebra nenhuma demo —, então são descartados.
- Sem contexto do repositório. O modelo não consegue ver seu helper
authorize(), seu esquema de validação ou seu gerenciador de segredos, então ele insere uma chave literal no código ou pula a verificação em vez de reutilizar um controle existente. - Bajulação + velocidade. Ele retorna exatamente o que você pediu ("adicione um endpoint de pedidos"), não o modelo de ameaças em torno disso, e gargalos como revisão e modelagem de ameaças são justamente o que o desenvolvimento em velocidade de IA elimina. A principal constatação da OX Security é que o código gerado por IA não contém mais vulnerabilidades por linha do que o escrito por pessoas; o que leva código vulnerável para produção é a velocidade, porque "uma revisão de código adequada simplesmente não consegue escalar no ritmo da nova velocidade de produção". A OX também alerta para aplicações "inseguras por ingenuidade" (insecure by dumbness): construídas com IA e publicadas por usuários não técnicos, sem a experiência em segurança necessária para perceber o que está faltando.
- Defasagem do corte de treinamento. Os modelos recorrem a padrões de criptografia e de bibliotecas que eram adequados anos atrás (MD5, SHA-1, opções de TLS descontinuadas, fluxos de autenticação antigos).
Por que isso é prejudicial
- Explorabilidade direta. O 2025 GenAI Code Security Report da Veracode (80 tarefas de programação, mais de 100 LLMs) encontrou falhas de segurança em 45% dos casos, e os modelos não se defenderam contra cross-site scripting (CWE-80) em 86% dos casos. A CodeRabbit encontrou vulnerabilidades XSS 2,74 vezes mais em pull requests coescritos com IA do que nos escritos só por pessoas; a Tenzai constatou que nenhum dos 15 apps construídos por cinco agentes de código tinha proteção contra CSRF ou definia cabeçalhos de segurança; a Escape.tech encontrou mais de 400 segredos expostos em mais de 5.600 apps feitos com vibe coding.
- Invisível para testes e para leitores. Uma verificação de autorização ausente não tem teste que falhe nem diff para apontar, então passa direto pela revisão — e o volume de saída da IA significa que a revisão não consegue escalar para detectá-la.
- Dívida técnica que se acumula. A análise de 2025 da GitClear sobre 211 milhões de linhas alteradas mostrou que as linhas associadas a refatoração ("movidas") caíram de 25% das linhas alteradas em 2021 para menos de 10% em 2024, enquanto as linhas copiadas e coladas subiram de 8,3% para 12,3% e, em 2024, superaram as movidas pela primeira vez; blocos com cinco ou mais linhas duplicadas cresceram cerca de oito vezes durante 2024. O mesmo padrão inseguro é clonado pela base de código, multiplicando o raio de impacto de cada ponto cego.
##Tratamento
Táticas de revisão e de prompting
- Nomeie o modelo de ameaças no prompt. "Escreva este endpoint assumindo que o
idé controlado por um atacante; imponha autorização em nível de objeto, parametrize todas as consultas, codifique toda a saída e leia os segredos deprocess.env." Especificar o adversário inverte o padrão. - Force a reutilização de controles existentes. "Use nosso helper
authorize(user, 'order', id)e o validadororderSchema— não escreva uma nova validação." Isso combate diretamente a causa da falta de contexto do repositório (e o smell relacionado Código Duplicado). - Faça o modelo executar as ferramentas. Exija que ele rode
semgrep --config p/owasp-top-ten,gitleaks detect,npm audite sua configuração deeslint-plugin-security, e então corrija o que for sinalizado, antes de declarar concluído. - Peça os negativos explicitamente. "Liste as preocupações de autenticação, autorização, validação de entrada, codificação de saída e segredos para este handler e mostre onde cada uma é aplicada." Um espaço em branco nessa lista é o bug.
- Modele ameaças sobre o diff, não sobre a linha. As brechas perigosas são omissões, então revise perguntando "qual controle deveria estar aqui e não está?" em vez de procurar por linhas ruins.
A refatoração — parametrize a consulta (elimina a injeção), codifique a saída (elimina o XSS), adicione uma verificação de autorização em nível de objeto (elimina o IDOR) e leve o segredo embutido para a configuração:
// DEPOIS
app.get("/api/orders/:id",
authMiddleware,
validate(orderParamsSchema), // validação de entrada
async (req, res) => {
const { rows: [order] } = await db.query(
"SELECT * FROM orders WHERE id = $1", [req.params.id] // parametrizado
);
if (!order || order.userId !== req.user.id) { // autorização em nível de objeto
return res.sendStatus(404);
}
res.json({ customerName: order.customerName }); // saída estruturada, codificada automaticamente
}
);
// segredo: process.env.STRIPE_API_KEY, carregado uma vez na inicialização, nunca inline
Onde o smell se espalhou por clonagem, corrija uma vez e aplique Extrair Método ao controle (requireOrderOwnership, escapeHtml) para que cada ponto de chamada compartilhe uma única implementação auditada em vez de N cópias.
##Detectado por
- Gitleaks generic-api-key — Segredos definidos diretamente no código / generic-api-key
- Semgrep p/owasp-top-ten — p/owasp-top-ten (por exemplo, sql-injection, xss, uso perigoso de strings de formatação)
- GitHub CodeQL js/sql-injection, js/xss, js/hardcoded-credentials, js/path-injection
- eslint-plugin-security detect-non-literal-fs-filename, detect-child-process, detect-eval-with-expression, detect-object-injection
- Bandit (Python) B105 / B608 / B324 — B105 hardcoded_password_string, B608 hardcoded_sql_expressions, B324 fraco hashlib
- SonarQube / SonarSource Security Hotspots / Vulnerability — Regras de revisão de segurança e vulnerabilidades (injeção, criptografia fraca, credenciais definidas no código)
- npm audit / OWASP Dependency-Check npm audit / OWASP Dependency-Check — Detecção de dependência conhecidamente vulnerável