Threat modeling sering kali diabaikan karena diasosiasikan dengan dokumentasi tebal ribuan halaman dan metodologi birokratis seperti STRIDE formal. Pendekatan ini tidak efisien untuk siklus rilis modern. Merujuk pada konsep informal threat modeling oleh praktisi keamanan seperti Soatok, evaluasi keamanan sistem autentikasi API dapat disederhanakan menjadi empat pertanyaan inti:

  1. Aset apa yang dilindungi? (Misalnya kredensial, token sesi, data PII pengguna).
  2. Siapa penyerang dan apa batas kapabilitasnya? (Dari penyerang oportunistik via script injection hingga operator jaringan perantara).
  3. Di mana trust boundary (batas kepercayaan) ditarik? (Pemisah tegas antara entitas yang dipercaya dan yang tidak terpercaya).
  4. Apa mitigasi teknisnya? (Kontrol arsitektur dan kriptografis untuk menutup celah).

Pemetaan Trust Boundary: Studi Kasus SPA, API Gateway, dan Microservices

Asumsikan arsitektur umum: Single Page Application (SPA) di browser berkomunikasi melalui internet publik ke API Gateway, yang kemudian meneruskan permintaan ke sejumlah backend microservice di jaringan privat.

Titik kritis threat modeling terletak pada pendefinisian Trust Boundary secara akurat:

  • Boundary 1 (Client Storage vs. Browser Execution Context): Browser pengguna adalah lingkungan yang sepenuhnya berada di luar kendali server (untrusted). Runtime JavaScript tempat SPA berjalan dapat disusupi melalui celah Cross-Site Scripting (XSS) pihak ketiga (misal: dependency supply chain attack).
  • Boundary 2 (Public Internet vs. API Gateway): Jalur data antara klien dan API Gateway rentan terhadap inspeksi, modifikasi, dan man-in-the-middle (MitM) jika konfigurasi TLS tidak ketat. Gateway berfungsi sebagai gerbang verifikasi identitas pertama.
  • Boundary 3 (API Gateway vs. Internal Microservices): Kesalahan umum arsitektur adalah mengasumsikan jaringan privat sepenuhnya aman (zero-trust fallacy). Microservice internal yang satu tidak boleh langsung memercayai klaim identitas mentah tanpa validasi kriptografis terdesentralisasi.

Analisis Vektor Risiko Utama

1. Token Theft (Pencurian Token)

Menyimpan JWT atau access token di localStorage atau sessionStorage mengekspos token ke skrip apa pun yang dieksekusi di origin yang sama. Ketika terjadi celah XSS, penyerang dapat membaca token langsung via window.localStorage.getItem('token') dan mengirimkannya ke server milik penyerang.

2. Replay Attack (Serangan Pemutaran Ulang)

Jika access token yang dicuri tidak diikat ke saluran aman tertentu dan berumur panjang (misal: valid 24 jam tanpa mekanisme pencabutan), penyerang dapat mengirimkan token tersebut berulang kali untuk mengakses resource korban tanpa perlu mengetahui password korban.

3. Insider Threat & Lateral Movement (Pergerakan Lateral)

Jika API Gateway memvalidasi token lalu hanya meneruskan header internal tidak terotentikasi seperti X-User-Id: 12345 ke downstream microservices, kerentanan Server-Side Request Forgery (SSRF) pada satu service internal memungkinkan penyerang memalsukan identitas siapa pun ke service lainnya tanpa validasi token.

Mitigasi Teknis Konkret

1. Eliminasi Token Theft: HttpOnly & SameSite Cookies

Hindari menyimpan access token di client storage yang dapat diakses JavaScript. Gunakan cookie terenkripsi dengan atribut protektif tinggi:

Set-Cookie: __Host-access_token=eyJhbGciOi...; Path=/; Secure; HttpOnly; SameSite=Strict

Prefix __Host- memastikan cookie hanya dikirim ke host yang menyetelnya (bukan subdomain) dan harus menggunakan HTTPS. Flag HttpOnly memblokir akses dari document.cookie, menihilkan ekstraksi token via XSS.

2. Asymmetric Key Signing (EdDSA / RS256)

Jangan gunakan algoritma simetris (HS256) jika token diverifikasi oleh banyak microservice. Berbagi shared secret ke setiap service menciptakan risiko tinggi: kebocoran satu service memungkinkan service tersebut memalsukan token untuk seluruh sistem.

Gunakan kriptografi asimetris (misal: RS256 atau Ed25519). Auth Service memegang Private Key untuk menandatangani token, sedangkan API Gateway dan internal microservice hanya memegang Public Key (bisa didistribusikan via endpoint internal JWKS) untuk memverifikasi keaslian klaim.

3. Refresh Token Rotation dengan Deteksi Pemakaian Ulang (Reuse Detection)

Gunakan pola token family untuk mendeteksi pencurian refresh token. Setiap kali refresh token digunakan, server menerbitkan pasangan access token dan refresh token baru, lalu membatalkan refresh token sebelumnya.

// Pseudocode Logika Validasi Refresh Token
async function handleRefreshToken(presentedTokenString) {
  const tokenRecord = await db.tokens.find({ token: presentedTokenString });

  if (!tokenRecord) {
    // Token tidak dikenal
    throw new SecurityError('Invalid token');
  }

  // Deteksi pemakaian ulang: token sudah pernah dipakai sebelumnya
  if (tokenRecord.isUsed) {
    // Bahaya: Kemungkinan token dicuri dan dipakai oleh dua pihak berbeda
    // Batalkan SELURUH token family untuk sesi ini (force logout)
    await db.tokens.revokeFamily(tokenRecord.familyId);
    throw new SecurityError('Token reuse detected. All sessions revoked.');
  }

  // Tandai token saat ini sebagai sudah digunakan
  await db.tokens.markAsUsed(tokenRecord.id);

  // Buat refresh token baru dalam family yang sama
  const newRefreshToken = generateSecureEntropyToken();
  await db.tokens.create({
    token: newRefreshToken,
    familyId: tokenRecord.familyId,
    userId: tokenRecord.userId,
    isUsed: false,
    expiresAt: Date.now() + 7 * 24 * 60 * 60 * 1000
  });

  return {
    accessToken: signAccessToken(tokenRecord.userId),
    refreshToken: newRefreshToken
  };
}

4. Edge Rate Limiting & Sliding Window Throttling

Terapkan rate limiting ketat pada endpoint autentikasi di layer reverse proxy atau API Gateway untuk meredam serangan credential stuffing dan brute-force token refresh. Pisahkan limit berdasarkan IP dan identifier akun (misalnya username/email):

  • Endpoint /api/v1/auth/login: Maksimal 5 percobaan gagal per 15 menit per kombinasi IP + Akun.
  • Endpoint /api/v1/auth/refresh: Maksimal 20 request per menit per IP.

Checklist Verifikasi Threat Model untuk Pull Request

Gunakan checklist berikut sebelum menyetujui (merge) pull request yang memodifikasi jalur autentikasi:

  • [ ] Storage: Apakah access/refresh token bebas dari akses JavaScript langsung (menggunakan HttpOnly; Secure; SameSite=Lax/Strict)?
  • [ ] TTL (Time-To-Live): Apakah access token berumur pendek (misal: 5 hingga 15 menit)?
  • [ ] Algoritma Kriptografi: Apakah verifikasi token menolak algoritma none dan secara eksplisit menggunakan signature asimetris yang aman?
  • [ ] Family Invalidation: Apakah reuse detection aktif pada refresh token endpoint dan membatalkan seluruh rantai token saat pelanggaran terdeteksi?
  • [ ] Boundary Downstream: Apakah internal service tetap memverifikasi cryptographic payload token atau mTLS, dan tidak hanya mengandalkan plain header injection dari gateway?
  • [ ] Error Handling: Apakah response kegagalan auth seragam (tidak membocorkan status apakah email terdaftar atau tidak via timing attack / pesan error spesifik)?
  • [ ] Rate Limiting: Apakah endpoint auth baru terlindungi oleh proteksi throttling di ingress gateway?