Membedah mesin autentikasi aplikasi modern: password hashing dengan Argon2id, session management yang aman dari cookie flags hingga rotation, MFA berbasis TOTP/WebAuthn, dan OAuth 2.0/OIDC beserta jebakan JWT; ditutup praktik auth hardening yang bisa langsung diterapkan pada aplikasi kalian

Setelah di episode 4 kita menguasai empat pilar secure coding, episode ini memfokuskan diri pada sistem yang paling sering diserang dan paling mahal akibatnya bila gagal: autentikasi dan manajemen sesi. Mengapa topik ini pantas satu episode penuh? Karena hampir semua breach dimulai dari kredensial — lemah, bocor, dicuri, atau di-reuse. OWASP menempatkannya di A07, dan credential stuffing adalah vektor nomor satu serangan otomatis saat ini.
Kita bahas berurutan seperti alur hidup identitas: password disimpan (hashing), pengguna terverifikasi (login), status login dipertahankan (session), lapisan kedua ditambahkan (MFA), dan delegasi ke penyedia identitas (OAuth/OIDC).
Aturan pertama dan mutlak: password tidak pernah disimpan sebagai teks atau hash cepat. Fungsi hashing password modern sengaja lambat dan boros memori agar brute force hardware mahal:
| Algoritma | Status | Catatan |
|---|---|---|
| Argon2id | Rekomendasi utama | Winner PHC; parameter memory+time+parallelism |
| scrypt | Baik | Alternatif memory-hard |
| bcrypt | Diterima | Cost factor ≥ 12; batas panjang 72 byte |
| PBKDF2 | Hanya jika wajib compliance | CPU-bound, butuh iterasi sangat tinggi |
| SHA256/MD5 | Terlarang untuk password | Terlalu cepat → trivial brute force |
import { hash, verify } from "@node-rs/argon2";
const passwordHash = await hash(plainPassword, {
memoryCost: 19456, // KiB (~19 MiB)
timeCost: 2,
parallelism: 1,
});
const valid = await verify(passwordHash, submittedPassword);Dua detail yang sering salah:
Important
Pesan error reset password harus generik: "jika email terdaftar, tautan telah dikirim". Membedakan "email tidak terdaftar" vs "password salah" memberi penyerang enumerasi akun gratis — pelanggaran A07 klasik.
Session menjawab pertanyaan server setiap request: "ini siapa?". Dua arsitektur besar: server-side session (ID acak di cookie, state di Redis/DB) dan stateless token (JWT). Untuk aplikasi web konvensional, server-side session lebih aman karena revocation instan.
Set-Cookie: sid=8f3c...; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=3600HttpOnly — JavaScript tidak bisa membaca cookie → XSS tak bisa mencuri sesi langsung.Secure — hanya dikirim via HTTPS.SameSite=Lax (atau Strict untuk app internal) — mitigasi CSRF lintas situs.Max-Age pendek + sliding renewal — jendela pencurian menyempit.Tiga momen wajib rotasi ID sesi: setelah login sukses (mencegah session fixation), setelah perubahan hak akses, dan setelah ganti password. Dan momen wajib invalidasi: logout, timeout idle, dan — sering terlupakan — semua sesi milik user saat indikasi kompromi.
Login sukses → generate ID baru (crypto random ≥ 128 bit)
Logout → hapus state server + clear cookie
Ganti password → revoke semua session user
Idle 30 menit → expire (sliding)
Absolut 12 jam → re-authenticateJWT bukan musuh, tapi tiga jebakannya muncul terus-menerus:
alg: none / algorithm confusion — library lama menerima header alg dari token itu sendiri. Selalu pin algoritma di sisi verifikasi (HS256 atau RS256, eksplisit).Password akan bocor — statistiknya sudah pasti (reuse, phishing, breach). MFA membuat kredensial bocor saja tidak cukup. Tingkatannya bertingkat:
| Metode | Kekuatan | Kelemahan |
|---|---|---|
| SMS OTP | Rendah-sedang | SIM swap, SS7 interception |
| TOTP (authenticator app) | Sedang-baik | Phishable |
| Push approval number matching | Baik | Fatigue attack tanpa number matching |
| WebAuthn/FIDO2/passkey | Terbaik | Origin-bound, tahan phishing |
Arah industri 2026 jelas: passkeys (WebAuthn) — kunci publik tersimpan di device/platform, tidak bisa difishing karena terikat domain. Sebagai AppSec engineer, dorong WebAuthn untuk aplikasi high-value, minimal TOTP sebagai fallback, dan hindari SMS kecuali tidak ada pilihan.
Implementasi TOTP sendiri cukup mudah dengan library (otplib, speakeasy) — simpan secret terenkripsi, window toleransi ±1 periode, dan selalu izinkan recovery code sekali pakai.
Saat kalian butuh "login with Google" atau single sign-on antar service, jangan bangun sendiri — gunakan OAuth 2.0 (authorization framework) + OIDC (layer identitas di atasnya).
Alur paling aman untuk web app adalah Authorization Code Flow + PKCE:
PKCE (code verifier/challenge) wajib bahkan untuk web app confidential client — ia mencegah intercept authorization code. Kesalahan implementasi yang paling sering saya temui saat review:
* padahal cukup email profile — prinsip least privilege berlaku juga di sini.Terapkan urutan ini pada aplikasi latihan kalian — dampak vs effort paling efisien:
HttpOnly Secure SameSite) + rotasi ID pasca-login.Tip
Jangan bangun auth dari nol untuk production. Gunakan penyedia identitas matang (Keycloak self-hosted, Auth0, Clerk) dan habiskan waktu review konfigurasinya — 90% bug auth ada di konfigurasi, bukan di kriptografi.
Inti yang harus dibawa pulang:
Di episode 6 kita keluar dari browser dan masuk wilayah yang jadi tulang punggung semua produk digital: API Security — autentikasi token API, rate limiting yang layak, OWASP API Top 10, dan teknik testing API secara sistematis. Sampai jumpa di episode 6!