7 kegagalan keamanan Claude Code: penyebab, pemulihan, pencegahan
Cegah kebocoran .env, kerusakan produksi, biaya CI, dan prompt injection saat memakai Claude Code.
Claude Code bukan sekadar jendela chat yang memberi saran kode. Ia bisa mengedit file, menjalankan test, membaca status Git, dan mengusulkan perintah deployment. Kemampuan ini berguna, tetapi approval yang diberikan tanpa membaca dapat menjalankan aksi berbahaya lebih cepat daripada mengetiknya manual.
Panduan ini mengubah insiden keamanan yang sering terjadi menjadi guardrail praktis. Untuk pemula: permission adalah batas apa yang boleh dilakukan agent, hook adalah titik pemeriksaan sebelum atau sesudah tool dijalankan, dan sandbox adalah ruang kerja terisolasi agar dampak kesalahan lebih kecil. Contoh di bawah mencakup settings.json, scanner secret dengan Node.js, dan workflow 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"]
Peta kegagalan
| Kasus gagal | Kapan terjadi | Dampak | Guardrail pertama |
|---|---|---|---|
Commit .env | ”Tambahkan juga untuk CI” | API key bocor dan biaya tak terduga | .gitignore plus scan staged files |
| Menghapus data produksi | Migration memakai URL yang salah | Kehilangan data | Cek environment sebelum perintah DB |
git push --force | Konflik diselesaikan terburu-buru | Commit tim tertimpa | Aturan ask dan branch protection |
| Review AI berulang di CI | Setiap PR menjalankan otomasi luas | Biaya Actions dan API naik | max-turns, timeout, least privilege |
| Menempel log tidak tepercaya | Log memuat instruksi tersembunyi | Prompt injection | Tolak fetch web dan shell berisiko |
| Akses MCP terlalu luas | Server eksternal dipercaya terlalu cepat | Data lokal terbaca berlebihan | Izinkan hanya MCP tepercaya |
| Approval fatigue | Pengguna terus menekan approve | Perintah berbahaya lolos | Hook yang fail closed |
Intinya bukan Claude Code tidak aman secara default. Dokumentasi resmi Security menjelaskan permission yang berorientasi read, prompt approval, sandboxing, dan tanggung jawab pengguna. Risiko nyata muncul saat tim sibuk dan manusia melewati pemeriksaan. Konfigurasi yang baik membuat jalur aman lebih mudah daripada jalur berbahaya.
Use case 1: mencegah kebocoran API key
Kesalahan pemula yang paling umum adalah menganggap .env sebagai brankas. Bukan: itu file teks lokal. Ia hanya relatif aman selama tidak masuk Git, log, screenshot, atau prompt. Jika key Stripe, SendGrid, Anthropic, atau GitHub muncul di repository publik, anggap sudah compromised.
Commit bentuk konfigurasi saja, bukan nilai asli.
# .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
Lalu ketatkan permission Claude Code. deny memblokir, ask meminta konfirmasi, dan allow menyetujui perintah aman yang sering dipakai. Halaman resmi Settings dan Configure permissions menjelaskan cara aturan ini dievaluasi.
{
"$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"
]
}
}
Konfigurasi ini tidak mematikan Claude Code. Ia membuat perintah rendah risiko tetap lancar dan aksi destruktif menjadi jelas. Jika proyek membutuhkan akses web, mulai dari aturan sempit: domain yang diizinkan, tujuan, dan review manusia sebelum melonggarkan.
Use case 2: menjaga review PR tetap serius
Di tim, kegagalan berbahaya sering berupa proses yang melonggar. Orang mulai menganggap “AI sudah review” berarti file permission, perubahan workflow, dan handling credential tidak perlu dicek lagi. Justru di titik itu masalah keamanan lolos.
Tambahkan scanner tanpa dependency eksternal. Secara default ia memeriksa staged files; di CI bisa memeriksa seluruh repository dengan --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"
}
}
Pitfall-nya adalah berhenti di “kita punya script.” Letakkan npm run security:staged di rutinitas commit, template PR, atau CI. Meminta Claude Code mengingat security check lebih lemah daripada command yang otomatis gagal.
Use case 3: melindungi produksi dan budget CI
Insiden produksi biasanya muncul dari environment yang tertukar. Masalahnya bukan hanya DROP TABLE; masalah sebenarnya adalah menjalankannya ke DATABASE_URL produksi sambil mengira itu database development. Sebelum meminta Claude Code menghapus data lama, tampilkan label database, cloud project, branch, dan waktu backup dalam teks yang mudah dibaca.
Untuk GitHub Actions, dokumentasi resmi Claude Code GitHub Actions menyarankan API key disimpan di Secrets dan permission dibatasi. Workflow ini hanya mereview diff PR dan tidak memberi write access ke repository.
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 penting karena job review saja tidak membutuhkan akses tulis. timeout-minutes dan --max-turns juga kontrol keamanan: otomasi tanpa batas dapat menjadi insiden biaya dan availability.
Pemulihan jika sudah terjadi
Jika API key bocor, jangan mulai dari membersihkan Git history. Pertama revoke atau rotate key di provider. Repository yang sudah bersih tidak membantu jika nilainya sudah disalin orang lain.
- Revoke atau rotate key yang terekspos.
- Periksa log penggunaan dan billing selama periode exposure.
- Ganti GitHub Secrets, variable platform deploy, dan nilai CI.
- Hapus nilai dari Git history dan minta cache cleanup jika perlu.
- Tambahkan
.gitignore, permission settings, dan scanner di PR remediasi yang sama.
Jika data produksi rusak, pause write atau ubah aplikasi ke read-only sebelum menjalankan perbaikan. Tentukan backup timestamp, target restore, dan batas kehilangan data yang bisa diterima. Perintah recovery harus dijalankan satu per satu dengan konfirmasi manusia dan log.
Dokumentasi, tautan internal, dan langkah berikutnya
Gunakan halaman resmi Security, Configure permissions, Settings, Hooks, dan GitHub Actions sebagai sumber utama. Hooks sangat berguna karena bisa menjalankan pemeriksaan custom sebelum tool dieksekusi.
Untuk bacaan internal, lanjutkan ke /id/blog/claude-code-security-best-practices/, /id/blog/claude-code-permissions-guide/, dan /id/blog/claude-code-secrets-management/.
Jika butuh template siap adaptasi, lihat materi di /products/. Untuk mengubahnya menjadi rencana rollout, kebijakan CI, dan workflow review tim, gunakan opsi konsultasi dan training di /training/.
Di repository uji lokal Masa, konfigurasi ini memblokir .env yang tidak sengaja di-stage, string palsu sk_live_, dan job GitHub Actions yang terlalu permisif sebelum publikasi. Scanner regex tidak pernah menangkap semua format secret; jawaban jangka panjang harus berlapis: rotasi di provider, least privilege, check otomatis, dan review manusia sebelum menyetujui aksi Claude Code.
PDF gratis: cheatsheet Claude Code
Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.
Kami menjaga datamu dan tidak mengirim spam.
Tentang penulis
Masa
Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.
Artikel terkait
Permission safety ladder Claude Code: perluas akses tanpa kehilangan kontrol
Naik dari read-only ke edit terbatas, command bukti, dan cek deploy dengan kontrol yang jelas.
Claude Code Small PR Proof Pack: perubahan kecil yang mudah direview
Paket bukti untuk PR Claude Code: diff, check, URL publik, jalur CTA, dan rollback.
Review gate Claude Code sebelum commit: diff, test, URL publik, dan CTA
Cara memakai Claude Code sebelum commit: diff scope, build, URL publik, link Gumroad, CTA konsultasi, missing test, dan file tidak terkait.