Tips & Tricks (Atualizado: 03/06/2026)

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.

7 falhas de segurança no Claude Code: causas, recuperação e prevenção

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

FalhaQuando aconteceDanoBarreira 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çãoMigration aponta para a URL erradaPerda de dadosChecagem de ambiente antes de DB
git push --forceResolver conflito com pressaCommits do time sobrescritosRegras ask e branch protection
Review de IA em loop na CIToda PR roda automação amplaCusto de Actions e APImax-turns, timeout, menor privilégio
Colar logs não confiáveisLogs trazem instruções escondidasPrompt injectionNegar fetch web e shell arriscado
MCP amplo demaisServidor externo confiado rápido demaisLeitura excessiva de dados locaisPermitir apenas MCP confiáveis
Fadiga de aprovaçãoUsuário aceita sem lerComandos perigosos aprovadosHooks 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.

  1. Revogue ou rotacione a chave exposta.
  2. Verifique logs de uso e faturamento da janela de exposição.
  3. Substitua GitHub Secrets, variáveis de deploy e valores de CI.
  4. Remova o valor do histórico Git e peça limpeza de cache se necessário.
  5. 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.

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.

#claude-code #security #incident #best-practices #devops
Grátis

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.

Masa

Sobre o autor

Masa

Engenheiro focado em workflows práticos com Claude Code.