Threat modeling login API adalah cara paling praktis untuk menurunkan risiko abuse, credential stuffing, brute force, dan session hijack sebelum insiden benar-benar terjadi. Intinya bukan membuat dokumen panjang, melainkan memetakan alur login, aset yang dilindungi, titik serang, lalu mengubah temuan itu menjadi kontrol backend yang bisa diuji.

Konteks teknologi boleh berubah cepat. Hype AI dan ledakan produk baru tidak menghapus fakta dasar bahwa sistem autentikasi tetap diserang dengan pola lama: input berbahaya, sesi bocor, token dicuri, retry tak terbatas, dan observabilitas yang lemah. Karena itu, pendekatan yang disiplin tetap relevan: model ancaman dulu, lalu hardening yang spesifik pada endpoint, cookie, token, secret, dan log.

Artikel ini memakai konteks tren akar ledakan AI hanya sebagai pengingat bahwa kemajuan teknologi tidak menggantikan dasar keamanan. Sistem modern tetap butuh threat model yang konkret, terutama di area login yang langsung terhubung ke identitas pengguna.

Apa yang harus dimodelkan pada login API

Jangan mulai dari daftar kontrol. Mulailah dari flow dan aset. Untuk login API modern, aset utamanya biasanya:

  • Kredensial pengguna: email/username, password, OTP, recovery code
  • Session identifier atau refresh token
  • Access token, bila arsitektur memakai token-based auth
  • Secret untuk signing/verifikasi token atau encrypt cookie
  • Data identitas dan profil yang dipakai sesudah login
  • Audit log dan sinyal deteksi anomali

Setelah itu, gambarkan jalur data minimum:

  1. POST /login menerima identifier dan password
  2. Backend validasi input, cek account state, verifikasi password hash
  3. Sistem menerapkan rate limit / lockout adaptif
  4. Jika lolos, backend membuat session atau menerbitkan token
  5. Client menyimpan cookie sesi atau access token sesuai desain
  6. Endpoint berikutnya memverifikasi sesi/token pada setiap request
  7. Logout, refresh token, password reset, dan device revocation harus masuk model yang sama

Kesalahan umum adalah memodelkan hanya endpoint login, tetapi mengabaikan endpoint pendukung seperti /refresh, /logout, /password/reset, /me, upload avatar, atau perubahan email. Padahal penyerang sering masuk lewat area pendukung yang kontrolnya lebih longgar.

Metode threat modeling yang pragmatis

Anda tidak harus memakai proses formal yang berat. Untuk backend web nyata, pendekatan berikut cukup efektif:

1. Petakan komponen dan trust boundary

Tulis komponen yang benar-benar terlibat:

  • Browser atau mobile app
  • API gateway / reverse proxy
  • Auth service / monolith backend
  • Database user
  • Cache untuk session atau rate limit
  • Log pipeline / SIEM
  • Object storage untuk avatar, bila ada

Tandai batas kepercayaan: internet publik, jaringan internal, storage, cache, dan sistem observabilitas. Di titik inilah penyalahgunaan sering muncul, misalnya header spoofing dari proxy yang salah konfigurasi atau akses langsung ke storage object.

2. Identifikasi abuse case, bukan hanya bug

Threat model login API harus memikirkan perilaku penyerang:

  • Credential stuffing dari daftar akun bocor
  • Password spraying dengan banyak username dan satu password umum
  • Brute force per akun atau per IP
  • User enumeration dari perbedaan pesan error atau waktu respons
  • Session hijack melalui cookie bocor, XSS, malware browser, atau MITM pada koneksi yang tidak dipaksa TLS
  • Refresh token replay
  • Abuse upload avatar untuk menyimpan file berbahaya atau menguras storage
  • Log poisoning dengan input yang sengaja memecah format log

3. Nilai dampak dan peluang

Prioritaskan ancaman yang memiliki kombinasi dampak tinggi dan peluang tinggi. Untuk sebagian besar aplikasi internet-facing, tiga prioritas teratas biasanya:

  1. Penyalahgunaan login massal: stuffing, spraying, brute force
  2. Pembajakan sesi: cookie/token dicuri lalu dipakai ulang
  3. Kehilangan visibilitas: tidak ada audit trail untuk mendeteksi dan merespons

Tabel ancaman vs mitigasi

AncamanContoh jalur serangMitigasi konkret
Credential stuffingBot mencoba ribuan kombinasi email/password dari data breachRate limit per IP dan per akun, lockout adaptif, MFA untuk kondisi berisiko, deteksi pola login massal, password hashing kuat
Password sprayingSatu password umum dicoba ke banyak akun untuk menghindari lockout per akunRate limit global per source, korelasi per ASN/device/fingerprint, deteksi banyak akun gagal dari sumber yang sama
User enumerationRespons berbeda untuk akun tidak ada vs password salahPesan error generik, konsistensi status code dan bentuk respons, hindari perbedaan waktu yang mencolok
Session hijackCookie/token dicuri dari XSS, log, proxy, atau browser yang kompromiCookie HttpOnly, Secure, SameSite, rotasi session setelah login, TLS wajib, TTL terbatas, device/session revocation
Refresh token replayRefresh token lama dipakai ulang setelah rotasiRotasi refresh token one-time-use, simpan token family/server-side state, deteksi reuse dan cabut seluruh keluarga token
JWT abuseToken terlalu lama, klaim tak tervalidasi, secret bocorTTL pendek untuk access token, verifikasi issuer/audience/expiry, key rotation, jangan simpan token sensitif di localStorage bila bisa dihindari
Input abusePayload login terlalu besar, format aneh, log injectionValidasi panjang/format, batas ukuran body, normalisasi input, sanitasi saat logging
Avatar/upload abuseUpload file berbahaya setelah autentikasi untuk pivot seranganWhitelist tipe file, verifikasi MIME dan magic bytes, simpan di object storage non-eksekusi, scan malware bila relevan, URL terotorisasi
Weak secret managementSigning key bocor dari repo/env yang salah kelolaSimpan secret di secret manager, rotasi berkala, dukung beberapa key aktif saat transisi, audit akses secret
Kehilangan jejak auditInsiden terjadi tetapi tidak ada data siapa login dari manaAudit log terstruktur untuk login sukses/gagal, refresh, logout, revoke, perubahan password, alert anomali

Menerjemahkan threat model menjadi hardening yang konkret

Desain auth flow yang minim celah

Flow login yang sehat biasanya memiliki sifat berikut:

  • Validasi input dilakukan sebelum query mahal ke database
  • Verifikasi password memakai hash adaptif yang diakui luas
  • Rate limit aktif sebelum dan sesudah verifikasi password, tergantung arsitektur
  • Session ID dirotasi setelah login berhasil untuk mencegah session fixation
  • Perubahan privilege atau MFA challenge juga memicu rotasi sesi/token
  • Logout benar-benar mencabut sesi server-side atau menandai refresh token tidak valid

Bila memakai sesi berbasis cookie, kontrol revocation biasanya lebih sederhana karena server punya state. Bila memakai JWT stateless untuk access token, perhatikan bahwa revocation access token tidak instan kecuali Anda menambah mekanisme denylist, TTL sangat pendek, atau arsitektur token berlapis dengan refresh token yang bisa dicabut.

Cookie session vs JWT: pilih berdasarkan kebutuhan, bukan tren

Session cookie cocok bila aplikasi web Anda berjalan di domain yang bisa mengandalkan cookie browser dan Anda butuh kontrol server-side yang kuat atas revocation. Kelebihannya:

  • Mudah dicabut dari server
  • Tidak mengekspos token ke JavaScript bila memakai HttpOnly
  • Lebih aman dari pencurian via XSS dibanding token yang disimpan di penyimpanan yang bisa diakses script

Kekurangannya:

  • Perlu perhatian pada CSRF
  • Kurang nyaman untuk beberapa pola integrasi lintas domain bila desain tidak matang

JWT access token berguna untuk arsitektur terdistribusi dan API antar layanan, tetapi bukan solusi otomatis lebih aman. Kelebihannya:

  • Verifikasi lokal tanpa lookup database pada setiap request
  • Cocok untuk service-to-service atau federasi tertentu

Risikonya:

  • Sulit direvoke bila benar-benar stateless
  • Sering disimpan di tempat yang tidak aman
  • Kesalahan verifikasi klaim atau rotasi key bisa fatal

Untuk aplikasi web biasa, pola yang sering lebih aman adalah: session cookie atau refresh token yang disimpan aman, plus access token berumur pendek hanya jika memang diperlukan.

Konfigurasi cookie yang aman

Jika memakai cookie untuk sesi:

  • HttpOnly: mencegah akses dari JavaScript
  • Secure: hanya terkirim lewat HTTPS
  • SameSite=Lax atau Strict sesuai kebutuhan alur login Anda
  • Scope domain/path sesempit mungkin
  • TTL masuk akal dan didukung idle timeout di server bila relevan

Kesalahan umum:

  • Menggunakan SameSite=None tanpa alasan jelas
  • Menyetel domain cookie terlalu luas sehingga subdomain lain ikut menerima
  • Tidak merotasi session ID setelah autentikasi berhasil

Validasi input pada endpoint login

Endpoint login terlihat sederhana, tetapi tetap butuh validasi defensif. Tujuannya bukan hanya mencegah SQL injection—ORM modern biasanya sudah membantu—melainkan juga mengurangi attack surface operasional.

POST /api/login
Content-Type: application/json

{
  "email": "[email protected]",
  "password": "secret"
}

Kontrol yang sebaiknya ada:

  • Batas ukuran body request
  • Panjang maksimum untuk email/username dan password
  • Normalisasi input yang konsisten, misalnya trimming untuk identifier bila kebijakan bisnis mengizinkan
  • Tolak tipe data yang salah, array/object tak terduga, atau field berlebih bila kontrak API ketat
  • Jangan log password atau token mentah dalam kondisi apa pun

Contoh pseudocode handler:

function loginHandler(req) {
  enforceTls(req)
  rejectIfBodyTooLarge(req)

  const email = normalizeEmail(req.body.email)
  const password = req.body.password

  validateEmailFormat(email)
  validatePasswordTypeAndLength(password)

  applyRateLimit({ ip: req.ip, account: email })

  const user = findUserByEmail(email)
  const passwordOk = user ? verifyPassword(password, user.passwordHash) : fakeVerify()

  if (!passwordOk) {
    recordFailedLogin(email, req.ip, req.userAgent)
    maybeTriggerAdaptiveLockout(email, req.ip)
    return genericUnauthorized()
  }

  if (requiresStepUp(user, req)) {
    return startMfaChallenge(user)
  }

  const session = issueSession(user, req)
  rotateSessionId(session)
  recordSuccessfulLogin(user.id, req.ip, req.userAgent)
  return setSessionCookie(session)
}

fakeVerify() dipakai untuk membantu mengurangi perbedaan perilaku saat akun tidak ditemukan, sehingga enumeration lebih sulit. Ini bukan solusi tunggal, tetapi berguna bila diimplementasikan dengan hati-hati.

Rate limit dan lockout adaptif

Salah satu hasil terpenting dari threat modeling login API adalah keputusan rate limiting yang tidak naif. Hanya membatasi per IP tidak cukup, karena penyerang bisa memakai botnet atau proxy pool. Hanya membatasi per akun juga tidak cukup, karena password spraying menargetkan banyak akun sekaligus.

Gabungkan beberapa dimensi:

  • Per IP atau source address
  • Per akun / identifier
  • Per device fingerprint yang andal, jika ada dan tidak melanggar privasi
  • Per subnet/ASN atau sinyal jaringan lain, bila infrastruktur mendukung
  • Per route, misalnya /login, /refresh, /password/reset

Lockout adaptif lebih baik daripada lockout kaku. Contoh pendekatan:

  • Kegagalan kecil: tambahkan delay beberapa detik
  • Pola mencurigakan: wajibkan CAPTCHA atau step-up MFA
  • Serangan jelas: blok sementara source dan tantang akun target
  • Jangan mengunci akun terlalu mudah sampai menjadi vektor denial-of-service terhadap pengguna sah

Trade-off penting: lockout keras per akun memang menghambat brute force, tetapi juga mudah disalahgunakan untuk mengganggu pengguna. Karena itu, banyak sistem modern memilih kombinasi delay progresif, challenge tambahan, dan korelasi sinyal risiko.

Rotasi secret dan manajemen key

Jika Anda menandatangani JWT atau mengenkripsi cookie/session data, secret management adalah bagian dari threat model, bukan urusan operasional terpisah.

Prinsip yang aman:

  • Jangan simpan secret di repo
  • Gunakan secret manager atau mekanisme distribusi rahasia yang terkontrol
  • Dukung beberapa key aktif selama masa rotasi
  • Pisahkan key berdasarkan lingkungan dan fungsi
  • Catat siapa yang mengakses atau mengubah secret

Untuk JWT, pola umum adalah menyertakan kid agar verifier tahu key mana yang dipakai. Saat rotasi, signer memakai key baru, sementara verifier masih menerima key lama selama masa transisi singkat. Untuk cookie/session yang dienkripsi atau ditandatangani, prinsipnya sama: server harus bisa membaca artefak lama selama jendela migrasi, lalu memaksa pembaruan bertahap.

Kesalahan umum:

  • Rotasi key tanpa kompatibilitas mundur, menyebabkan semua sesi putus mendadak
  • Satu secret dipakai untuk banyak fungsi berbeda
  • Secret tercetak ke log atau halaman error

Refresh token dan deteksi replay

Bila arsitektur Anda memakai refresh token, anggap artefak ini setara kunci rumah. Refresh token harus:

  • Disimpan aman, idealnya dalam cookie HttpOnly jika konteksnya browser
  • Memiliki rotasi saat digunakan
  • Memiliki identitas unik agar reuse bisa dideteksi
  • Dapat dicabut per device/session

Pola yang umum dipakai adalah refresh token rotation: setiap kali token dipakai, server mengeluarkan token baru dan menandai token lama tidak boleh dipakai lagi. Jika token lama muncul lagi, itu sinyal kuat adanya pencurian atau replay; respons aman biasanya mencabut seluruh keluarga token untuk sesi tersebut dan memaksa login ulang.

Upload avatar: relevan karena abuse sering terjadi setelah login

Setelah pengguna berhasil login, endpoint seperti POST /profile/avatar sering menjadi target berikutnya. Threat model login API yang baik sebaiknya memeriksa area ini karena penyerang yang berhasil memperoleh akses akan mencari primitive lain untuk persistence, penyimpanan file, atau serangan ke admin.

Kontrol minimum untuk avatar upload:

  • Whitelist tipe file yang benar-benar dibutuhkan
  • Periksa MIME dan magic bytes, bukan hanya ekstensi
  • Batasi ukuran file dan dimensi gambar
  • Simpan file di object storage atau direktori non-eksekusi
  • Jangan layani file upload dari domain yang punya akses cookie sensitif bila bisa dipisahkan
  • Rename file secara acak, jangan pakai nama dari pengguna
  • Scan file bila profil risiko mengharuskannya

Ini relevan untuk session hijack secara tidak langsung: XSS atau konten aktif yang lolos lewat upload dapat membantu mencuri sesi, khususnya bila file di-host pada origin yang sama.

Audit log dan deteksi anomali

Tanpa audit log yang tepat, Anda tidak bisa membedakan typo pengguna dari serangan distribusi. Log untuk autentikasi harus terstruktur, bukan string bebas yang sulit dianalisis.

Apa yang perlu dicatat

  • Login berhasil dan gagal
  • Alasan gagal dalam bentuk kode internal, bukan detail sensitif ke klien
  • Password reset diminta dan diselesaikan
  • MFA challenge dimulai, gagal, berhasil, atau dibypass oleh kebijakan tertentu
  • Refresh token digunakan, diputar, atau terdeteksi reuse
  • Logout, revoke session, perubahan password, perubahan email, perubahan device tepercaya

Field yang berguna:

  • Timestamp
  • User ID bila diketahui
  • Identifier yang dicoba, sebaiknya dalam bentuk yang diproteksi sesuai kebijakan privasi
  • IP yang sudah melalui verifikasi proxy yang benar
  • User-Agent ringkas
  • Request ID / correlation ID
  • Outcome dan reason code
  • Session ID atau token ID dalam bentuk non-rahasia

Contoh event log terstruktur

{
  "event": "auth.login.failed",
  "request_id": "8f2c...",
  "account": "[email protected]",
  "ip": "203.0.113.10",
  "user_agent": "Mozilla/5.0",
  "reason": "invalid_credentials",
  "risk_score": "medium",
  "timestamp": "2026-07-03T10:15:00Z"
}

Jangan masukkan password, access token, refresh token, cookie, atau header otorisasi ke log. Itu kesalahan yang masih sering terjadi dan bisa mengubah insiden kecil menjadi kebocoran besar.

Deteksi anomali yang realistis

Anda tidak butuh sistem canggih di awal. Beberapa aturan sederhana sudah sangat membantu:

  • Lonjakan gagal login per menit di endpoint tertentu
  • Satu IP mencoba banyak akun
  • Satu akun gagal dari banyak negara/ASN dalam waktu singkat
  • Refresh token reuse
  • Login sukses dari lokasi baru segera diikuti perubahan password atau email
  • Banyak avatar upload gagal/aneh setelah login dari akun yang baru dibuat

Mulailah dari aturan yang bisa dijelaskan dan dioperasikan. Model statistik atau ML tanpa data bersih sering menambah noise. Prinsip ini sejalan dengan tema artikel: kemajuan teknologi tidak menghapus kebutuhan akan kontrol dasar yang disiplin.

Contoh endpoint dan kontrol minimum

POST /api/login

  • HTTPS wajib
  • Body size limit
  • Validasi schema
  • Rate limit per IP + per akun
  • Pesan error generik
  • Audit log sukses/gagal
  • Rotasi session ID setelah sukses

POST /api/refresh

  • Refresh token disimpan aman
  • Rotasi setiap pemakaian
  • Deteksi reuse
  • Rate limit ketat
  • Audit event refresh dan revoke

POST /api/logout

  • Cabut sesi server-side atau tandai refresh token tidak valid
  • Hapus cookie dengan benar
  • Audit log logout

POST /api/profile/avatar

  • Auth wajib
  • Whitelist tipe file
  • Validasi ukuran dan konten file
  • Simpan di storage aman non-eksekusi
  • Rate limit untuk cegah abuse storage

Checklist implementasi threat modeling login API

  1. Gambar auth flow end-to-end termasuk login, refresh, logout, reset password, dan upload avatar bila ada
  2. Daftar aset sensitif: password hash, cookie, refresh token, signing key, audit log
  3. Tentukan trust boundary: browser, proxy, app, cache, DB, storage, log pipeline
  4. Petakan abuse case: stuffing, spraying, enumeration, hijack, replay, log poisoning, upload abuse
  5. Terapkan validasi input dan body size limit pada semua endpoint auth
  6. Gunakan password hashing yang kuat dan konsisten
  7. Pilih session cookie atau JWT berdasarkan kebutuhan revocation dan arsitektur, bukan preferensi tren
  8. Amankan cookie dengan HttpOnly, Secure, dan SameSite yang tepat
  9. Terapkan rate limit multi-dimensi dan lockout adaptif
  10. Rotasi session ID setelah login dan saat privilege berubah
  11. Jika memakai refresh token, aktifkan rotation dan deteksi reuse
  12. Kelola secret dengan secret manager dan rencana rotasi tanpa downtime
  13. Buat audit log terstruktur untuk semua event auth penting
  14. Tambahkan alert anomali yang sederhana tetapi operasional
  15. Uji dengan simulasi abuse: brute force, replay token, upload file salah tipe, dan revocation flow

Kesalahan yang paling sering terjadi

  • Menyimpan token di tempat yang mudah diakses JavaScript tanpa alasan kuat
  • Mengandalkan JWT stateless penuh tetapi tetap berharap revocation instan
  • Rate limit hanya per IP
  • Lockout terlalu agresif sehingga menjadi alat DoS terhadap akun sah
  • Mengirim pesan error yang membocorkan keberadaan akun
  • Tidak mencatat refresh token reuse
  • Memperlakukan upload avatar sebagai fitur kecil yang tidak perlu dimodelkan
  • Tidak menguji perilaku sistem saat secret dirotasi

Penutup

Threat modeling login API bukan latihan dokumentasi, melainkan cara sistematis untuk memutuskan kontrol mana yang benar-benar dibutuhkan agar abuse dan session hijack lebih sulit terjadi. Jika Anda hanya mengambil satu langkah setelah membaca artikel ini, mulailah dengan memetakan endpoint auth dan sesi, lalu cocokkan tiap ancaman utama dengan kontrol nyata: validasi input, cookie/token yang aman, rate limit multi-dimensi, lockout adaptif, rotasi secret, audit log, dan deteksi replay/anomali.

Teknologi akan terus berganti, termasuk gelombang AI dan otomatisasi baru. Namun backend yang aman tetap bergantung pada dasar yang sama: pahami apa yang dilindungi, dari siapa, lewat jalur mana, lalu hardening secara disiplin di tempat yang tepat.