Pular para o conteúdo
~/.primo-academy.sh
☰ Aulas · Engenharia assistida por IA: Claude Code, Cursor, Copilot, audit, testes e refactor · 0/8
Recomendado: essencial

Ler código gerado: como auditar diff, red flags, segurança, performance

4 min de leitura

fonte

Você aceitou um diff de 200+ linhas que IA gerou. Funciona (testes passam). Manda pro PR. Aí vem o reviewer: "isso aqui tem 3 problemas de segurança". Esse nó cobre como auditar código gerado por IA - checklist de red flags, patterns de segurança, performance, e como não cair em armadilhas.

IA gera código que parece certo mas tem falhas sutis: SQL injection, XSS, algoritmo O(n²) em vez de O(n log n), dependencies desatualizadas com CVE. Sem revisar, você herda a vulnerabilidade. Review não é opcional.

Você sai de "aceito código gerado" pra "aceito depois de auditar com checklist".

O essencial 🟢

O checklist dos 7 red flags. Antes de aceitar diff gerado por IA, rode este checklist:

  1. Segurança: SQL injection? XSS? CSRF? Secret hardcoded?
  2. Input validation: Inputs são validados (zod, yup, io-ts)?
  3. Auth/authz: Permissoes verificadas? Token validado?
  4. Error handling: Try/catch adequado? Errors não silenciosos?
  5. Performance: O(n²) em vez de O(n)? Loop aninhado desnecessário? Memory leak (setInterval não cleared)?
  6. Dependencies: Pkg novo? CVE conhecido? Licença OK?
  7. Edge cases: null/undefined? array vazio? string vazia? número negativo? Unicode?

Cada item = 1-2 min de review. Total: 10-15 min por PR de 200 linhas. Vale a pena.

Os 3 bugs de segurança mais comuns em código gerado por IA.

  1. SQL injection. IA gera query com template literal.

    // ❌ Vulnerável
    const user = await db.query(
      `SELECT * FROM users WHERE id = ${userId}`
    );
    
    // ✅ Seguro
    const user = await db.query(
      "SELECT * FROM users WHERE id = $1",
      [userId]
    );
    
  2. XSS (Cross-Site Scripting). IA gera render sem escape.

    // ❌ Vulnerável
    <div dangerouslySetInnerHTML={{ __html: userInput }} />
    
    // ✅ Seguro
    <div>{userInput}</div>  // React escapa automático
    
  3. Secret hardcoded. IA gera código com credenciais.

    // ❌ Vulnerável
    const apiKey = "sk-abc123hardcoded";
    
    // ✅ Seguro
    const apiKey = process.env.OPENAI_API_KEY;
    

Checklist de performance.

  • Big O: loop dentro de loop = O(n²). Hash map / Set para lookup O(1).
  • Memory: setInterval não cleaned, addEventListener não removed, referência circular.
  • Network: N+1 queries, falta cache, falta de paginação.
  • Render: re-render desnecessário (React), loop gigante no template.

Checklist de edge cases.

- null / undefined
- array vazio []
- string vazia ""
- número 0
- número negativo
- NaN, Infinity
- Unicode (emoji, RTL)
- timezone (UTC vs local)
- locale (pt-BR vs en-US)
- input muito grande (>1MB)
- concurrent updates

O pattern: "trust but verify". IA gera código que parece correto. Você verifica com:

  1. Ler o diff (não aceitar sem ler).
  2. Rodar testes (IA gera teste? Confia? Escreve o seu).
  3. Type check (TypeScript salva).
  4. Lint (ESLint/Biome pega patterns ruins).
  5. Code review (1 outro humano revisa).
  6. Test em prod (canary, feature flag, monitor).

Como ler um diff grande (200+ linhas) eficientemente. Não leia linha por linha. Estratégia:

  1. Visão geral: olhe a estrutura (quais arquivos? quais funções novas? quais deletadas?).
  2. Pontos de entrada: main, index, exports públicos.
  3. Lógica nova: funções/classes adicionadas (diff +).
  4. Mudanças críticas: arquivos de segurança (auth, payment, API routes).
  5. Testes: novos testes = bom sinal. Testes mudados sem justificativa = red flag.

Ferramentas de audit.

  • git diff --stat: visão geral do tamanho.
  • git diff --check: warnings de whitespace.
  • CodeQL (GitHub): scan automático de segurança no PR.
  • Snyk / Dependabot: scan de vulnerabilities em dependencies.
  • ESLint + plugins: patterns ruins (security, performance).
  • Semgrep: static analysis customizável.

Checklist de dependencies.

# Pkg novo adicionado
git diff package.json
# Pergunte:
# 1. Esse pkg é necessário? (N+1 deps)
# 2. Tem CVE conhecido? (npm audit)
# 3. Licença compatível? (MIT, Apache, etc)
# 4. Maintainer ativo? (último commit)
# 5. Bundle size? (bundlephobia)
# 6. Alternatives? (mature, popular)

O erro mais comum: aceitar código de IA "porque funciona". "Funciona" não significa "correto". Funciona no caminho feliz. Falha em: segurança, performance, edge cases, acessibilidade. Audit antes de aceitar.

Checklist visual de código aceitável.

[ ] Lido TODO o diff (não skim)
[ ] Sem SQL injection (queries parametrizadas)
[ ] Sem XSS (escape user input)
[ ] Sem secret hardcoded (env vars)
[ ] Inputs validados (zod, yup)
[ ] Error handling adequado (try/catch + log)
[ ] Performance O(n) ou O(n log n), não O(n^2)
[ ] Memory: intervals/listeners cleaned
[ ] Edge cases: null, vazio, Unicode
[ ] Tests: novos testes OU testes existentes passam
[ ] Type check: 0 erros
[ ] Lint: 0 errors
[ ] Dependencies: 0 CVEs (npm audit)
[ ] Accessibility: ARIA, contraste, keyboard
[ ] License: MIT/Apache, não GPL em projeto proprietário

Aprofundamento 🟡

Diff de 200+ linhas: como revisar sem perder detalhe. Estrategia 3-pass:

  1. Pass 1 - Contexto (5 min): git diff --stat, leia commit message, leia descrição do PR. Entenda a intenção antes de auditar código.

  2. Pass 2 - Hot paths (10 min): Foque em security-critical: auth, payment, API routes, file upload, query strings, eval/Function. CodeQL ou Semgrep scan automático aqui.

  3. Pass 3 - Logic (15 min): Foque em lógica nova (funções adicionadas) e mudanças em funções existentes (refactor). Rode testes local. Type check.

Total: 30 min por PR grande. Vs 10 min pra PR pequeno. Trade-off aceitável.

Como auditar código de auth especificamente. Red flags específicos:

// 1. Token em localStorage (XSS rouba)
localStorage.setItem("token", jwt);  // ❌

// 2. Auth check no client (bypass)
if (user.role === "admin") showAdminPanel();  // ❌

// 3. JWT sem verificar signature
const user = jwt.decode(token);  // ❌
const user = jwt.verify(token, SECRET);  // ✅

// 4. Permissoes baseadas em user.id
if (req.params.id === user.id) updateUser();  // ❌ race condition
// ✅ Server-side: verificar role + ownership

Como auditar código de payment.

// 1. Trust no client-side price
const amount = req.body.amount;  // ❌ user manipula
const amount = product.price;    // ✅ server-side lookup

// 2. Idempotency ausente
if (!paymentExists(orderId)) {
  await charge(orderId);
}  // ❌ double charge em retry
// ✅ Use idempotency key

// 3. Amount sem validar
if (amount > 0) charge(amount);  // ❌
if (amount > 0 && amount < MAX_AMOUNT) charge(amount);  // ✅

CodeQL e Semgrep. Ferramentas static analysis que rodam no PR (GitHub Actions) e acham bugs conhecidos:

# GitHub Actions
- uses: github/codeql-action/analyze@v2
  with:
    languages: javascript

CodeQL acha SQL injection, XSS, path traversal, unsafe deserialization. Semgrep é customizável (rules escritas em YAML).

AI auditor: 2-pass com 2 LLMs. Pattern: LLM A gera código, LLM B revisa (Claude gera, GPT revisa, ou vice-versa). Bugs que LLM A perdeu (por ser o autor) são pegos por LLM B (sem viés de autor). Em 2026, +30% bugs pegos com 2-pass vs 1.

Leitura recomendada:

Dica: o erro mais comum em AI coding é aceitar código sem auditar. "Funciona" != "correto". 10-15 min de checklist por PR grande = evita SQL injection, XSS, O(n²), secret hardcoded. IA gera 80% do código, você audita 20% - a parte crítica é a auditoria. Sem audit, IA é vetor de ataque: o atacante manipula o prompt ou explora alucinação conhecida (lib inexistente, CVE). Audit é obrigatório.

No próximo nó, vamos IA no test: como gerar testes com IA, validar que não são teatro (testa "implementação" mas não lógica), e garantir que testes pegam bugs reais.

// Quiz

Qual o erro mais comum ao aceitar código gerado por IA e como evitar?

Escolha uma alternativa

// recursos

// avaliação da trilha

—
ainda sem avaliações