Belajar 2FA Authentication - OWASP & Best Practices Keamanan
Episode 14 of 23

Belajar 2FA Authentication - OWASP & Best Practices Keamanan

Episode ini merangkum best practices keamanan autentikasi dari OWASP: verifikasi hanya di sisi server, timing-safe comparison, larangan mencatat secret dan kode ke log, serta alasan memakai library teruji seperti otplib alih-alih menulis TOTP dari nol.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Semua komponen 2FA sudah dipasang: enrollment, verifikasi, recovery, rate limit, dan transport. Episode 14 adalah lapisan terakhir yang menyatukan semuanya — best practices keamanan dari OWASP Authentication Cheat Sheet yang mengatur cara kerja fitur ini secara keseluruhan.

Tiga aturan yang dibahas di sini sering menjadi pembeda antara fitur 2FA yang aman dan yang sekedar terlihat aman: verifikasi di sisi server, perbandingan yang tahan timing attack, dan disiplin logging. Ditambah satu anti-pattern klasik: menulis TOTP sendiri dari nol.

Verifikasi di Sisi Server Saja

Jangan Percaya Client

Setiap kode TOTP harus diverifikasi di server, tidak pernah di JavaScript browser. Validasi di client hanya untuk kenyamanan pengguna — misalnya memastikan input 6 digit — tapi keputusan benar-salah mutlak di server. Klien bisa dimodifikasi, dan data yang dikirim bisa dipalsukan.

Praktik ini juga berarti endpoint verifikasi harus menolak input yang tidak masuk akal sebelum menghitung: panjang bukan 6 digit, bukan angka, atau field yang hilang. Semakin sedikit kerja yang dilakukan server pada input tak valid, semakin kecil permukaan untuk serangan.

Hindari Enumerasi Status

Pesan error yang membedakan "password salah" dan "kode salah" membantu penyerang memetakan akun. Satu respons generik untuk kegagalan kredensial — tanpa menyebut bagian mana yang gagal — menyulitkan pengumpulan informasi. Episode 6 menerapkan prinsip ini pada pesan verifikasi kode.

Timing-Safe Comparison

Serangan Berbasis Waktu

Perbandingan string biasa mengembalikan false begitu menemukan karakter yang berbeda. Penyerang yang bisa mengukur waktu respons bisa menebak kode karakter demi karakter — serangan yang disebut timing attack. Kode 6 digit menjadi jauh lebih lemah jika karakter dapat ditebak satu per satu.

Ditangani oleh Library

Kabar baiknya: library seperti otplib menangani perbandingan ini secara internal dengan operasi yang waktunya konstan. Kalian tidak perlu menulis perbandingan sendiri — cukup pastikan tidak mengganti authenticator.check dengan perbandingan manual:

JSVerifikasi yang aman vs manual
const aman = authenticator.check(req.body.token, secret);
const rapuh = req.body.token === expectedCode;

Baris aman dihitung dengan perbandingan timing-safe oleh otplib, sedangkan baris rapuh membocorkan informasi melalui waktu. Aturan emasnya: biarkan library yang menangani perbandingan kriptografi.

Timing attack pada aplikasi web nyata lebih sulit dieksekusi karena latensi jaringan menutupi perbedaan kecil, tapi jangan pernah memberi kesempatan. Prinsip pertahanan yang sama berlaku untuk pesan error dan jalur kode: semua hasil harus diproses dengan jalur yang nyaris identik.

Larangan Mencatat Secret dan Kode

Log yang Aman

Baris log yang berisi secret Base32, kode TOTP, atau URI provisioning adalah kecelakaan yang menunggu terjadi. Debugger sementara di endpoint verifikasi sering meninggalkan jejak seperti ini. Audit semua jalur log dan pastikan hanya peristiwa yang dicatat:

Contoh log yang aman untuk audit MFA
mfa_enabled user=550e8400-e29b-41d4-a716-446655440000
mfa_disabled user=550e8400-e29b-41d4-a716-446655440000
mfa_failed user=550e8400-e29b-41d4-a716-446655440000 attempts=3

Catat identitas pengguna dan hasilnya, bukan inputnya. Jika perlu menyimpan jejak untuk forensik, simpan hash satu arah dari kode yang gagal — bukan plaintext.

Jangan Log Body Permintaan

Middleware yang mencatat seluruh body request secara otomatis akan menangkap password dan kode TOTP. Konfigurasikan logging untuk mengecualikan body pada route auth dan MFA, atau gunakan library logging yang sadar field sensitif.

Anti-Pattern: Menulis TOTP Sendiri

Library Teruji Lebih Aman

TOTP tampak sederhana — HMAC, truncation, modulo — tapi detailnya penuh jebakan: endianness counter, encoding Base32, padding, dan perilaku window. Implementasi sendiri yang tampak benar bisa menghasilkan kode yang kadang diterima, kadang tidak, atau tidak kompatibel dengan Google Authenticator.

Gunakan library yang mengikuti RFC dan telah diuji terhadap test vector:

Library TOTP yang teruji
npm install otplib@13.4.1
pip install pyotp==2.10.0

otplib@13.4.1 untuk Node.js dan pyotp untuk Python keduanya mengikuti RFC 4226 dan RFC 6238, diuji terhadap test vector resmi, dan kompatibel dengan Google Authenticator. Menulis ulang dari nol hanya dibenarkan untuk kepentingan belajar — episode 16 bahkan memakai library untuk menguji implementasi.

Kompatibilitas Lintas Ekosistem

Selain keamanan, library memberi satu keuntungan yang sulit ditiru implementasi manual: kompatibilitas. otplib dan pyotp diuji terhadap Google Authenticator, Microsoft Authenticator, dan Authy di banyak versi, sehingga secret yang dibuat di satu ekosistem tetap valid di ekosistem lain. Implementasi sendiri sering lolos uji internal tapi gagal ketika dipakai lintas aplikasi.

Checklist Keamanan 2FA

Rangkuman praktik yang dibahas di episode 7 sampai 14 dalam satu daftar yang bisa kalian tempel di dinding:

  • Secret TOTP tersimpan terenkripsi AES-256-GCM.
  • Verifikasi kode hanya di sisi server dengan library timing-safe.
  • Recovery codes di-hash dan single-use.
  • Rate limit 5 percobaan per menit pada semua endpoint kode.
  • Replay protection dengan lastUsedStep.
  • HTTPS wajib, cookie Secure HttpOnly SameSite.
  • CSP membatasi sumber halaman enrollment.
  • Log hanya peristiwa, tidak pernah secret atau kode.
  • Jangan menulis TOTP sendiri dari nol.

Daftar ini adalah persimpangan dari semua episode sebelumnya. Kalau satu item terlewat, asumsikan fitur 2FA kalian belum siap produksi.

Penutup

Episode 14 menyatukan best practices OWASP: verifikasi murni di sisi server, perbandingan timing-safe yang ditangani library, disiplin logging tanpa secret dan kode, serta keputusan memakai library teruji alih-alih menulis TOTP dari nol.

Inti yang harus dibawa pulang:

  • Verifikasi kode hanya di server, jangan pernah di client.
  • Gunakan pesan error generik untuk mencegah enumerasi akun.
  • Serahkan perbandingan timing-safe kepada library.
  • Jangan pernah mencatat secret, kode, atau URI provisioning.
  • Hindari logging body permintaan pada route auth.
  • Pakai otplib atau pyotp yang teruji terhadap test vector RFC.

Di episode 15 selanjutnya kita akan membahas session, token, dan trusted devices — session jangka pendek dengan rotasi id, logout menyeluruh, cookie trusted device yang terpisah, serta hubungan JWT dengan flag 2FA saat token dikeluarkan.

Belajar 2FA Authentication - OWASP & Best Practices Keamanan | Belajar 2FA Authentication