Logotipo do ConstructiCat
CodeBust.
Explorar a seção ▾

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/fetch sem 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 input ou // TODO: add auth fica 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 de process.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 validador orderSchema — 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 audit e sua configuração de eslint-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