Mindset keamanan itu satu kebiasaan: sebelum nulis fitur, kamu nanya dulu "fitur ini bisa disalahgunakan gimana?" Bayangin kamu bikin kunci untuk sebuah ruangan. Tukang kunci yang baik gak cuma mikir "gimana supaya yang berhak bisa masuk", tapi juga "gimana supaya yang gak berhak gak bisa". Cara berpikir itu yang bikin kodenya aman, bukan tool tertentu.
🧪 Tebakan cepat: sebuah tim bilang "kita aman karena pakai firewall, jadi gak perlu validasi input di aplikasi". Prinsip keamanan apa yang mereka langgar? Tebak dulu, jawabannya ada di bagian "Pertahanan berlapis".
Prinsip pertama: least privilege
Least privilege (hak akses paling sedikit) berarti tiap orang atau proses cuma diberi akses seminimal yang dia butuhkan untuk tugasnya. Kalau sebuah fungsi cuma perlu membaca data, jangan kasih dia izin menghapus.
Di Lab, ada tiga peran dengan kebutuhan yang jelas:
// Yang BENAR-BENAR dibutuhkan tiap peran
const needs = {
viewer: ['read'], // cukup baca
editor: ['read', 'write'], // baca dan tulis
admin: ['read', 'write', 'delete'], // semuanya
}
- Viewer cuma perlu
read. Kasih diadeleteberarti over-privilege: kalau akun viewer dibajak, penyerang bisa menghapus data. - Editor perlu
readdanwrite, gak lebih. - Admin memang butuh ketiganya. Least privilege bukan berarti "tolak semua", tapi "pas sesuai kebutuhan". Kasih lebih = risiko, kasih kurang = kerjanya macet.
Jangan percaya input user
Semua input dari user, baik dari form, URL, header, maupun cookie, harus dianggap berbahaya sampai dibuktikan aman. Caranya:
- Validasi tipe dan panjangnya (string, angka, email, batasi panjang).
- Pakai whitelist (daftar yang boleh), bukan blacklist (daftar yang dilarang). Blacklist selalu ketinggalan satu payload baru.
Gagal dengan aman
Kalau terjadi error, sistem harus jatuh ke kondisi aman (menolak), bukan terbuka.
// BURUK: error membocorkan isi dalam
res.status(500).json({ error: err.message, stack: err.stack })
// BAIK: user dapat pesan umum, detail dicatat di server
console.error(err) // log lengkap untuk kamu
res.status(500).json({ error: 'Terjadi kesalahan. Coba lagi.' })
- Stack trace dan query SQL jangan pernah dikirim ke user: itu peta buat penyerang.
- Saat ragu apakah seseorang boleh, defaultnya tolak, bukan izinkan.
Pertahanan berlapis
Defense in depth (pertahanan berlapis) adalah strategi memasang beberapa lapisan keamanan, sehingga kalau satu lapisan ditembus, lapisan berikutnya masih melindungi. Contoh: validasi input di frontend dan backend, firewall di depan server, enkripsi di database, dan pencatatan di tiap lapis.
Tim yang bilang "cukup pakai firewall, gak perlu validasi input" melanggar prinsip ini: mereka mengandalkan satu lapis saja. Kalau firewall tembus atau serangannya datang dari jalur yang diizinkan, gak ada lagi yang menahan. Itu jawaban tebakannya: yang dilanggar adalah defense in depth. Validasi input di aplikasi tetap wajib sebagai lapisan tambahan.
⚠️ Jebakan yang sering ketemu
- Blacklist sebagai pengaman utama. Memblokir "yang jelas jahat" selalu kebobolan payload baru. Pakai whitelist: izinkan yang jelas aman, tolak sisanya.
- Mengandalkan satu lapis. Firewall saja, atau validasi di frontend saja, bukan pengaman. Pasang berlapis.
- Error yang membocorkan isi dalam. Mengirim stack trace atau query ke user memberi penyerang peta sistemmu. Pesan umum untuk user, detail untuk log.
- Kode yang terlalu ribet. Makin kompleks kodenya, makin banyak celah tersembunyi. Yang sederhana lebih mudah diamankan.
TL;DR: Mindset keamanan dimulai dengan menanyakan "bisa disalahgunakan gimana?" sebelum nulis kode. Least privilege: kasih akses pas sesuai kebutuhan (viewer cukup read, editor read dan write, admin ketiganya). Jangan percaya input user, pakai whitelist bukan blacklist. Gagal dengan aman: saat error atau ragu, defaultnya tolak. Defense in depth berarti banyak lapisan, dan mengandalkan firewall saja melanggar prinsip itu.