7 falhas de segurança no Claude Code: causas, recuperação e prevenção
Evite vazamento de .env, danos em produção, custos de CI e prompt injection com Claude Code.
Claude Code não é apenas uma janela de chat que sugere código. Ele pode editar arquivos, executar testes, ler o estado do Git e propor comandos de deploy. Essa capacidade é útil, mas uma aprovação distraída pode executar uma ação perigosa mais rápido do que você digitaria manualmente.
Este guia transforma acidentes comuns de segurança em barreiras práticas. Para iniciantes: permissão é o limite do que o agente pode fazer, hook é um ponto de controle antes ou depois de usar uma ferramenta, e sandbox é um ambiente isolado onde erros causam menos impacto. Os exemplos incluem settings.json, um scanner de segredos em Node.js e um workflow do GitHub Actions.
flowchart TD
Request["User request"] --> Plan["Claude Code plan"]
Plan --> Permission["Permission rules"]
Permission --> Hook["PreToolUse hook"]
Hook --> Execute["Tool execution"]
Execute --> Audit["Log, review, recovery"]
Hook -->|block risky command| Stop["Stop before damage"]
Mapa de falhas
| Falha | Quando acontece | Dano | Barreira inicial |
|---|---|---|---|
Commit de .env | ”Adicione também para a CI” | Vazamento de chave e gasto indevido | .gitignore mais scan de staged files |
| Apagar dados de produção | Migration aponta para a URL errada | Perda de dados | Checagem de ambiente antes de DB |
git push --force | Resolver conflito com pressa | Commits do time sobrescritos | Regras ask e branch protection |
| Review de IA em loop na CI | Toda PR roda automação ampla | Custo de Actions e API | max-turns, timeout, menor privilégio |
| Colar logs não confiáveis | Logs trazem instruções escondidas | Prompt injection | Negar fetch web e shell arriscado |
| MCP amplo demais | Servidor externo confiado rápido demais | Leitura excessiva de dados locais | Permitir apenas MCP confiáveis |
| Fadiga de aprovação | Usuário aceita sem ler | Comandos perigosos aprovados | Hooks que bloqueiam por padrão |
A mensagem não é que Claude Code seja inseguro por padrão. A documentação oficial de Security descreve permissões focadas em leitura, confirmações, sandboxing e responsabilidade do usuário. O risco real aparece quando o processo do time fica apressado. A configuração precisa tornar o caminho seguro mais simples que o perigoso.
Caso de uso 1: impedir vazamento de API keys
O erro mais comum é tratar .env como um cofre. Não é: ele é um arquivo de texto local. Só é relativamente seguro enquanto não entra no Git, logs, screenshots ou prompts. Se uma chave Stripe, SendGrid, Anthropic ou GitHub aparece em um repositório público, ela deve ser considerada comprometida.
Commite apenas o formato da configuração, não os valores reais.
# .gitignore
.env
.env.*
!.env.example
secrets/
*.pem
*.key
*service-account*.json
credentials.json
# .env.example
ANTHROPIC_API_KEY=replace_me
DATABASE_URL=postgres://app_user:password@localhost:5432/app_dev
STRIPE_SECRET_KEY=sk_test_replace_me
Depois ajuste as permissões do Claude Code. deny bloqueia, ask pede confirmação, e allow aprova comandos seguros e repetitivos. As páginas oficiais de Settings e Configure permissions explicam como essas regras são avaliadas.
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)",
"Bash(git status)",
"Bash(git diff *)"
],
"ask": [
"Bash(git push *)",
"Bash(npm run deploy *)",
"Write(./migrations/**)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(rm -rf *)",
"Bash(curl *)",
"Bash(wget *)",
"WebFetch"
]
}
}
Essa configuração não desliga o Claude Code. Ela deixa comandos de baixo risco rápidos e ações destrutivas explícitas. Se o projeto precisa de acesso web, comece estreito: domínio permitido, objetivo claro e revisão humana antes de abrir mais.
Caso de uso 2: manter reviews de PR confiáveis
Em times, a falha perigosa costuma ser de processo. As pessoas passam a achar que “a IA revisou” significa que ninguém precisa olhar arquivos de permissão, workflows ou credenciais. É exatamente aí que problemas passam.
Adicione um scanner sem dependências externas. Por padrão ele revisa arquivos staged; na CI pode revisar todo o repositório com --all.
// scripts/claude-security-check.mjs
import { execFileSync } from "node:child_process";
import fs from "node:fs";
const args = process.argv.slice(2);
const scanAll = args.includes("--all");
const explicitFiles = args.filter((arg) => arg !== "--all");
function runGit(args) {
return execFileSync("git", args, { encoding: "utf8", maxBuffer: 10 * 1024 * 1024 });
}
function filesToScan() {
if (explicitFiles.length > 0) return explicitFiles;
if (scanAll) return runGit(["ls-files"]).split(/\r?\n/).filter(Boolean);
return runGit(["diff", "--cached", "--name-only"]).split(/\r?\n/).filter(Boolean);
}
function readTrackedOrWorkingTree(file) {
if (scanAll || explicitFiles.length > 0) return fs.readFileSync(file, "utf8");
return runGit(["show", `:${file}`]);
}
const forbiddenPath = [
/^\.env$/,
/^\.env\./,
/(^|\/)secrets\//,
/(^|\/).*service-account.*\.json$/i,
/(^|\/)credentials\.json$/i,
/\.(pem|key)$/i
];
const secretPattern =
/(sk-ant-[A-Za-z0-9_-]{20,}|sk_live_[A-Za-z0-9_-]{20,}|AKIA[0-9A-Z]{16}|-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----)/;
let failed = false;
for (const file of filesToScan()) {
if (forbiddenPath.some((pattern) => pattern.test(file))) {
console.error(`[blocked] forbidden secret path: ${file}`);
failed = true;
continue;
}
try {
const text = readTrackedOrWorkingTree(file);
if (secretPattern.test(text)) {
console.error(`[blocked] secret-like value found in: ${file}`);
failed = true;
}
} catch {
// Ignore deleted or binary files.
}
}
if (failed) process.exit(1);
console.log("security check passed");
{
"scripts": {
"security:staged": "node scripts/claude-security-check.mjs",
"security:all": "node scripts/claude-security-check.mjs --all"
}
}
O erro é parar em “temos um script”. Coloque npm run security:staged na rotina de commit, no template de PR ou na CI. Pedir ao Claude Code para lembrar de rodar o check é mais fraco que um comando que falha automaticamente.
Caso de uso 3: proteger produção e orçamento de CI
Incidentes de produção normalmente nascem de confusão de ambiente. O problema não é só DROP TABLE; é executar isso contra o DATABASE_URL de produção achando que era desenvolvimento. Antes de pedir ao Claude Code para apagar dados antigos, mostre em texto claro o rótulo do banco, projeto cloud, branch e horário do backup.
Para GitHub Actions, a documentação oficial de Claude Code GitHub Actions recomenda usar Secrets para API keys e limitar permissões. Este workflow revisa apenas o diff da PR e não recebe permissão de escrita no repositório.
name: Claude Code guarded review
"on":
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
jobs:
claude-security-review:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Run repository secret scan
run: node scripts/claude-security-check.mjs --all
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: "${{ secrets.ANTHROPIC_API_KEY }}"
prompt: >
Review only the pull request diff for secret handling, auth checks,
destructive commands, and permission changes. Do not modify files.
claude_args: |
--max-turns 3
--disallowedTools "Bash(git push *)" "Bash(npm run deploy *)" "Bash(rm -rf *)"
permissions: contents: read importa porque um job só de review não precisa escrever. timeout-minutes e --max-turns também são controles de segurança: automação sem limite pode causar incidentes de custo e disponibilidade.
Recuperação se algo já deu errado
Se uma API key vazou, não comece limpando o histórico do Git. Primeiro revogue ou rotacione a chave no provedor. Um repositório limpo não ajuda se alguém já copiou o valor.
- Revogue ou rotacione a chave exposta.
- Verifique logs de uso e faturamento da janela de exposição.
- Substitua GitHub Secrets, variáveis de deploy e valores de CI.
- Remova o valor do histórico Git e peça limpeza de cache se necessário.
- Adicione
.gitignore, permissões e scanner no mesmo PR de correção.
Se dados de produção foram danificados, pause escritas ou coloque o app em modo somente leitura antes de corrigir. Decida primeiro o backup, destino de restauração e perda aceitável. Comandos de recuperação devem ser executados um por um, com confirmação humana e logs.
Documentação, links internos e próximo passo
Use as páginas oficiais Security, Configure permissions, Settings, Hooks e GitHub Actions como referência. Hooks são especialmente úteis porque permitem checar antes da execução das ferramentas.
Para aprofundar no site, leia /pt/blog/claude-code-security-best-practices/, /pt/blog/claude-code-permissions-guide/ e /pt/blog/claude-code-secrets-management/.
Se você precisa de templates prontos para adaptar, veja os materiais em /products/. Para transformar isso em plano de adoção, política de CI e fluxo de review do time, use as opções de consultoria e treinamento em /training/.
No repositório local de teste de Masa, esta configuração bloqueou um .env staged por engano, uma string falsa sk_live_ e um job de GitHub Actions permissivo demais antes da publicação. Scanner por regex nunca cobre todos os formatos de segredo; a resposta duradoura é em camadas: rotação no provedor, menor privilégio, checks automáticos e revisão humana antes de aprovar ações do Claude Code.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Escada de segurança de permissões no Claude Code
Amplie de read-only para edições limitadas, comandos de prova e deploy checks sem perder controle.
Claude Code Small PR Proof Pack: pequenas mudanças fáceis de revisar
Um pacote de prova para PRs do Claude Code: diff, checks, URL pública, CTA e rollback.
Gate de revisão antes do commit com Claude Code
Revisão antes do commit com Claude Code: diff, build, URL pública, Gumroad, consultoria, testes e arquivos fora do escopo.