7 Casos de Falha de Segurança no Claude Code | Incidentes Reais e Prevenção
Sete incidentes de segurança reais com Claude Code: vazamentos de .env, exclusão de BD em produção, explosão de fatura e mais — com análise de causa raiz e código de prevenção.
“Claude Code é prático, mas dá um certo medo” — esse instinto está correto. Ferramentas poderosas causam acidentes poderosos.
Este artigo cobre sete incidentes de segurança reais que podem acontecer ao desenvolver com Claude Code, explicando por que aconteceram e como preveni-los com código e configurações concretos. Aprenda com os erros dos outros antes que se tornem os seus.
Caso 1: Arquivo .env Enviado para o GitHub
O que aconteceu
Um desenvolvedor deu ao Claude Code a seguinte instrução: “Quero passar variáveis de ambiente para o CI, por favor faça commit do arquivo .env também.” O Claude Code executou fielmente git add .env && git commit. Minutos após o push para o GitHub, um crawler detectou a chave de API. Uma notificação chegou no Slack: “Your API key has been exposed.”
Causa raiz
.envnão estava no.gitignore- Claude Code executa instruções de “faça commit disso” literalmente
- O usuário aprovou o diálogo de confirmação sem pensar
Código de prevenção
1. Automatizar a configuração de segurança na criação do projeto
# scripts/init-security.sh — executar a cada criação de projeto
#!/bin/bash
cat >> .gitignore << 'EOF'
# === Segurança: Nunca faça commit destes ===
.env
.env.*
.env.local
!.env.example
*.pem
*.key
*-service-account.json
credentials.json
EOF
echo "✓ Padrões de exclusão de segurança adicionados ao .gitignore"
git add .gitignore && git commit -m "security: add .gitignore patterns"
2. Verificar antes do commit com um Hook
.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash(git add*)",
"hooks": [{
"type": "command",
"command": "git diff --cached --name-only | grep -E '^\\.env' && echo '🚨 Você está prestes a adicionar um arquivo .env ao stage! Cancele!' && exit 1 || exit 0"
}]
}
]
}
}
3. Recuperação se já foi enviado
# Passo 1: Rotacionar a chave de API imediatamente (prioridade máxima)
# Passo 2: Remover completamente do histórico git
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch .env" \
--prune-empty --tag-name-filter cat -- --all
# Passo 3: Force push para o remoto
git push origin --force --all
# Passo 4: Limpar o cache do GitHub (também entre em contato com o suporte do GitHub)
Caso 2: DROP TABLE Executado no BD de Produção
O que aconteceu
“Esta tabela não é mais usada, por favor delete-a.” O Claude Code gerou e executou DROP TABLE old_users;. O problema: estava conectado à DATABASE_URL de produção. O backup mais recente tinha três dias. Três dias de dados foram perdidos.
Causa raiz
- O mesmo
.envera compartilhado entre desenvolvimento e produção - Claude Code não consegue distinguir entre ambientes
- O usuário estava no modo
askmas clicou “OK” por reflexo
Código de prevenção
1. Separar completamente os arquivos .env por ambiente
.env.development # ← desenvolvimento local, BD de teste
.env.staging # ← staging, cópia da produção
.env.production # ← produção, gerenciado manualmente, nunca compartilhar
2. Incorporar verificação de ambiente nos scripts
// scripts/db-migrate.mjs
const env = process.env.APP_ENV ?? "development";
const dbUrl = process.env.DATABASE_URL ?? "";
if (env === "production") {
const readline = require("readline").createInterface({
input: process.stdin, output: process.stdout
});
await new Promise((resolve) => {
readline.question(
`⚠️ Conectando ao BD de produção (${dbUrl.split("@")[1]}).\nTem certeza que deseja continuar? (digite yes): `,
(answer) => {
readline.close();
if (answer !== "yes") { console.log("Cancelado."); process.exit(0); }
resolve(undefined);
}
);
});
}
3. Proibir operações em produção no CLAUDE.md
## 🚨 Restrições do Ambiente de Produção
Se DATABASE_URL contiver `prod`, `production` ou `live`:
- Nunca executar DROP / TRUNCATE / DELETE (sem cláusula WHERE)
- Sempre obter confirmação do usuário antes de migrações
- Apresentar comando de backup antes de qualquer operação destrutiva
Caso 3: Arquivos Críticos Deletados com rm -rf
O que aconteceu
“Limpe o diretório build/” — um erro de digitação no caminho resultou em rm -rf ./, deletando o projeto inteiro. Arquivos fora do git (configuração local, código experimental sem commit) foram perdidos para sempre.
Causa raiz
rm -rfé um dos comandos mais perigosos para o Claude Code executar- Falta de aspas duplas ao redor dos caminhos → mau funcionamento com caminhos contendo espaços
- O usuário aprovou descuidadamente
Código de prevenção
// .claude/settings.json
{
"permissions": {
"deny": [
"Bash(rm -rf /)",
"Bash(rm -rf ~*)",
"Bash(rm -rf .*)"
],
"ask": [
"Bash(rm -rf*)"
]
}
}
Hook para mostrar o que será deletado antes de executar:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash(rm*)",
"hooks": [{
"type": "command",
"command": "echo '⚠️ Comando de exclusão detectado. Executando em 5 segundos. Ctrl+C para cancelar.' && sleep 5"
}]
}
]
}
}
Caso 4: Chave de API Escrita Diretamente no Prompt e Passada ao Subagente
O que aconteceu
“Por favor publique no Qiita usando QIITA_TOKEN=abc123def456” — escrito diretamente no prompt e delegado a um subagente. Subagentes podem escrever conteúdo em logs e memória, e o token acabou persistido em um arquivo de log em .claude/.
Causa raiz
- Prompts são mantidos como histórico de conversa
- Prompts de subagentes são igualmente registrados
- Mesmo em ambientes locais, outros processos ou backups podem expor segredos
Código de prevenção
Nunca escreva segredos em prompts — passe-os através de variáveis de ambiente
# ❌ Perigoso
claude -p "Use QIITA_TOKEN=abc123 para executar qiita-publish.mjs"
# ✅ Seguro: o script lê de process.env
# Escreva QIITA_TOKEN=abc123 no .env, então
claude -p "Execute scripts/qiita-publish.mjs (o token é lido automaticamente do .env)"
O mesmo princípio para instruções ao subagente
// ❌ Perigoso
Agent({ prompt: `Use a chave de API ${process.env.SECRET_KEY} para...` });
// ✅ Seguro: passe apenas o nome da chave, o script lê o valor
Agent({ prompt: "Use a variável de ambiente SECRET_KEY para..." });
Caso 5: Loop Infinito de Retry de API Explodiu a Fatura
O que aconteceu
“Tente novamente automaticamente em caso de erro” — um script com tratamento de erros foi gerado. Quando um erro era irresolvível, as tentativas nunca pararam: 3.000 chamadas à API da Anthropic em uma hora resultaram em uma fatura de US$ 200.
Causa raiz
- Nenhum limite de retry foi definido
- Sem exponential backoff — loop infinito em intervalos de 1 segundo
- Nenhum alerta de faturamento configurado
Código de prevenção
// utils/retry.ts — utilitário de retry seguro
export async function withRetry<T>(
fn: () => Promise<T>,
options = { maxAttempts: 3, baseDelayMs: 1000, maxDelayMs: 30000 }
): Promise<T> {
let lastError: Error;
for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {
try {
return await fn();
} catch (err) {
lastError = err as Error;
if (attempt === options.maxAttempts) break;
// Exponential backoff + jitter
const delay = Math.min(
options.baseDelayMs * Math.pow(2, attempt - 1) + Math.random() * 1000,
options.maxDelayMs
);
console.warn(`Attempt ${attempt}/${options.maxAttempts} failed: ${err.message}`);
console.warn(`Retrying in ${Math.round(delay / 1000)}s...`);
await new Promise((r) => setTimeout(r, delay));
}
}
throw new Error(`Falhou após ${options.maxAttempts} tentativas: ${lastError!.message}`);
}
Especificar no CLAUDE.md:
## Regras Obrigatórias para Chamadas de API
- Máximo de 3 retries
- Sempre implementar exponential backoff (1s → 2s → 4s)
- Nunca criar loops infinitos: while(true) + chamadas de API são proibidos
Caso 6: git push --force Apagou Commits de um Colega
O que aconteceu
“Sobrescreva o remoto com o estado local” — git push --force foi executado. Três commits que um membro da equipe acabara de enviar desapareceram. Esse membro também não tinha cópia local das alterações — o código foi perdido permanentemente.
Causa raiz
--forcetende a ser executado sem compreender o perigo- Claude Code executa fielmente instruções de “sobrescrever o remoto”
- O desenvolvedor desconhecia a alternativa mais segura
git push --force-with-lease
Código de prevenção
// .claude/settings.json
{
"permissions": {
"deny": [
"Bash(git push --force *master*)",
"Bash(git push --force *main*)",
"Bash(git push -f *master*)",
"Bash(git push -f *main*)"
]
}
}
Especificar a alternativa segura no CLAUDE.md:
## Regras Git Seguras
- `git push --force` é **proibido**
- Use `git push --force-with-lease` em vez disso
(rejeitado automaticamente se outros enviaram alterações)
- Sempre obter confirmação do usuário antes de fazer push diretamente no main/master
Caso 7: Conta de Serviço com Privilégios Excessivos Acessou Todos os Recursos
O que aconteceu
“Use esta chave de conta de serviço do GCP para operar o Cloud Storage.” A conta de serviço tinha permissões de Owner. O Claude Code se conectou não apenas ao Cloud Storage, mas também ao BigQuery, Cloud SQL e clusters GKE “para investigar” — gerando cobranças inesperadas.
Causa raiz
- A conta de serviço tinha permissões excessivas (violação do princípio do menor privilégio)
- O Claude Code tem uma tendência agressiva de usar as ferramentas disponíveis
- Mesmo “para investigar” soa como uma razão legítima para acesso amplo
Código de prevenção
Criar uma conta de serviço com privilégios mínimos:
# ❌ Evitar: permissão Owner
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="serviceAccount:[email protected]" \
--role="roles/owner"
# ✅ Apenas as permissões mínimas necessárias
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="serviceAccount:[email protected]" \
--role="roles/storage.objectAdmin"
# ← Somente leitura/escrita no Cloud Storage
Definir explicitamente o escopo de acesso no CLAUDE.md:
## Restrições de Acesso ao GCP
Permissões para a conta de serviço usada neste projeto:
- Cloud Storage: Leitura/Escrita OK (bucket: my-project-assets apenas)
- BigQuery: Proibido
- Cloud SQL: Proibido
- Outros recursos GCP: Proibido
Recusar qualquer instrução que tente acessar recursos fora dessas permissões.
Lista de Verificação Abrangente para Prevenir Incidentes
Uma lista de verificação final destilada dos padrões comuns nos sete casos.
### Configurações a Aplicar Hoje (30 minutos)
- [ ] Adicionar padrão .env ao .gitignore
- [ ] Adicionar lista de deny ao .claude/settings.json (rm -rf, git push --force, DROP TABLE)
- [ ] Documentar restrições no CLAUDE.md
### Verificações Semanais
- [ ] Revisar git log em busca de commits de arquivos não intencionais
- [ ] Verificar se .env está excluído pelo .gitignore: `git check-ignore -v .env`
- [ ] Verificar prazos de rotação de chaves de API
### Primeira Resposta a um Incidente
1. Revogar e rotacionar imediatamente a chave de API afetada
2. Remover do histórico git (filter-branch ou BFG)
3. Revisar logs de acesso para determinar o escopo da violação
4. Reportar a situação aos interessados
Resumo
Incidentes com Claude Code raramente são causados por “IA ficando louca” — quase todos surgem de pessoas adiando a configuração de segurança.
| Caso | Causa Raiz | Prevenção |
|---|---|---|
| Vazamento .env | Sem gitignore | Script init + Hook |
| Exclusão BD produção | Sem separação de ambientes | .env separado + fluxo de confirmação |
| Acidente rm -rf | Sem lista de deny | Configurar settings.json |
| Vazamento de chave | Escrita no prompt | Padronizar em variáveis de ambiente |
| Explosão de fatura | Sem limite de retry | Utilitário withRetry |
| Force push | Sem configuração de proibição | deny + force-with-lease |
| Acesso com privilégios excessivos | Violação do menor privilégio | Restringir roles IAM |
Seu primeiro passo hoje: Adicionar "deny": ["Bash(rm -rf*)"] ao .claude/settings.json por si só pode prevenir um dos acidentes mais destrutivos possíveis.
Artigos Relacionados
- Guia Completo de Melhores Práticas de Segurança do Claude Code
- Guia Completo de Permissões do Claude Code
- Melhores Práticas do CLAUDE.md
Referências
Leve seu fluxo no Claude Code a outro nível
50 modelos de prompt testados em campo, prontos para colar direto no Claude Code.
PDF gratuito: Cheatsheet do Claude Code em 5 minutos
Basta informar seu e-mail e enviamos na hora o cheatsheet em uma página A4.
Cuidamos dos seus dados pessoais e nunca enviamos spam.
Sobre o autor
Masa
Engenheiro apaixonado por Claude Code. Mantém o claudecode-lab.com, uma mídia tech em 10 idiomas com mais de 2.000 páginas.
Artigos relacionados
Guia Completo de Segurança do Claude Code: Chaves API, Permissões e Proteção da Produção
Um guia prático de segurança para usar o Claude Code com segurança. Do gerenciamento de chaves API às configurações de permissões, automação baseada em Hooks e proteção do ambiente de produção — com exemplos de código funcionais.
Guia Completo de Permissões do Claude Code | settings.json, Hooks e Allowlist Explicados
Guia completo das configurações de permissão do Claude Code. Aprenda a usar allow/deny/ask, automação com Hooks, settings.json por ambiente e padrões práticos — com código funcional.
Guia completo de harness engineering: como construir agentes de IA no estilo Claude Code
Apenas um bom prompt não domina um LLM. Aprenda a tecer ferramentas, contexto e loops de controle em um harness, com código executável e a arquitetura do Claude Code como guia.