Crie um Agente de Análise de Segurança do Claude Code para a OWASP
A varredura terminou às 23h47 de uma quinta-feira, e fiquei olhando para o terminal como se ele tivesse acabado de insultar todo o meu código. Trinta e sete vulnerabilidades. Nove críticas. Um score de risco de 245 piscando no topo do relatório, naquele tom específico de vermelho que diz "não envie isso". O detalhe? Não era o código de um cliente. Era um aplicativo de anotações deliberadamente vulnerável que eu criei como alvo de teste para o agente de scanner de segurança Claude Code, que eu tinha acabado de montar naquela tarde.
E o agente pegou tudo. Hash de senhas com MD5. Concatenação de strings SQL brutas. Um caminho de controle de acesso quebrado onde qualquer usuário autenticado podia excluir as notas de qualquer outro usuário apenas adivinhando um ID. Um ponto de execução arbitrária de código que eu escondi três arquivos abaixo porque realmente queria ver se ele encontraria. Encontrou. Em trinta segundos.
Foi aí que parei de pensar nisso como um experimento de fim de semana e comecei a enxergar como algo que eu deveria ter construído seis meses atrás.
Eu comando uma marca de cibersegurança — xCyberSecurity — e boa parte desse trabalho é executar auditorias no estilo OWASP em aplicativos web. A auditoria em si é um tempo humano caro. Ler código, rastrear o fluxo de dados, conferir versões de dependências, cruzar referências com CVEs, redigir achados com severidade e remediação. Esse trabalho é feito por um engenheiro sênior. Devagar. Cuidadosamente. Cobrado por hora.
Um agente Claude Code não substitui esse engenheiro. Mas pode fazer o primeiro filtro. Pode capturar o óbvio antes de um humano sequer abrir o arquivo. E como o Claude Code lançou o padrão Skill + sub-agent, tudo é modular — um componente reutilizável que posso compartilhar entre projetos, encadear com outros agentes e incluir num pre-commit hook numa tarde de terça-feira.
Foi assim que eu construí. E, mais importante ainda, por que a arquitetura importa.
Por que um Agente Único Não Funciona Aqui
Meu primeiro instinto — e provavelmente o seu também — é simplesmente escrever um prompt de sistema gigante. "Você é um auditor de segurança. Verifique SQL injection, controle de acesso quebrado, criptografia fraca, toda a lista Top 10 da OWASP, escreva um relatório." Entrega. Próximo.
Foi exatamente essa versão que testei primeiro. Ela funcionou. Mais ou menos. Os relatórios eram inconsistentes. Alguns scans classificavam toda chamada md5() como crítica; outros simplesmente ignoravam. A pontuação de "gravidade" mudava entre execuções — um scan considerava uma chave de API hardcoded como "alta", outro como "crítica". Pior ainda: o agente não tinha memória de como era um bom resultado. Cada invocação era uma improvisação do zero.
O verdadeiro problema era estrutural. Eu estava tentando fazer uma janela de contexto abrigar quatro conteúdos ao mesmo tempo: o material de referência do OWASP Top 10, a metodologia de auditoria, o formato do relatório e o código realmente auditado. É muita carga cognitiva para um único prompt — e o Claude, até mesmo o Opus 4.7, responde a essa carga como qualquer auditor humano depois do oitavo energético. Fica descuidado.
Skills resolvem isso. Subagentes também. Use ambos, e todo o sistema se encaixa.
Se quiser entender melhor como as skills se integram ao Claude Code, expliquei isso no meu guia de Skills para Claude Code — vale a leitura junto com este post, porque o scanner mostrado aqui é uma aplicação concreta desses padrões.
A Arquitetura: Habilidade + Subagente
Aqui está a divisão que funciona.
A Habilidade é a camada de conhecimento. Ela contém o material de referência do OWASP Top 10, a metodologia de varredura e o formato exato do relatório. Trata-se de uma pasta com um arquivo SKILL.md e alguns arquivos markdown — um para cada categoria OWASP — que são carregados conforme a necessidade. A habilidade em si não faz nenhuma varredura. É um conjunto de instruções esperando para ser acionado.
O Subagente é a camada de execução. É um subagente Claude Code especializado, com seu próprio prompt de sistema, acesso a ferramentas específicas (Read, Glob, Grep, Bash para clones via gh, Write para relatórios) e instruções explícitas para carregar a habilidade de segurança ao ser executado. O subagente é o que você de fato invoca. A habilidade é a fonte de consulta dele.
Essa separação é importante por três razões.
Primeiro, separação de responsabilidades. O conhecimento é versionado de forma independente da lógica de execução. Quando o OWASP atualizou o Top 10 em 2025 — moveram SSRF para Broken Access Control, adicionaram Software Supply Chain Failures como nova categoria de topo e incluíram Mishandling of Exceptional Conditions — eu atualizei dois arquivos markdown na habilidade. O subagente permaneceu o mesmo. No antigo modelo de um único prompt gigante, eu teria que reescrever todo o prompt do sistema.
Segundo, compartilhamento fácil. A habilidade é uma pasta. Posso compactá-la, enviar para um colega, fazer commit em um repositório compartilhado ou colocá-la em um registro de habilidades do time. O subagente é um único arquivo markdown com frontmatter. Mesma lógica. Alguém do meu time pode clonar ambos, configurá-los em cinco minutos e obter resultados de varredura idênticos aos meus.
Terceiro, composabilidade. O subagente de varredura pode ser invocado diretamente — @security-scanner audite este repositório — ou encadeado a partir de um agente coordenador de nível superior. Tenho um agente principal que faz revisão de código; quando detecta security: em uma mensagem de commit, delega para o scanner. Esse padrão seria impossível se a lógica de segurança estivesse embutida no prompt do próprio agente de revisão. Falo mais sobre esse tipo de delegação no meu post sobre arquitetura de swarm de agentes, e o scanner é um ótimo exemplo desta prática.
O resto deste artigo é o passo a passo da implementação.
O SKILL.md Que Você Pode Copiar
A skill está localizada em .claude/skills/security-vulnerability/. Aqui está o arquivo SKILL.md — este é o esqueleto que realmente utilizo, com uma leve revisão:
---
name: security-vulnerability
description: Faça a varredura de uma base de código ou repositório GitHub em busca das vulnerabilidades do OWASP Top 10 2025. Use quando o usuário solicitar uma auditoria de segurança, varredura de vulnerabilidades, revisão OWASP ou checagem de segurança antes da implantação em um diretório local ou URL do GitHub.
---
Você está realizando uma auditoria de segurança conforme as categorias do OWASP Top 10 2025. Siga exatamente o fluxo de execução abaixo. Não pule etapas. Não invente níveis de severidade.
## Manipulação de Entrada
Aceite um dos dois tipos de entrada:
- Um caminho de diretório local (ex.: `/Users/me/projects/app`)
- Uma URL do GitHub (ex.: `https://github.com/org/repo`)
Se a entrada for uma URL do GitHub, clone com:
gh repo clone <org/repo> /tmp/scan-<timestamp>
Depois, defina o caminho de trabalho para o diretório clonado.
## Fluxo de Execução
1. **Inventariar o código-fonte.** Identifique as linguagens, frameworks e manifestos de pacotes (package.json, composer.json, requirements.txt, go.mod, Gemfile, pom.xml).
2. **Carregar as referências por categoria.** Para cada categoria do OWASP Top 10 2025, leia o arquivo de referência correspondente nesta pasta de habilidade:
- references/A01-broken-access-control.md
- references/A02-security-misconfiguration.md
- references/A03-supply-chain-failures.md
- references/A04-injection.md
- references/A05-cryptographic-failures.md
- references/A06-insecure-design.md
- references/A07-auth-failures.md
- references/A08-data-integrity-failures.md
- references/A09-logging-alerting-failures.md
- references/A10-exceptional-conditions.md
3. **Escanear por categoria.** Para cada categoria, utilize Grep e Read no código-fonte usando os padrões documentados no arquivo de referência da respectiva categoria. Registre cada ocorrência com caminho do arquivo, número da linha, trecho do código e categoria.
4. **Verificar dependências.** Para cada manifesto de pacote, extraia as versões declaradas. Sinalize pacotes com CVEs conhecidos consultando OSV.dev ou o GitHub Advisory Database. Não invente IDs de CVE. Se não for possível consultar no ambiente atual, registre o pacote e versão como “dependências não verificadas” em vez de criar um veredito.
5. **Pontuar e classificar.** Atribua uma severidade para cada ocorrência: crítica, alta, média ou baixa. Utilize a métrica do arquivo references/severity-rubric.md. Calcule o risco total: (crítica × 10) + (alta × 5) + (média × 2) + (baixa × 1).
6. **Gerar o relatório.** Salve em `audit/YYYY-MM-DD/report.md` relativo ao alvo do scan. Utilize o formato de relatório abaixo.
## Formato do Relatório
O relatório deve conter, nesta ordem:
1. **Resumo** — alvo, data da varredura, total de descobertas por severidade, pontuação geral de risco, veredito de aprovação/reprovação.
2. **Achados por categoria** — uma seção para cada categoria OWASP com achados. Cada achado lista: severidade, arquivo:linha, trecho de código, motivo do risco, sugestão de correção.
3. **Riscos de dependências** — pacotes conhecidos como vulneráveis com referências CVE e caminhos de atualização.
4. **Dependências não verificadas** — pacotes sinalizados, mas não confirmados.
5. **Prioridade de remediação** — uma lista ordenada das dez principais correções por severidade e esforço.
## Regras Rígidas
- Nunca invente IDs de CVE, níveis de severidade ou correções que você não tenha confiança. Marque explicitamente qualquer incerteza.
- Nunca aplique correções automaticamente. O subagente pode propor patches em um arquivo separado, mas modificar o código-fonte requer aprovação explícita de um humano.
- Se um arquivo exceder 2000 linhas, leia-o em partes. Não pule o arquivo.
- Toda constatação deve citar um arquivo e intervalo de linhas específico.
É isso. Todo o cérebro da skill. Cada arquivo de referência dentro de references/ é um documento focado de 200 a 400 linhas: definição, padrões comuns para busca (grep), exemplos específicos de linguagem e a matriz de severidade daquela categoria. Você pode rascunhar esses arquivos de referência em uma tarde se já tiver alguma experiência em segurança.
O Subagente que o Utiliza
O subagente está localizado em .claude/agents/security-scanner.md. Veja o frontmatter e o prompt do sistema — novamente, a versão real que executo:
---
name: security-scanner
description: Audite um diretório local ou repositório do GitHub com base no OWASP Top 10 2025. Use proativamente quando o usuário mencionar auditoria de segurança, varredura de vulnerabilidade, teste de penetração, checagem pré-implantação ou revisão OWASP.
model: opus
tools: Read, Glob, Grep, Bash, Write
---
Você é um engenheiro sênior de segurança de aplicações. Seu trabalho é realizar uma auditoria completa baseada no OWASP Top 10 2025 em um codebase alvo e produzir um relatório acionável para um revisor humano.
Quando acionado:
1. Confirme com o usuário o alvo da varredura se houver ambiguidade (caminho local vs. URL do GitHub).
2. Carregue a skill `security-vulnerability` e siga exatamente o seu fluxo de execução.
3. Execute a varredura. Seja sistemático, não criativo. Cobertura é mais importante do que velocidade.
4. Escreva o relatório em `audit/YYYY-MM-DD/report.md` e destaque o resumo no chat.
5. Após salvar o relatório, ofereça — mas não realize — correções automáticas para achados que sejam mecanicamente seguras (ex: substituir `md5()` por `password_hash()`, parametrizar uma query SQL). Aguarde aprovação explícita antes de modificar qualquer arquivo-fonte.
Regras de operação:
- Você não faz pentest em sistemas ativos. Apenas análise estática.
- Você não faz suposições. Se um achado for incerto, marque como incerto no relatório.
- Você não deleta nem move arquivos.
- Registre toda chamada de ferramenta. Mantenha o histórico da auditoria em `audit/YYYY-MM-DD/trail.log`.
Dois arquivos. Esse é todo o scanner.
O que aconteceu quando executei
Criei um aplicativo de notas deliberadamente vulnerável como alvo de teste. Stack ao estilo Laravel, SQLite, algumas rotas, autenticação de usuário, CRUD de notas. Ocultei intencionalmente seis classes de vulnerabilidades nele e acabei adicionando outras que nem lembrava ter incluído.
A varredura levou cerca de 90 segundos do início ao fim em uma base de código com 4.000 linhas. Aqui está o resumo produzido:
- Total de achados: 37
- Crítico: 9
- Alto: 15
- Médio: 12
- Baixo: 1
- Score de risco: 245 (crítico)
Os achados críticos abrangeram A01 Controle Quebrado de Acesso (duas rotas sem checagem de posse — qualquer usuário autenticado podia editar ou deletar qualquer nota simplesmente adivinhando o ID), A04 Injeção (três casos de concatenação de strings cruas em consultas SQL), A05 Falhas Criptográficas (hash de senha usando MD5 e uma APP_KEY fixa codificada diretamente em um .env.example que foi versionado), e A06 Design Inseguro (um endpoint administrativo aceitando um parâmetro cmd que era passado diretamente para uma chamada de execução de shell).
O relatório detalhou tudo isso com caminhos de arquivos, números de linha, trechos exatos de código e uma sugestão de correção para cada item encontrado. Nos casos de injeção SQL, sugeriu a reescrita das queries com parâmetros ali mesmo. Para o hash MD5, indicou o uso do Hash::make() do Laravel e explicou o caminho de migração para os registros de senha existentes.
Foi perfeito? Não. Marcou uma instrução de logging que imprimia o e-mail de um usuário como uma questão A09 — defensável, mas um pouco agressivo; na maioria das jurisdições, isso sequer seria considerado um achado. Também deixou passar uma condição de corrida sutil no endpoint de compartilhamento de notas, algo que um revisor humano notaria em cerca de trinta segundos. Correspondência estática de padrões não consegue lidar com questões de concorrência, e nenhum prompt vai resolver isso.
Mas o que foi identificado, foi apontado com precisão. E recebi um relatório com data registrada em audit/2026-04-18/ pronto para enviar a um cliente.
Conectando ao Fluxo de Pré-Commit ou CI
O sub-agente é útil de forma independente. Mas ele se torna ainda mais valioso quando executado automaticamente.
Para pré-commit, utilizo um hook do Git que aciona o modo headless do Claude Code apenas nos arquivos staged. Ele carrega o sub-agente de scanner, restringe o escopo da varredura aos caminhos alterados e bloqueia o commit se surgirem novos achados críticos ou de alto risco que não estavam presentes na análise anterior. A palavra importante aqui é "novo" — rodar um scan OWASP completo a cada commit seria inviável. Um delta scan em relação ao último baseline aprovado é o formato correto.
Para CI, segue o mesmo padrão, apenas com um encapsulamento diferente. Uma GitHub Action roda em pull requests, clona o branch da PR em um diretório temporário, executa o scanner e publica o resumo como comentário na PR, com o relatório completo anexado como artefato de build. Se o score de risco subir mais do que um limite predefinido em relação ao branch base, a verificação falha. O responsável pelo time pode sobrescrever aplicando um rótulo aprovado. Isso já interceptou dois upgrades de dependências que trouxeram pacotes vulneráveis de forma transitiva antes de chegarem ao main.
Nenhuma dessas integrações é responsabilidade do scanner — trata-se de orquestração ao redor dele. Mas ambas são triviais de implementar uma vez que existem o skill e o sub-agente, pois o scanner lê um caminho e gera um relatório. Todo o resto é apenas integração.
Onde Isso Falha, Honestamente
Não vou fingir que isso substitui um pentester humano, então vamos ser específicos sobre os limites.
Falsos positivos. O scanner gera muitos alertas com base em padrões. Toda chamada md5() é sinalizada, mesmo que esteja sendo usada para algo que não envolve segurança, como fingerprinting de conteúdo. Toda chamada considerada perigosa em um arquivo de teste é alertada. Você aprende a filtrar, mas se for entregar o relatório para um cliente não técnico, precisará fazer esse filtro previamente.
Sem raciocínio em tempo de execução. A análise estática vê o que está no código, não o que acontece quando ele roda. Condições de corrida, ataques de temporização, falhas de lógica de negócio que só aparecem a partir de uma sequência específica de chamadas de API — o scanner não vai identificar. Um pentester consegue. Essa lacuna não pode ser eliminada.
Inteligência de dependências depende do feed. O scanner consulta o OSV.dev e o GitHub Advisories. Se um pacote tem uma CVE publicada, ótimo. Se uma vulnerabilidade foi reportada há três dias e ainda não entrou num banco público, o scanner vai deixar passar. Zero-days continuam sendo um desafio humano.
Correção automática é uma armadilha. Esta é a que faço questão de enfatizar. O sub-agente pode propor correções. Jamais deve aplicá-las sem revisão. Sei disso porque a primeira versão do agente aplicava correções por conta própria e alegremente substituiu uma chamada a md5() em um fluxo legado de verificação de senha, sem realizar migração das senhas. A mudança quebrou o login de todos os usuários existentes no ambiente de staging. Correções estáticas sem consciência de migração transformam um achado “médio” em um incidente crítico. Sempre mantenha um humano no processo.
A própria segurança de skills. Por fim — e este é um ponto que me fez refletir ao ler uma pesquisa recente da Repello sobre segurança de skills — skills são contexto executável. Qualquer skill que você instalar pode acessar seu filesystem e executar comandos no shell. Uma skill maliciosa disfarçada de scanner de segurança é um risco real. Eu escrevo minhas próprias skills, audito cada skill importada e mantenho a fronteira de confiança bem restrita. Você também deveria.
A Parte Que a Maioria Ignora
O que mais repito quando outros desenvolvedores me perguntam sobre esse padrão é que o scanner não é a parte valiosa. O scanner leva uma semana de trabalho. Qualquer engenheiro competente com Claude Code e uma tarde livre consegue construir um.
O valor real está na disciplina que a separação Skill + subagente impõe. Ao escrever a skill, você está registrando como uma boa auditoria de segurança realmente deve ser — as categorias, padrões, critérios de severidade, formato do relatório. Esse documento, armazenado em .claude/skills/security-vulnerability/, é um conhecimento institucional que antes não existia. Ele vale mais que o próprio agente. Porque, no ano que vem, quando a OWASP publicar o Top 10 2028 e metade das categorias mudar novamente, você só precisa atualizar os arquivos de referência. O agente continua funcionando. O conhecimento é versionado, compartilhável, e não fica preso na cabeça de alguém.
Essa é a verdadeira lição desta construção. Não é “Eu automatizei o OWASP”. A lição é que agentes modulares forçam você a tornar seu conhecimento explícito — e conhecimento explícito se multiplica.
Escolha um repositório hoje à noite. Não o do cliente. Um seu. Rode um scan. Veja os resultados. Você vai aprender mais sobre seu próprio código em noventa segundos do que nos últimos seis meses de desenvolvimento.
Perguntas Frequentes
O Claude Code pode escanear um repositório GitHub privado?
Sim, desde que o gh CLI na máquina onde o Claude Code está rodando esteja autenticado com acesso a esse repositório. O scanner usa o comando gh repo clone internamente, então herda as permissões concedidas pelo seu gh auth login. Para repositórios de organizações, certifique-se de que seu token possui o escopo repo.
O scanner substitui ferramentas como Snyk ou Semgrep?
Não. Ele complementa essas ferramentas. Snyk e Semgrep utilizam conjuntos de regras e bancos de vulnerabilidades curados, que são mais autoritativos do que qualquer prompt de LLM isolado. O scanner do Claude Code acrescenta raciocínio — ele consegue rastrear fluxo de dados e identificar problemas específicos de contexto que passam despercebidos por regras estáticas. Use ambos. O scanner detecta falhas de design; o Snyk identifica CVEs conhecidas mais rapidamente.
Quanto custa rodar um scan OWASP dessa forma?
No Opus 4.7, um scan completo em uma base de código de 4.000 linhas com a configuração Skill + sub-agente me custa alguns dólares em uso de API por execução. Scans delta em arquivos staged num hook de pré-commit são bem mais baratos. Se você tem uma assinatura do Claude Code com uso incluído, a maioria dos scans do dia a dia fica dentro desse orçamento.
Posso compartilhar a skill com meu time sem compartilhar minha conta do Claude?
Sim. A skill é só uma pasta com arquivos markdown. Faça o commit de .claude/skills/security-vulnerability/ no repositório do seu projeto ou em um repositório de skills compartilhado. Cada membro do time com o Claude Code carregará a skill automaticamente a partir da própria conta. O mesmo vale para o arquivo de sub-agente em .claude/agents/.
O scanner deve aplicar correções automaticamente?
Não, e eu diria nunca. Proponha correções, registre-as em um arquivo patch separado, exija revisão humana antes de modificar qualquer arquivo-fonte. Já quebrei um ambiente de staging confiando que o agente aplicaria uma troca "segura" de criptografia. Segura isoladamente, catastrófica quando combinada com o restante do fluxo de autenticação. Sempre mantenha a revisão humana no processo.
Vamos Trabalhar Juntos
Quer criar sistemas de IA, automatizar fluxos de trabalho ou escalar sua infraestrutura de tecnologia? Gostaria muito de ajudar.
- Fiverr (soluções personalizadas & integrações): fiverr.com/s/EgxYmWD
- Portfólio: mejba.me
- Ramlit Limited (soluções corporativas): ramlit.com
- ColorPark (design & branding): colorpark.io
- xCyberSecurity (serviços de segurança): xcybersecurity.io