alltools.one
Security
2025-06-12
8 min
alltools.one Team
JWTSecurityAuthenticationAPIWeb Security

Keamanan JSON Web Token: Kerentanan Umum dan Perbaikannya

JWT adalah standar de facto untuk autentikasi API, tetapi kesederhanaannya yang tampak menyembunyikan jebakan keamanan yang nyata. JWT yang salah dikonfigurasi telah menyebabkan bypass autentikasi, eskalasi hak istimewa, dan kebocoran data. Panduan ini membahas kerentanan paling kritis dan cara mencegahnya.

Ringkasan Struktur JWT

JWT terdiri dari tiga bagian yang dienkode Base64URL yang dipisahkan oleh titik:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ.signature
  • Header: Algoritma dan tipe token
  • Payload: Klaim (data pengguna, kedaluwarsa, dll.)
  • Signature: Verifikasi kriptografis

Periksa struktur JWT dengan JWT Encoder/Decoder kami.

Untuk pemahaman dasar tentang struktur JWT, lihat panduan JWT Tokens Explained kami.

Kerentanan Kritis

1. Serangan Kebingungan Algoritma

Kerentanan JWT paling berbahaya. Jika server menerima header alg dari token tanpa validasi, penyerang dapat:

Serangan: Mengubah algoritma dari RS256 (asimetris) ke HS256 (simetris) dan menandatangani token palsu dengan kunci publik server:

// Attacker's forged token
header: { "alg": "HS256", "typ": "JWT" }
payload: { "sub": "admin", "role": "superadmin" }
// Signed with the server's PUBLIC key as the HMAC secret

Jika server memverifikasi token HS256 menggunakan kunci publik sebagai rahasia, token palsu lolos verifikasi.

Perbaikan: Selalu tentukan algoritma yang diharapkan secara eksplisit:

// WRONG - accepts whatever algorithm the token specifies
jwt.verify(token, key);

// CORRECT - enforce specific algorithm
jwt.verify(token, key, { algorithms: ['RS256'] });

2. Serangan Algoritma None

Beberapa library menerima "alg": "none" — token tanpa tanda tangan:

// Forged token with no signature
header: { "alg": "none", "typ": "JWT" }
payload: { "sub": "admin", "role": "superadmin" }
signature: ""  // empty

Perbaikan: Jangan pernah mengizinkan algoritma none di produksi. Tentukan secara eksplisit daftar algoritma yang diizinkan.

3. Rahasia Penandatanganan yang Lemah

JWT berbasis HMAC (HS256/HS384/HS512) hanya sekuat rahasianya:

// TERRIBLE - can be brute-forced in seconds
secret = "password123"

// WEAK - dictionary attack vulnerable
secret = "my-jwt-secret"

// STRONG - 256+ bits of randomness
secret = "a3f2b8c9d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0"

Perbaikan: Gunakan minimal 256 bit keacakan kriptografis untuk rahasia HMAC. Lebih baik lagi, gunakan kunci asimetris (RS256, ES256) di mana kunci penandatanganan tidak perlu dibagikan.

4. Kedaluwarsa yang Hilang

Token tanpa kedaluwarsa tidak pernah kedaluwarsa — token yang dicuri memberikan akses permanen:

// WRONG - no expiration
{ "sub": "user123", "role": "admin" }

// CORRECT - short expiration
{
  "sub": "user123",
  "role": "admin",
  "exp": 1705312800,
  "iat": 1705309200,
  "nbf": 1705309200
}

Praktik terbaik: Token akses kedaluwarsa dalam 15-60 menit. Gunakan refresh token (disimpan dengan aman) untuk sesi yang panjang.

5. Data Sensitif di Payload

Payload JWT dienkode Base64URL, bukan dienkripsi. Siapa pun dapat mendekodenya:

echo "eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ" | base64 -d
# {"sub":"123","role":"admin"}

Jangan pernah menyertakan: Kata sandi, kunci API, nomor kartu kredit, data pribadi (SSN, catatan medis), atau rahasia apa pun di payload JWT.

6. Penyimpanan Token (XSS vs CSRF)

PenyimpananRentan XSSRentan CSRF
localStorageYaTidak
Cookie (tanpa flag)YaYa
Cookie HttpOnlyTidakYa
Cookie HttpOnly + SameSiteTidakTidak

Direkomendasikan: Simpan JWT di cookie HttpOnly, Secure, SameSite=Strict. Ini mencegah akses JavaScript (pertahanan XSS) dan permintaan lintas situs (pertahanan CSRF).

Set-Cookie: token=eyJ...; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=3600

Daftar Periksa Keamanan

  1. Tentukan algoritma secara eksplisit — jangan pernah menerima dari header token
  2. Tolak algoritma none — selalu wajibkan tanda tangan
  3. Gunakan rahasia yang kuat — 256+ bit untuk HMAC, 2048+ bit untuk RSA
  4. Atur kedaluwarsa singkat — 15-60 menit untuk token akses
  5. Validasi semua klaimexp, iss, aud, nbf
  6. Simpan di cookie HttpOnly — bukan localStorage
  7. Rotasi rahasia secara berkala — rencanakan rotasi kunci
  8. Jangan pernah menyimpan data sensitif di payload
  9. Gunakan kunci asimetris untuk sistem terdistribusi (RS256 atau ES256)
  10. Implementasikan pencabutan token — daftar hitam atau kedaluwarsa singkat + refresh token

Penandatanganan Asimetris vs Simetris

AspekHS256 (Simetris)RS256 (Asimetris)
KunciRahasia bersamaPasangan kunci privat/publik
Siapa yang bisa menandatanganiSiapa pun yang memiliki rahasiaHanya pemegang kunci privat
Siapa yang bisa memverifikasiSiapa pun yang memiliki rahasiaSiapa pun yang memiliki kunci publik
Distribusi kunciRahasia harus dibagikan dengan amanHanya kunci publik yang dibagikan
PerformaLebih cepatLebih lambat
Terbaik untukLayanan tunggalMicroservices, sistem terdistribusi

Rekomendasi: Gunakan ES256 (ECDSA) untuk aplikasi baru — memberikan keamanan asimetris dengan performa mendekati HMAC.

Strategi Pencabutan Token

JWT bersifat stateless secara desain — tidak ada cara bawaan untuk mencabutnya. Strateginya:

  1. Kedaluwarsa singkat: Jika token kedaluwarsa dalam 15 menit, jendela token yang dicuri terbatas
  2. Rotasi refresh token: Terbitkan refresh token baru setiap kali digunakan; jika refresh token digunakan dua kali, cabut semua token
  3. Daftar hitam: Simpan ID token yang dicabut (klaim jti) dan periksa pada setiap permintaan
  4. Versi token: Sertakan nomor versi dalam klaim; tingkatkan versi pengguna saat logout

FAQ

Haruskah saya menggunakan JWT atau cookie sesi untuk autentikasi?

Cookie sesi lebih sederhana dan lebih aman untuk aplikasi web tradisional — server mengontrol siklus hidup sesi, dan pencabutan bersifat instan. JWT lebih cocok untuk API stateless, microservices, dan aplikasi mobile di mana penyimpanan sesi sisi server tidak praktis. Jika Anda memilih JWT, terapkan langkah-langkah keamanan dalam panduan ini.

Berapa waktu kedaluwarsa JWT yang ideal?

Untuk token akses: 15-60 menit. Lebih singkat lebih aman tetapi memerlukan refresh lebih sering. Untuk refresh token: 1-30 hari, disimpan di cookie HttpOnly. Untuk token sekali pakai (verifikasi email, reset kata sandi): 1-24 jam.

Sumber Terkait

Published on 2025-06-12
JSON Web Token Security: Common Vulnerabilities and Fixes | alltools.one