2,526 palavras · 13 min de leitura
O Claude Code Security já estava disponível, você só não usava
Semana passada a Anthropic anunciou que vai lançar uma ferramenta de segurança integrada ao Claude Code. O mercado reagiu como se fosse uma revolução. Empresas de segurança perderam bilhões em valor de mercado.
Mas a verdade é que o Claude Code Security já estava disponível. Você só não usava.
Ferramentas de segurança existem há décadas
SonarQube, Snyk, Checkmarx, Fortify, OWASP ZAP, Burp Suite, Veracode, Semgrep. A lista é longa. Ferramentas de análise estática, análise dinâmica, scanners de dependência, pentest automatizado. Não falta ferramenta.
Todas funcionam da mesma forma: olham o código de fora. São scanners. Recebem seu código como input, rodam regras, cospem um relatório. Você lê o PDF, prioriza os findings, abre tickets, e talvez corrija alguns. Meses depois, roda de novo.
O modelo mental é: código de um lado, segurança do outro. Dois mundos separados que se encontram no CI/CD.
A mudança real: segurança de dentro do código
O que muda com o Claude Code não é "mais uma ferramenta de segurança". É o lugar de onde a segurança acontece.
Quando o Claude Code audita seu código, ele não está rodando regras de regex por cima dos seus arquivos. Ele está lendo o código. Entendendo o fluxo de autenticação. Seguindo a cadeia de chamadas do handler até o banco de dados. Verificando se o rate limit usa Redis (distribuído) ou memória (inútil em múltiplas instâncias). Olhando se a projeção do MongoDB está filtrando os campos sensíveis. Checando se o timingSafeEqual está sendo usado na comparação de tokens.
Ele entende contexto. Sabe que aquele findById(req.params.id) sem filtro de tenant é um BOLA (Broken Object Level Authorization), o vulnerability #1 do OWASP API Security Top 10. Não porque bateu uma regex, mas porque entendeu que a query não tem escopo de multi-tenancy.
É a diferença entre um guarda que olha o prédio pelo lado de fora e um que conhece cada sala por dentro.
Eu já fazia isso. Com skills.
O Claude Code tem um recurso chamado skills, arquivos markdown em ~/.claude/skills/ que funcionam como instruções especializadas. Quando você invoca uma skill (tipo /security-scan), o Claude Code recebe aquele contexto e executa a tarefa com o conhecimento embutido no arquivo.
Eu criei 6 skills de segurança que transformaram meu Claude Code num auditor completo:
/security-scan: OWASP + SOC 2
A skill mais usada no dia a dia. Toda vez que termino uma feature, rodo /security-scan nos arquivos alterados.
Ela faz:
- Identifica os arquivos alterados via
git diff - Detecta o framework (Fastify, no meu caso)
- Lê cada arquivo procurando as 7 categorias do OWASP Top 10: Injection, Broken Auth, Sensitive Data Exposure, Broken Access Control, Security Misconfiguration, XSS, Insecure Dependencies
- Cruza com critérios SOC 2: CC6 (Access Control), CC7 (System Operations), PI (Processing Integrity), C (Confidentiality), A (Availability)
- Aplica regras específicas de stack: Node.js/Fastify, MongoDB/Mongoose, Redis, Cryptografia
- Cruza com a documentação de segurança do projeto: se existe um
AUDIT_2026.mdcom vulnerabilidades já corrigidas, verifica se a mudança não reintroduz o problema
O relatório sai com severidade (CRITICAL/HIGH/MEDIUM/LOW), localização exata (file:line), categoria OWASP ou critério SOC 2, o risco, e o fix exato.
/security-hardening: Auditoria profunda de produção
Essa é a skill pesada. Vai muito além de SOC 2. Cobre:
- OWASP Top 10 (2025): todos os 10 itens com patterns de grep e exemplos de código vulnerável vs seguro
- OWASP API Security Top 10: BOLA, Broken Authentication, Mass Assignment, SSRF, cada um com checklist
- Prevenção de NoSQL Injection: patterns específicos de MongoDB (
$gt,$ne,$regex,$where) - Prototype Pollution:
__proto__,constructor,prototyperejeitados no input - Rate Limiting & DDoS: multi-tier limits, Redis-backed,
Retry-After, Slowloris protection - Zero Trust: re-validação de sessão, encrypt everything, log every access decision
- LGPD/GDPR: minimização de dados, projeções MongoDB, direito de acesso/exclusão/portabilidade
- Secrets Management: patterns de grep para encontrar secrets hardcoded
- Security Headers: HSTS, CSP, X-Frame-Options, COOP, CORP
- Penetration Testing Checklist: checklist manual para testes trimestrais
A skill termina com um score de 0 a 100, mapa de superfície de ataque, e roadmap de remediação priorizado.
/soc2-audit: SOC 2 Type I e Type II completo
Essa cobre os 61 critérios do Trust Services Criteria (TSC) do AICPA:
- CC1: Ambiente de Controle (integridade, supervisão, estrutura, competência, accountability)
- CC2: Comunicação e Informação (qualidade da informação, comunicação interna/externa)
- CC3: Avaliação de Risco (objetivos, análise de risco, fraude, gestão de mudanças)
- CC4: Monitoramento (APM, health checks, alertas, error tracking)
- CC5: Atividades de Controle (auth middleware, sanitização, WAF, CI/CD)
- CC6: Controles de Acesso (autenticação, registro, remoção, restrições físicas, multi-tenancy)
- CC7: Operações do Sistema (monitoring, anomaly detection, incident response, recovery)
- CC8: Gestão de Mudanças (version control, branch protection, PR reviews, CI)
- CC9: Mitigação de Riscos (vendor risk, webhook signatures, SLA monitoring)
- A1: Disponibilidade (capacity, health checks, backups, DR)
- PI1: Integridade de Processamento (validação, idempotência, reconciliação, error correction)
- C1: Confidencialidade (classificação de dados, disposal)
- P1: Privacidade (notice, consent, collection, retention, access, disclosure, quality, monitoring)
O diferencial de Type II: não basta o controle existir no código. A skill verifica se existe evidência de operação contínua: logs provando que o controle roda consistentemente, enforcement automatizado, monitoramento que pega falhas.
/query-review: Review específico de MongoDB
Toda query MongoDB que eu escrevo passa por essa skill. Ela verifica:
- Projeção obrigatória: nunca retornar documentos inteiros (stores podem ter 50KB+)
- Timezone: datas no MongoDB são UTC, Brasil é UTC-3, meia-noite BRT = 03:00 UTC
- Índices faltantes: fields em
$matchdepois de$unwind, sorts em grandes collections lean()faltando: queries read-only devem usar.lean()awaitfaltando: Mongoose queries são thenables, sem await = bug silencioso- Queries sem limite:
find()semlimit()em collections grandes
/severity-review: Review com profundidade configurável
Três modos: Critical Only (pré-merge rápido), Standard (review normal), Thorough (nitpick completo). O dev escolhe a profundidade.
/docs: Documentação automática de segurança
Depois de qualquer mudança, essa skill detecta o que mudou e atualiza os docs correspondentes, incluindo AUDIT_2026.md e SOC2_COMPLIANCE.md com contadores, status, e barras de progresso.
O que isso produziu na prática
Agora vamos aos exemplos. Simulando em códigos legados, o resultado foi:
NoSQL Injection: seu login aceita operadores do MongoDB?
Esse é o clássico. Um código de login que faz findOne({ email, password }) direto no banco sem validar tipo. Se alguém mandar { "$gt": "" } no campo password, o MongoDB retorna o primeiro documento que corresponde. Login sem senha.
O que a skill encontra e o que o teste valida:
// O atacante manda isso no body:
// { email: { $gt: '' }, password: 'anything' }
// Se o backend não validar tipo, o MongoDB interpreta $gt como operador
it('rejects $gt operator in email', async () => {
const res = await app.inject({
method: 'POST',
url: '/login',
payload: { email: { $gt: '' }, password: 'anything' },
})
expect(res.statusCode).toBe(400) // Zod rejeita: email tem que ser string
})
O fix é simples: Zod na entrada. z.string().email() mata o problema na raiz. Mas sem a skill apontando, quantas APIs em produção hoje aceitam objetos onde deveria ter string?
A mesma lógica vale pra $ne, $regex, $or, $where. Cada operador é um vetor de ataque. A skill testa todos, em todos os endpoints de autenticação.
Prototype Pollution: o JSON que envenena o processo inteiro
Esse é mais sutil. O atacante manda um JSON com __proto__ no body. Se o backend usar Object.assign() ou spread sem sanitizar, o prototype de todos os objetos do processo é poluído.
// O atacante manda JSON raw com __proto__
// Se o parser não rejeitar, {"isAdmin": true} vaza pro Object.prototype
// E qualquer {} no processo passa a ter isAdmin === true
it('rejects __proto__ field with 400', async () => {
const res = await app.inject({
method: 'POST',
url: '/login',
headers: { 'content-type': 'application/json' },
payload: '{"email":"real@test.com","password":"correct123","__proto__":{"isAdmin":true}}',
})
expect(res.statusCode).toBe(400)
// Verifica que Object.prototype NÃO foi poluído
expect(({} as Record<string, unknown>).isAdmin).toBeUndefined()
})
A última linha é a mais importante: ela verifica que criar um objeto vazio {} e acessar .isAdmin retorna undefined. Se retornasse true, o processo inteiro estaria comprometido.
Response Leakage: "usuário não encontrado" vs "senha incorreta"
Se sua API retorna mensagens diferentes pra email inexistente e senha errada, qualquer atacante consegue enumerar quais emails existem no seu sistema. Com uma lista de emails, o ataque de força bruta fica muito mais eficiente.
it('error messages do not reveal whether email exists', async () => {
const resExists = await app.inject({
method: 'POST', url: '/login',
payload: { email: 'real@test.com', password: 'wrongpassword' },
})
const resNotExists = await app.inject({
method: 'POST', url: '/login',
payload: { email: 'notexist@test.com', password: 'wrongpassword' },
})
// Status code idêntico
expect(resExists.statusCode).toBe(401)
expect(resNotExists.statusCode).toBe(401)
// Mensagem idêntica: não dá pra saber qual email existe
expect(resExists.json().message).toBe(resNotExists.json().message)
// Até a messageKey tem que ser igual
expect(resExists.json().messageKey).toBe(resNotExists.json().messageKey)
})
2FA Bypass: a vulnerabilidade que nenhum scanner encontra
Essa foi a mais grave que a skill encontrou. É uma vulnerabilidade de lógica de negócio, não de input.
O fluxo de login era:
- Usuário manda email + password corretos
- Se tem 2FA, a API pede o código TOTP
- Usuário manda email + password + totp_code
O problema: no passo 1, quando a API confirmava email + password e pedia o TOTP, ela resetava o contador de tentativas falhas. Então o atacante podia:
{email, password}→ "informe o TOTP", counter = 0{email, password, totp_code: "000001"}→ falhou, counter = 1{email, password}→ "informe o TOTP", counter = 0 (reset!)- Repetir até acertar
Com 1 milhão de combinações possíveis no TOTP de 6 dígitos, e o counter sempre voltando a zero, era questão de tempo. Nenhum scanner de regex ou análise estática encontra isso. É preciso entender o fluxo e perceber que a ordem das operações está errada.
Mais exemplos do que a skill pega
A suíte completa cobre:
injection.test.ts: NoSQL injection ($gt, $ne, $regex, $where, $or), prototype pollution (__proto__, constructor.prototype), XSS (script tags, img onerror), command injection ($(whoami)), type confusion (number, boolean, array, null onde espera string), null byte injection, header injection, response leakage, oversized payloads, malformed JSON.
routes.test.ts: HTTP verb tampering, path traversal, session fixation, IDOR, mass assignment, 2FA bypass.
headers-cors.test.ts: CORS origin validation, Helmet headers, cookie security, Content-Type enforcement.
38 vulnerabilidades catalogadas no total
Tudo documentado no AUDIT_2026.md:
- 2 CRITICAL: password reset link logado em plaintext, 2FA bypass via rate limit reset
- 9 HIGH: admin token com MD5, session token sem entropia, swagger exposto em produção
- 13 MEDIUM: AES-CTR sem autenticação, rate limit desabilitado quando Redis cai, CORS regex aceita domínio errado
- 14 LOW: console.log em produção, backup codes sem timing-safe comparison
Com plano de remediação em 4 fases. Fase 1 (críticos): concluída no mesmo dia. Fase 2 (high): 7 de 8 feitos.
164 testes de segurança no total
Tudo que foi mostrado acima são exemplos reais da suíte. No total, são 164 testes: 75 funcionais + 89 de segurança, distribuídos em 4 arquivos dedicados em tests/security/.
SOC 2 Compliance Checklist com 157 itens
Rastreamento completo no SOC2_COMPLIANCE.md:
- Autenticação: 100% (20/20 itens)
- Rate Limiting: 63% (5/8)
- Sessões e Tokens: 60% (6/10)
- Proteção de Dados: 50% (6/12)
- Logging e Auditoria: 38% (6/16)
Com progresso visual e plano de ação de 39 itens priorizados.
Como fazer na sua máquina
1. Crie o diretório de skills
mkdir -p ~/.claude/skills
2. Crie uma skill
Cada skill é uma pasta com um skill.md dentro:
mkdir -p ~/.claude/skills/security-scan
O arquivo skill.md tem frontmatter YAML + instruções em markdown:
---
name: security-scan
description: Quando usar esta skill
---
# Security Scan
## Steps
### 1. Identifique os arquivos alterados
### 2. Leia cada arquivo
### 3. Verifique contra [categoria]
### 4. Reporte com severidade + fix
O segredo está na especificidade. Não escreva "verifique se tem vulnerabilidades". Escreva exatamente o que verificar, com exemplos de código vulnerável e seguro, com patterns de grep, com referências a critérios específicos (CC6.3, PI1.1, A01).
3. Ensine o contexto do seu projeto no CLAUDE.md
No CLAUDE.md do seu projeto, eu coloquei regras como:
- Toda alteração de segurança atualiza
docs/security/AUDIT_2026.md - Todo commit passa pelo skill
/commitque roda/docsautomaticamente - Skills disponíveis:
/security-scan,/query-review,/docs,/commit - Stack: Fastify 5 + Zod + Mongoose 8 + ioredis
O Claude Code absorve esse contexto e aplica as skills com conhecimento do projeto.
4. Use no fluxo natural de desenvolvimento
Não é um passo extra. É parte do fluxo:
1. Implementa feature
2. /security-scan ← audita os arquivos alterados
3. Corrige findings
4. /query-review ← verifica queries MongoDB
5. /commit ← que roda /docs automaticamente
Periodicamente:
/security-hardening ← auditoria profunda
/soc2-audit ← compliance completa
Por que isso importa mais que um scanner externo
Um scanner externo vê o código como texto. O Claude Code vê o código como sistema.
Ele sabe que o clearFailedAttempts na linha 69 do auth.service.ts é chamado antes da verificação 2FA, e que isso permite brute-force infinito do TOTP, resetando o counter a cada tentativa. Nenhum scanner de regex encontra isso. É uma vulnerabilidade de lógica de negócio.
Ele sabe que aquele Account.findById(id) sem segundo argumento vai retornar o documento inteiro incluindo o hash da senha, o secret do 2FA, e os backup codes. Não porque bateu uma regra "findById sem projeção", mas porque leu o schema do Mongoose e entendeu quais campos existem e quais são sensíveis.
Ele sabe cruzar o finding C2 do AUDIT_2026.md com o teste de regressão no injection.test.ts e confirmar que o fix foi implementado e testado.
Isso não é scan. É auditoria.
A ferramenta sempre esteve ali
Skills são arquivos markdown. Qualquer dev pode criar. Não precisa esperar a Anthropic lançar uma feature oficial. Não precisa pagar uma plataforma de segurança.
O Claude Code já lê código, já entende contexto, já sabe escrever testes, já conhece OWASP e SOC 2. A única coisa que faltava era alguém dizer pra ele como auditar, com a especificidade de quem realmente faz segurança.
As empresas de segurança não perderam bilhões porque surgiu mais um scanner. Perderam porque o paradigma mudou: a segurança saiu de fora e foi pra dentro do código. E quando está dentro, não tem como competir com quem entende cada linha.