Semua artikel
// Artikel

Secret di Source Code: Checklist Review dan Remediasi

Dipublikasikan 2 Juli 2026

Credential yang pernah di-commit adalah kejadian paparan, walau repository tidak terbuka. Salinannya dapat ada di fork, cache, log build, bundle rilis, mesin developer, dan history Git. CWE-798 mendefinisikan hard-coded credential sebagai password atau key kriptografis yang dikandung produk. Panduan mitigasinya meminta credential outbound ditempatkan di luar kode dan dilindungi dengan akses ketat. OWASP Secrets Management juga menekankan siklus hidup, least privilege, audit, rotasi, pencabutan, dan kedaluwarsa.

Mulai dari keputusan containment

Jangan mulai dengan menghapus baris atau menulis ulang history. Tetapkan dulu apakah nilainya nyata, layanan mana yang menerimanya, masa berlaku, dan izin yang dimilikinya. Perlakukan credential aktif yang pernah di-commit sebagai bocor sampai bukti menyatakan sebaliknya. Placeholder seperti example.invalid bukan insiden; token yang disalin dari variabel CI mungkin insiden. Jangan tempel nilai yang dicurigai ke tiket, chat, keluaran scanner, atau worksheet ini.

Field buktiArtefak terisiPemilikLulus / gagal
ID temuanSEC-2026-041, path repository, SHA commitPemilik securityLulus: record tanpa nilai secret
Inventaris credentialissuer, subjek, lingkungan, izin, kedaluwarsaPemilik layananGagal: issuer atau izin tidak diketahui
Bukti pencabutanevent audit issuer dan uji penolakan credential lamaPemilik identitasLulus: credential lama ditolak
Bukti penggantideployment memakai referensi secret baru, bukan literalPemilik rilisLulus: build dan smoke test berhasil
Keputusan historyrecord retain atau rewrite yang disetujui risikoPemilik repositoryGagal: rewrite sebelum pencabutan

Artefak selesai adalah record insiden bertanggal berisi identifier dan tautan bukti, bukan credential mentah. Cara ini menjaga jejak audit tanpa memperluas paparan.

Ganti konfigurasi literal dengan injeksi runtime

Kode buruk mengikat secret ke source dan sering ke setiap artefak build:

const webhookToken = "live-token-do-not-commit";
await fetch(url, { headers: { Authorization: `Bearer ${webhookToken}` } });

Pakai konfigurasi runtime dari platform dan gagal tertutup bila nilainya tidak ada:

const webhookToken = process.env.WEBHOOK_TOKEN;
if (!webhookToken) throw new Error("WEBHOOK_TOKEN is not configured");
await fetch(url, { headers: { Authorization: `Bearer ${webhookToken}` } });

Injeksi environment tidak otomatis membuat secret aman: inspeksi proses, crash report, dan log CI yang terlalu luas masih dapat membocorkannya. Pakai secret manager atau binding deployment terlindungi bila tersedia, berikan workload identity dengan akses minimum, dan jangan mencetak objek environment. OWASP menganjurkan pengelolaan terpusat dan least privilege. NIST SP 800-57 menempatkan manajemen key kriptografis sebagai siklus hidup, bukan pilihan penyimpanan sekali jadi.

Review lokasi yang sering lolos scanner

Telusuri kode, definisi infrastruktur, fixture test, resource mobile, berkas contoh, arsip paket, layer container, variabel CI, dokumentasi hasil generate, dan log deployment. Review juga titik penggunaan: key dapat tidak ada di source tetapi tercetak oleh debug statement. Verifikasi binary karena nilai dalam bundle sisi klien dapat diekstrak. Kecocokan scanner hanya petunjuk; bukan bukti nilai masih valid atau memiliki izin tinggi.

Alur pengecualian

Integrasi lama kadang masih membutuhkan credential statis sambil pengganti dibangun. Pemilik membuka pengecualian bertanggal berisi layanan terdampak, alasan, scope least-privilege, kontrol kompensasi, penyetuju security, tanggal berakhir, dan tiket remediasi. Contoh: EXC-SEC-019 mengizinkan satu token API partner read-only pada konfigurasi runtime terlindungi selama 14 hari sambil workload identity diaktifkan. Pengecualian berhenti saat kedaluwarsa: cabut token atau perbarui persetujuan dengan bukti baru. Pengecualian tidak pernah mengizinkan secret di-commit ke source.

Remediasi dengan urutan aman

  1. Nonaktifkan atau cabut credential pada issuer; rotasi konfigurasi yang bergantung padanya.
  2. Validasi pengganti lewat jalur runtime yang dituju dan pastikan credential lama ditolak.
  3. Periksa event audit untuk penggunaan sejak paparan; simpan record relevan dalam proses insiden.
  4. Hapus literal dari source aktif, artefak, contoh, dan log. Rewrite history hanya setelah containment dan koordinasi karena mengganggu kolaborator tanpa mencabut salinan nilai.
  5. Tambahkan deteksi secret sebelum commit dan di CI, lalu uji detector hanya memakai marker sintetis.

Penerimaan lulus bila tidak ada literal aktif pada jalur pengiriman yang direview, pengganti berizin minimum, nilai lama ditolak, record bukti lengkap, serta pengecualian berakhir atau ditutup. Kegagalan memicu pemilik insiden, pencabutan credential, investigasi terukur, dan retest. Audit kode dapat menelusuri penggunaan secret dari batas konfigurasi sampai panggilan outbound.

Verifikasi batas pengganti

Deploy pengganti ke environment uji terisolasi, panggil hanya workload identity yang dituju, lalu pastikan audit issuer mencatat subjek baru tanpa nilai secret. Setelah itu panggil integrasi sama memakai referensi yang dicabut: hasil yang diharapkan adalah autentikasi ditolak, bukan retry memakai fallback tertanam. Simpan request ID, identifier secret, event issuer, revisi deployment, pemilik, dan hasil. Rotasi gagal memerlukan rencana rollback yang mengganti referensi secret, bukan mengaktifkan kembali credential bocor.

Review praktik dan penutupan

Telusuri satu kredensial dari pembuatan hingga penggunaan runtime dan penghentian. Misalnya worker membutuhkan token database. Deployment harus menerima secret lewat binding platform, kode membaca binding saat eksekusi, dan log tidak memuat nilai maupun authorization header turunannya. Uji nilai sintetis tidak valid di staging dengan grep -R "test-secret-do-not-use" .; output yang diharapkan tidak menemukan kecocokan repositori setelah nilai dihapus. Periksa artefak build dan kebijakan source map juga, karena source tree bersih tidak membuktikan bundle bersih.

Review jalur gagal. Exception seperti binding hilang boleh menyebut nama binding, namun tidak boleh menserialisasi objek environment, request header, URL koneksi, atau prefiks token. Rotasi dapat membuat nilai lama dan baru berlaku sementara; tentukan pemilik, jendela overlap, kondisi rollback, serta verifikasi pencabutan. Jangan taruh secret berumur panjang dalam aplikasi mobile: ekstraksi package membuat nilai tertanam menjadi publik walau diobfuscate.

Bukti penutupan berisi identifier secret atau referensi opak, tanggal scan repositori, hasil scan CI, pemeriksaan binding runtime memakai kredensial sintetis, pemilik rotasi, dan catatan pencabutan. Jangan menempelkan nilai secret ke tiket, screenshot, log pengujian, atau komentar review. Buka ulang saat jalur akses, platform deployment, dependensi, atau principal berubah.

Sources

Punya sistem yang perlu diuji?