10 de dez. de 2025·8 min
Checklist de segurança do Claude Code para checagens rápidas em apps web
Use um checklist de segurança do Claude Code para executar checagens rápidas e concretas em autenticação, validação de entrada, tratamento de segredos e superfícies de injeção em apps web.
O que é uma checagem de segurança leve\n\nUma checagem de segurança leve é uma revisão rápida (geralmente 30–60 minutos) feita para encontrar problemas óbvios e de alto impacto antes do deploy. Não é uma auditoria completa. Pense nisso como uma inspeção de segurança: você passa pelos caminhos que mais falham em apps reais e procura evidência, não suposições.\n\nEste checklist do Claude Code foca nas áreas que quebram com mais frequência em apps web do dia a dia:\n\n- Pressupostos de autenticação (como você sabe quem é o usuário)\n- Lacunas de autorização (o que ele pode fazer)\n- Validação de entrada\n- Tratamento de segredos\n- Superfícies comuns de injeção (SQL, execução de comandos, renderização de templates, redirecionamentos, uploads)\n\nNão tenta provar a ausência de bugs, modelar atores de ameaça complexos ou substituir testes de penetração.\n\n“Achados concretos” significa que todo problema registrado tem evidência que um desenvolvedor pode agir imediatamente. Para cada achado, capture:\n\n- Os arquivos exatos e o nome da função/handler\n- O comportamento arriscado em uma frase\n- Um passo mínimo de repro (requisição, payload ou caminho de clique)\n- Por que importa (impacto) e quem pode disparar isso\n- Uma direção segura de correção (não uma reescrita completa)\n\nIA é uma ajudante, não uma autoridade. Use-a para buscar, resumir e propor testes. Depois verifique lendo o código e, quando possível, reproduzindo com uma requisição real. Se o modelo não apontar locais e passos específicos, trate a alegação como não comprovada.\n\n## Defina o escopo em 10 minutos\n\nUma revisão rápida só funciona se você estreitar o alvo. Antes de pedir ao Claude Code para olhar qualquer coisa, decida o que você quer provar hoje e o que você não está checando.\n\nComece com 1 a 3 jornadas reais de usuário onde erros custam dinheiro, expõem dados ou concedem poder. Bons candidatos: login, redefinição de senha, checkout e telas de edição de admin.\n\nEm seguida, nomeie os ativos que você precisa proteger. Seja específico: contas de usuário, ações de pagamento, dados pessoais, operações apenas de admin.\n\nDepois, escreva suas suposições de ameaça em palavras simples. Você está defendendo contra um usuário curioso clicando por aí, um atacante externo com scripts ou um insider com algum acesso? A resposta muda o que é “bom o suficiente”.\n\nPor fim, defina pass e fail para que sua checagem termine com achados, não impressões. Regras simples funcionam bem:\n\n- Pass: toda ação sensível mostra uma verificação explícita de authn e authz.\n- Fail: qualquer endpoint confia no cliente para ID de usuário ou papel.\n- Pass: entradas são validadas no servidor, não apenas na UI.\n- Fail: segredos aparecem em logs, configs ou código cliente.\n\nSe você não consegue descrever como a falha se manifesta, o escopo ainda está muito vago.\n\n## Prepare o contexto que você dá ao Claude Code\n\nUma checagem só funciona se o modelo estiver olhando para os lugares certos. Reúna um pequeno conjunto de código e anotações para que a revisão gere evidência, não suposições.\n\nComece compartilhando o caminho crítico de segurança: pontos de entrada de requisição e o código que decide quem é o usuário e o que ele pode fazer. Inclua código suficiente ao redor para mostrar como os dados fluem.\n\nUm pacote prático normalmente inclui:\n\n- Entrada de auth: parsing de sessão/JWT, configurações de cookie, callbacks de login, middleware de auth\n- Rotas + handlers: controllers, métodos RPC, resolvers GraphQL, handlers de jobs em background\n- Camada de dados: queries ORM, helpers SQL raw, construtores de query, migrations para tabelas sensíveis\n- Checagens de política: verificações de papel, checagens de propriedade, feature flags, endpoints apenas admin\n- Validação: validadores de schema de requisição, handlers de upload de arquivo, código de desserialização\n\nAdicione algumas linhas de notas de ambiente para que as suposições fiquem explícitas: sessão vs JWT, onde os tokens vivem (cookie ou header), comportamento de reverse proxy ou API gateway, filas/workers, e quaisquer endpoints “apenas internos”.\n\nAntes de caçar bugs, peça um inventário: pontos de entrada, endpoints privilegiados e stores de dados tocados. Isso evita superfícies esquecidas.\n\nTambém concorde com um formato de saída que force achados concretos. Uma tabela simples funciona bem: Achado, Severidade, Endpoint/arquivo afetado, Evidência (snippet exato ou intervalo de linhas), Cenário de exploração, Sugestão de correção.\n\n## Workflow passo a passo para uma revisão de 30–60 minutos\n\nTimebox it:\n\n- 10 minutos para orientação\n- 15–30 minutos para traçar fluxos\n- 10 minutos para redigir\n\nO objetivo não é cobertura perfeita. É um pequeno conjunto de achados testáveis.\n\nMantenha o app aberto enquanto lê. Clique na UI e observe quais requisições são disparadas. As notas devem apontar endpoints, parâmetros e fontes de dados específicas.\n\nUm workflow que cabe em uma sessão:\n\n1. Esboce pontos de entrada e limites de confiança. Anote rotas públicas, rotas autenticadas, rotas admin, webhooks, uploads e callbacks de terceiros. Marque onde os dados passam de controlados pelo usuário para confiáveis pelo servidor.\n2. Para cada endpoint importante, escreva o que prova identidade e onde isso acontece. Se a checagem for “middleware”, confirme que toda rota realmente o usa.\n3. Faça o mesmo para autorização. Escolha uma ação de risco (ver dados de outros usuários, atualizar papéis, exportar, deletar) e trace a decisão de permissão até a query no banco.\n4. Trace input do usuário até sinks. Siga um parâmetro desde a requisição até consultas SQL/ORM, renderização de template, execução de comando, fetch de URL (SSRF), redirecionamentos e caminhos de arquivo.\n5. Escaneie segredos e flows de configuração enquanto traça. Procure tokens em logs, código cliente, mensagens de erro, dumps de ambiente e snapshots.\n\nUm hábito útil: para cada “parece ok”, escreva o que você faria para quebrar isso. Se não consegue descrever uma tentativa de quebra, provavelmente não verificou o suficiente.\n\n## Checagens de authn: prove quem é o usuário\n\nAutenticação é onde o app decide “esta requisição pertence a esta pessoa”. Uma checagem rápida não é ler cada linha; é encontrar onde a identidade é estabelecida e checar atalhos e caminhos de falha.\n\nLocalize o limite de confiança: onde a identidade é criada ou aceita pela primeira vez? Pode ser um cookie de sessão, um token JWT, uma chave de API ou mTLS na borda. Peça ao Claude Code para apontar o arquivo e a função exatos que transformam “anônimo” em um id de usuário, e para listar todo outro caminho que pode fazer o mesmo.\n\nChecagens de authn que valem a pena revisar:\n\n- Identificar todos os pontos de entrada de auth (login web, tokens de API, auth mobile, auth de serviço interno) e confirmar que convergem para um modelo de identidade consistente.\n- Checar login e reset de senha quanto a rate limits, bloqueios e enumeração de usuário (mensagens ou tempos diferentes para contas existentes vs inexistentes).\n- Inspecionar sessão e cookies: HttpOnly, Secure, SameSite, expiração, rotação no login e mudança de privilégio, e invalidação de logout (server-side, não apenas “deletar cookie”).\n- Revisar MFA e recuperação para garantir que o caminho de recuperação não seja mais fraco que o MFA (por exemplo, reset por email que contorna MFA).\n- Revisar logs de falha de auth: úteis para ops, mas não vazar detalhes que ajudem atacantes (sem dicas de “usuário existe”, sem dumps de token).\n\nExemplo prático: se emails de reset retornam “conta não encontrada”, isso é enumeração rápida. Mesmo com mensagem genérica, diferenças de tempo podem vazar a mesma informação, então verifique tempo de resposta também.\n\n## Checagens de authz: prove que o usuário tem permissão\n\nAutorização é a questão que causa mais dano quando errada: “Este usuário pode fazer esta ação neste recurso exato?” Uma checagem rápida deve tentar quebrar essa suposição de propósito.\n\nEscreva papéis e permissões em linguagem clara. Mantenha humano:\n\n- Dono pode convidar membros\n- Membro pode editar seu próprio perfil\n- Suporte pode ver detalhes de cobrança mas não mudar o plano\n- Admin pode deletar projetos\n\nEntão verifique que cada ação sensível aplica authz no servidor, não apenas na UI. Botões podem ser ocultados, rotas podem ser bloqueadas no cliente, mas um atacante pode chamar a API diretamente.\n\nUma varredura rápida que costuma achar problemas reais:\n\n- Encontre endpoints/mutations que criam, deletam, exportam, mudam papéis ou acessam cobrança\n- Para cada um, localize a checagem de permissão no servidor (não no frontend)\n- Procure IDs controlados pelo usuário (projectId, userId, orgId) e confirme checagens de propriedade\n- Confirme que caminhos apenas admin falham fechado quando falta o papel\n- Cheque limites multi-tenant: orgId/accountId deve vir do contexto de sessão, não apenas do input da requisição\n\nO cheiro clássico de IDOR é simples: uma requisição como onde é controlado pelo usuário, e o servidor carrega sem verificar se pertence ao usuário/tenant atual.\n\nUm prompt que força uma resposta real:\n\n“Para este endpoint, mostre o código exato que decide acesso, e liste as condições específicas que permitiriam a um usuário de outro orgId acessá-lo. Se não houver, explique por quê com nomes de arquivo e função.”\n\n## Validação de entrada: mantenha dados ruins fora desde cedo\n\nA maioria dos problemas rápidos começa com uma lacuna: o app aceita entrada que o desenvolvedor não esperava. Trate “entrada” como qualquer coisa que um usuário ou outro sistema possa influenciar, mesmo que pareça inofensiva.\n\nComece nomeando as entradas para o endpoint que está checando:\n\n- Valores de query e path na URL\n- Campos do corpo da requisição (incluindo JSON aninhado)\n- Headers (headers de auth, content-type, forwarded IP)\n- Cookies\n- Uploads de arquivos (nome, tamanho, tipo, metadados)\n\nA validação deve acontecer perto de onde os dados entram no app, não no meio da lógica de negócio. Cheque o básico: tipo (string vs number), comprimento máximo, obrigatório vs opcional e formato (email, UUID, data).\n\nPara valores conhecidos como papéis, status ou direções de ordenação, prefira uma allowlist. É mais difícil contornar do que “bloquear alguns valores ruins”.\n\nTambém verifique o tratamento de erros. Se o app rejeita entrada, não retorne o valor bruto na resposta, logs ou UI. É assim que pequenos bugs de validação viram vazamentos de dados ou ajudantes para injeção.\n\nUm mini-plano “entrada ruim” para endpoints de risco (login, busca, upload, ações admin):\n\n- Strings muito longas (10.000+ caracteres)\n- Tipos errados (array em vez de string)\n- Valores enum inesperados\n- Caracteres especiais que podem mudar o significado\n- Valores vazios para campos obrigatórios\n\nExemplo: um parâmetro de ordenação que aceita qualquer string pode virar um fragmento SQL. Uma allowlist como "date" ou "price" evita essa classe de erro cedo.\n\n## Superfícies comuns de injeção para varrer rapidamente\n\nA maioria das revisões rápidas encontra problemas nos mesmos poucos lugares: qualquer lugar onde a entrada do usuário é interpretada como código, query, caminho ou URL. Esta seção é onde você caça momentos “a entrada cruza um limite de confiança”.\n\nTrace dados desde pontos de entrada (query params, headers, cookies, uploads, formulários admin) até onde terminam.\n\n### Alvos de varredura rápida\n\nProcure por estes padrões e exija um call site concreto e um exemplo de payload para cada um:\n\n- SQL injection: queries construídas por concatenação de string, dinâmico e builders de que juntam valores do usuário\n- XSS: renderização HTML, templates, previews de markdown, editores rich text onde “sanitize depois” é assumido\n- Injeção de comando: chamadas de shell em torno de processamento de imagem, ferramentas PDF, backups ou passos “convert” que passam flags controladas pelo usuário\n- SSRF: fetchers de URL para webhooks, previews de link, importar-a-partir-de-URL e checks internos que aceitam uma URL do usuário\n- Path traversal: endpoints de download de arquivo, extração de zip e pipelines de upload que depois leem arquivos por nome\n\nTambém fique de olho em desserialização e injeção em templates. Qualquer coisa que parseie JSON, YAML ou strings templadas fornecidas pelo usuário pode esconder comportamento arriscado, especialmente se suportar tipos customizados, expressões ou renderização server-side.\n\nSe um recurso aceita uma URL, um nome de arquivo ou texto formatado, assuma que pode ser abusado até provar o contrário com caminhos de código e testes.\n\n## Tratamento de segredos: encontre vazamentos e armazenamento fraco\n\nProblemas com segredos costumam ser barulhentos quando você sabe onde procurar. Foque onde os segredos vivem e onde eles são copiados por acidente.\n\nLugares comuns onde segredos aparecem:\n\n- Variáveis de ambiente e arquivos de config do app\n- Output do CI e logs de build (incluindo logs de deploy falho)\n- Bundles cliente e builds mobile (qualquer coisa enviada aos usuários)\n- Endpoints de debug, páginas de health e ferramentas admin\n- Páginas de erro, stack traces e eventos de analytics\n\nEntão force uma resposta concreta: se um segredo está exposto hoje, o que acontece depois? Um bom sistema tem um caminho de rotação (nova chave emitida), revogação (chave antiga desativada) e uma maneira de redeployar rapidamente. Se a resposta for “trocaríamos depois”, trate como um achado.\n\nLeast privilege é outra vitória rápida. Incidentes pioram porque chaves têm muitos privilégios. Procure por usuários de banco capazes de dropar tabelas, tokens de terceiros que gerenciam contas, ou chaves compartilhadas entre ambientes. Prefira uma chave por serviço, por ambiente, com o menor conjunto de permissões.\n\nPrompts rápidos para colar no Claude Code:\n\n- “Procure por tokens hard-coded, senhas e chaves privadas. Liste caminhos de arquivo exatos e os padrões de string que você casou.”\n- “Encontre qualquer código que logue headers de requisição, cookies, vars de ambiente ou objetos de erro completos. Mostre as linhas de log e quais campos sensíveis podem aparecer.”\n- “Verifique se segredos podem acabar em snapshots, exports ou artefatos de build. Identifique o que é capturado e onde é armazenado.”\n\nFinalmente, confirme guardrails: bloqueie segredos no controle de versão (pre-commit/CI checks) e garanta que backups ou snapshots não incluam credenciais em texto claro. Se a plataforma suportar snapshots e rollback, verifique se segredos são injetados em tempo de execução, não embutidos em imagens salvas.\n\n## Prompts que forçam achados concretos (padrões para copiar e colar)\n\nPrompts vagos geram respostas vagas. Force o modelo a se comprometer com evidência: localizações exatas, um trace que você possa seguir, uma repro que você possa rodar e o que tornaria a afirmação errada.\n\nUse um padrão por vez, depois peça para revisar após você confirmar ou rejeitar um detalhe.\n\n- “Procure no repo por auth, sessions, tokens e middleware. Nomeie arquivos exatos, funções e intervalos de linhas envolvidos. Cite os trechos relevantes. Se não puder apontar código, diga 'nenhuma evidência encontrada'.”\n- “Escolha uma entrada controlada pelo usuário (header, query, body, cookie). Mostre o fluxo de dados passo a passo desde o ponto de entrada até onde é usado (SQL, HTML, shell, template, redirect, caminho de arquivo). Liste cada função na cadeia.”\n- “Dê um repro mínimo com curl (método, formato de URL, headers, body). Inclua código de status esperado e um exemplo de resposta de sucesso/falha. Declare suposições (papéis, estado de auth).”\n- “O que invalidaria este achado? Liste 2–3 checagens: flags de config, ordem de middleware, validação por allowlist, queries parametrizadas, escaping do framework. Se alguma estiver presente, explique por que o risco muda.”\n- “Proponha a menor mudança que bloqueie o problema sem quebrar casos válidos. Depois escreva um teste a adicionar (nome, intenção, inputs, resultado esperado). Se houver tradeoffs, descreva-os.”\n\nSe a saída ainda parecer vaga, compacte:\n\n“Responda apenas com: caminho do arquivo, nome da função, linha arriscada e impacto em uma frase.”\n\n## Um exemplo realista: transformar um palpite em um problema verificado\n\nEndpoints de atualização de perfil frequentemente escondem bugs de controle de acesso. Aqui vai um caso pequeno para percorrer este checklist.\n\n um endpoint API atualiza um perfil de usuário:\n\n com JSON como .\n\nVocê pede ao Claude Code para encontrar o handler, traçar como é usado e provar se o servidor aplica propriedade.\n\nO que aparece com frequência:\n\n- a requisição exige sessão ou token, então parece protegida.\n- o handler confia em da query string e atualiza essa conta sem checar se corresponde ao usuário logado.\n- é trimado, mas não é validado como inteiro.\n- SQL é construído por concatenação como .\n\nUm bom relatório é concreto:\n\n- Alta (IDOR + possível SQL injection)\n- uma requisição com login válido altera outra conta quando é modificado; SQL é construído a partir de input não confiável\n- ignore vindo do cliente, use o id da conta autenticada no servidor; parametrizar a query\n- tente atualizar outra conta e espere 403; rejeitar não numérico\n\nApós o patch, recheck rápido:\n\n- Tente a mesma requisição com outro e confirme que falha.\n- Confirme que logs mostram que o servidor usa o id autenticado, não o query param.\n- Confirme que a query usa placeholders/params, não concatenação de string.\n- Rode um teste negativo para input malformado (letras, número muito grande).\n\n## Armadilhas comuns que fazem checagens rápidas perderem problemas reais\n\nA forma mais rápida de perder uma vulnerabilidade é confiar no que a UI aparenta impor. Um botão oculto ou desativado não é uma checagem de permissão. Se o servidor aceita a requisição, qualquer pessoa pode repeti-la com outro ID de usuário, papel diferente ou chamada direta na API.\n\nOutro erro comum é um pedido vago. “Faça uma revisão de segurança” usualmente gera um relatório genérico. Uma checagem rápida precisa de escopo apertado (quais endpoints, quais papéis, quais dados) e um formato de saída rigoroso (nome de arquivo, função, linha arriscada, repro mínima).\n\nA mesma regra vale para saída de IA: não aceite alegações sem apontadores. Se um achado não inclui local de código concreto e um passo-a-passo para dispará-lo, trate como não comprovado.\n\n### Maneiras rápidas de a checagem perder o foco\n\nEstas armadilhas aparecem repetidamente:\n\n- Assumir “apenas admin” porque é uma página admin, sem que o servidor imponha isso\n- Pedir resultados amplos em vez de “mostre a requisição exata que contorna X”\n- Aceitar “possível SQL injection” sem o ponto de construção da query e o caminho de input\n- Pular pontos de entrada menos óbvios como webhooks, jobs agendados, ferramentas de importação e ações admin internas\n- Consertar sintomas (adicionar um filtro ou regex) enquanto a causa raiz é validação ausente ou autorização ausente\n\nSe você se pegar adicionando filtros a cada novo caso de borda, pare. A correção geralmente é mais cedo e mais simples: valide entradas na fronteira e torne checagens de autorização explícitas e centralizadas para que todo caminho de código as utilize.\n\n## Checagens rápidas que você pode rodar antes de liberar\n\nIsto não substitui uma revisão completa, mas captura erros que escapam quando todos estão cansados. Mantenha-as focadas no que você pode provar rápido: uma requisição que você pode enviar, uma página que pode carregar, uma linha de log que pode achar.\n\nCinco checagens rápidas que costumam compensar:\n\n- Tente 10 logins errados seguidos. Há rate limit, lockout ou pelo menos desaceleração? Dá para saber se um email existe por mensagens de erro ou timing?\n- Pegue um recurso real (pedido, fatura, perfil). Mude o ID na URL, no corpo JSON ou nas variáveis GraphQL. Você recebe dados que não são seus, mesmo que apenas metadados?\n- Para campos-chave (email, nome, busca, upload), tente strings muito longas, Unicode estranho e tipos inesperados (número em vez de string). Você aplica limites de comprimento e allowlists onde importa?\n- Procure em logs recentes e bundles cliente por tokens, chaves de API, JWTs ou “Authorization: Bearer”. Cheque páginas de erro também. “Só estava em staging” vira “foi para produção”.\n- Procure concatenação de string em SQL, filtros, renderização de template, comandos shell ou URLs de redirect. Se input chega a um desses sem validação forte, assuma risco até provar o contrário.\n\nAnote as 3 principais correções que você pode entregar nesta semana, não uma lista de desejos. Exemplo: (1) adicionar rate limiting em login e reset, (2) impor checagens de propriedade server-side no endpoint "get by id", (3) limitar comprimento de input e rejeitar caracteres inesperados no campo de busca.\n\n## Próximos passos: torne este checklist parte do seu processo de build\n\nUma checagem só paga se os resultados mudarem o que você entrega. Trate este checklist como um passo pequeno e repetível do build, não uma missão de resgate única.\n\nTransforme cada achado em um item de backlog difícil de entender errado:\n\n- Fix: o que mudará no código ou config\n- Test: como provar que está consertado (uma requisição, um unit test, um passo de QA)\n- Owner: uma pessoa responsável\n- Target date: próxima release ou um dia específico\n- Evidência: arquivo/endpoint e a requisição/payload exato que mostrou o problema\n\nEscolha uma cadência que combine com seu risco e tamanho de time. Para muitos times, cada release é o ideal. Se releases são frequentes, faça uma revisão de 30–60 minutos mensalmente e uma checagem mais curta antes de liberar.\n\nFacilite a repetição criando um pacote de prompts reutilizável e um template de checklist. Mantenha prompts focados em saídas concretas: mostre rota, guarda, requisição falha e comportamento esperado. Armazene o pacote onde seu time já trabalha para não ser pulado.\n\nSe você constrói apps via chat, incorpore o checklist no planejamento. Adicione uma nota curta de “suposições de segurança” para authn/authz, entradas e segredos, e corra a checagem logo depois da primeira versão funcional.\n\nPlataformas como Koder.ai (koder.ai) podem se encaixar bem nesse hábito porque permitem iterar rápido enquanto mantêm checkpoints de revisão. Usar snapshots e rollback ao redor de mudanças arriscadas facilita liberar correções de segurança sem travar quando algo quebra.