Apa yang dibuktikan oleh JWT yang diterjemahkan
Decoder JWT menunjukkan kepada Anda apa yang diklaim oleh token. Ia tidak dapat menunjukkan kepada Anda apakah klaim tersebut benar. Panduan ini mencakup apa saja ketiga segmen tersebut, apa yang dilakukan dan tidak dilakukan decoding, dan serangan yang ada di celah di antara keduanya.
Tiga segmen, dua di antaranya hanya JSON
JWT dalam bentuk umumnya adalah JWS: tiga segmen url base64 yang dipisahkan oleh titik. Yang pertama adalah header, yang kedua adalah payload, dan yang ketiga adalah tanda tangan.
Header dan payload adalah objek JSON biasa yang telah dikodekan base64url. Dikodekan, tidak dienkripsi. Siapa pun yang memegang token dapat membaca keduanya, secara instan, tanpa kunci — itu bukan cacat, melainkan desainnya. JWT adalah pernyataan yang ditandatangani, bukan amplop tertutup. Tanda tangan menjamin bahwa pernyataan itu tidak diubah; itu tidak melakukan apa pun untuk merahasiakannya.
Konsekuensinya patut dinyatakan dengan jelas karena sering kali terlewatkan: jangan pernah memasukkan sesuatu yang bersifat rahasia ke dalam payload JWT. Bukan kata sandi, bukan pengenal nasional lengkap, bukan rincian sistem internal. Asumsikan payloadnya bersifat publik, karena bagi siapa pun yang memiliki token, payload tersebut bersifat publik.
Segmen ketiga adalah tanda tangan, dihitung dari dua segmen pertama. Ini adalah satu-satunya bagian yang membawa nilai keamanan apa pun, dan merupakan bagian yang tidak dapat dievaluasi oleh decoder.
Apa yang dibuktikan oleh penguraian kode: tidak ada
Inilah inti dari keseluruhan panduan ini. Mendekode JWT mem-parsing dua string base64url menjadi JSON. Ini mengonfirmasi bahwa token tersebut terbentuk dengan baik. Hal ini tidak mengkonfirmasi bahwa token tersebut asli, bahwa token tersebut dikeluarkan oleh pihak yang disebutkan dalam klaim "iss", bahwa klaim tersebut belum diedit, atau bahwa token tersebut valid.
Siapa pun dapat membuat token. Ambil JWT apa saja, ubah "role": "user" menjadi "role": "admin", enkode ulang payload, tempelkan tanda tangan apa pun di bagian akhir, dan decoder akan menampilkan klaim Anda yang telah diedit persis seperti yang ditampilkan aslinya. Tidak ada cara untuk mengetahui perbedaannya, karena memeriksa perbedaannya adalah operasi berbeda yang memerlukan kunci yang tidak dimiliki dekoder.
Jadi ketika dekoder — yang ini, atau yang lainnya — menunjukkan kepada Anda "exp: 2026-01-01", yang sebenarnya disampaikan kepada Anda adalah: token ini berisi klaim bahwa masa berlakunya habis pada tanggal tersebut. Apakah klaim itu ada artinya tergantung sepenuhnya pada validitas tanda tangan yang belum diperiksa.
Alat ini hanya menerjemahkan kode, dan menyatakannya di halaman, di samping hasil, setiap saat. Tidak dalam catatan kaki. Alasannya adalah karena dekoder yang tidak membahas hal ini melatih penggunanya untuk membaca data yang belum terverifikasi seolah-olah data tersebut telah diverifikasi, dan kebiasaan tersebut adalah akar dari seluruh jaringan bug autentikasi.
Mengapa alat ini tidak menawarkan verifikasi
Verifikasi memerlukan tiga hal yang tidak dapat dimiliki secara bertanggung jawab oleh halaman web: kunci penerbit, algoritme yang dipasang sebelumnya, dan kebijakan tentang apa yang harus ditolak.
Kuncinya adalah masalah yang jelas. Untuk algoritma HMAC (HS256 dan teman-teman) kuncinya adalah rahasia bersama — rahasia yang sama yang digunakan untuk membuat token. Menempelkannya ke halaman web berarti menempelkan kredensial yang dapat mencetak token yang valid ke dalam halaman web. Untuk RSA dan ECDSA kunci publik bukanlah rahasia, namun Anda tetap perlu mengambil kunci yang tepat dari titik akhir JWKS yang tepat dan kepercayaan yang Anda miliki.
Algoritme adalah masalah yang paling halus, dan sumber dari dua serangan yang terkenal. Yang pertama adalah alg: "none": header mengklaim token tidak ditandatangani, dan pemverifikasi yang menghormati header daripada konfigurasinya sendiri menerima apa pun. Yang kedua adalah kebingungan RS256-to-HS256: penyerang mengambil kunci publik — yang, menurut definisi, publik — mengubah header menjadi HS256, dan menandatangani token menggunakan kunci publik tersebut sebagai rahasia HMAC. Pemverifikasi yang membaca algoritme dari token dan mencari "kunci" akan memvalidasinya.
Kedua serangan tersebut berasal dari kesalahan yang sama: membiarkan token memberi tahu pemverifikasi cara memeriksa token. Pemverifikasi yang benar mengabaikan algoritma header dan menggunakan algoritma yang telah dikonfigurasi. Itu adalah keputusan milik sistem yang memercayai token — bukan pada alat praktis, dan bukan pada siapa pun yang menempelkan sesuatu ke dalam formulir.
Mengapa tidak menempelkan token produksi di mana pun
Token akses adalah kredensial pembawa. Itulah arti "pembawa" pada header Otorisasi: siapa pun yang menyandangnya, adalah Anda. Tidak ada faktor kedua dan biasanya tidak ada cara untuk membedakan token yang dicuri dari token yang sah. Sampai habis masa berlakunya, ini adalah kunci yang berfungsi untuk akun Anda.
Jadi menempelkan token langsung ke halaman web mana pun berarti memberikan kredensial ke halaman itu. Yang ini menerjemahkan semuanya secara lokal dan tidak membuat permintaan jaringan setelah halaman dimuat — Anda dapat mengonfirmasinya di panel jaringan browser Anda, dan Anda harus melakukannya, karena ini memerlukan waktu sepuluh detik. Namun perhatikan apa argumen sebenarnya: klaim, pada sebuah situs web, bahwa situs tersebut dapat dipercaya. Setiap situs yang mengekstraksi token membuat klaim yang persis sama, dan pengunjung tidak dapat membedakannya secara sekilas.
Kebiasaan aman tidak bergantung pada menilai situs dengan benar. Gunakan token yang kedaluwarsa, token lingkungan pengujian, atau token yang telah Anda buat untuk tujuan tersebut. Jika Anda telah menempelkan token produksi di suatu tempat — di mana pun — putar token tersebut. Pencabutan itu murah; sebuah insiden tidak.
Hal yang sama berlaku dengan kekuatan yang lebih besar pada penandatanganan kunci. Tidak ada alasan yang sah untuk mengetikkan rahasia HMAC atau kunci pribadi ke dalam halaman web, dan situs mana pun yang meminta seseorang untuk "memverifikasi" token Anda meminta kemampuan untuk memalsukan token. Itulah alasan konkret alat ini tidak memiliki fitur verifikasi: fitur tersebut memerlukan permintaan.
Membaca klaim yang penting
RFC 7519 mendaftarkan sejumlah kecil nama klaim. "iss" adalah penerbitnya, "sub" subjek yang dimaksud dengan token, "aud" audiens yang dituju, "exp" masa berlakunya, "nbf" waktu valid paling awal, "iat" waktu penerbitannya, dan "jti" adalah id unik untuk deteksi pemutaran ulang. Segala sesuatu yang lain bersifat khusus untuk aplikasi.
Klaim waktu adalah nilai NumericDate: detik sejak zaman Unix, bukan milidetik. Hal ini membuat orang terus-menerus tersandung, karena sebagian besar nilai waktu JavaScript adalah milidetik. Token yang tampaknya kedaluwarsa pada 1970 biasanya diberi nilai milidetik; yang tampaknya kedaluwarsa pada tahun 55000 biasanya memiliki nilai kedua dikalikan dengan 1000 di suatu tempat.
"aud" perlu mendapat perhatian khusus saat Anda melakukan debug. Token yang benar-benar valid masih bisa menjadi token yang salah karena dikeluarkan untuk audiens yang berbeda. Pemverifikasi yang memeriksa tanda tangan tetapi bukan audiens akan menerima token yang dibuat untuk layanan lain secara keseluruhan — yang merupakan jalur eskalasi hak istimewa yang nyata dalam sistem yang berbagi penyedia identitas.
Alat ini merender klaim waktu di UTC, menandai token yang kedaluwarsa sebagai kedaluwarsa, dan memasangkannya dengan pengingat bahwa klaim kedaluwarsa hanya berarti jika tanda tangannya valid. Pengingatnya ada karena "dikatakan belum kedaluwarsa" adalah saat yang tepat ketika kebiasaan data yang tidak terverifikasi menimbulkan kerusakan.
Daftar periksa singkat untuk sistem yang melakukan kepercayaan
Jika Anda menulis kode yang menerima token dan bukan hanya memeriksanya, berikut ini adalah versi singkat dari apa yang dilakukan oleh pemverifikasi yang benar.
- Verifikasi tanda tangan terlebih dahulu, dengan kunci yang Anda peroleh di luar batas, sebelum membaca klaim apa pun.
- Sematkan algoritme dalam konfigurasi Anda sendiri. Jangan pernah membacanya dari header token. Tolak "tidak ada" tanpa syarat.
- Periksa "exp" dan "nbf" terhadap jam tepercaya, dengan toleransi kemiringan paling kecil.
- Centang "iss" dan "aud" terhadap nilai yang Anda harapkan. Tanda tangan yang valid pada token yang ditujukan untuk orang lain tetap merupakan token yang salah.
- Gunakan perpustakaan yang terverifikasi untuk platform Anda daripada merakitnya sendiri. Setiap item dalam daftar ini ada di dalamnya karena penerapannya salah.
- Pertahankan masa pakai token yang singkat, dan miliki jalur pencabutan. Token berumur pendek membatasi kerusakan kebocoran yang belum Anda sadari.
Apa yang terjadi pada apa yang Anda tempel
- Setiap konversi, hash, decode dan diff berjalan di tab browser Anda. Tidak ada masukan yang diunggah, dicatat atau disimpan di server, karena tidak ada server yang terlibat setelah halaman dimuat.
- Hash berasal dari implementasi Web Crypto milik browser, dan UUID dari generator acak yang aman secara kriptografis. Tidak ada yang melibatkan panggilan jaringan.
- Tidak ada yang Anda ketikkan yang ditulis ke penyimpanan lokal atau cookie. Memuat ulang halaman akan membuangnya; menutup tab akan membuangnya.
- Analisis seluruh situs hanya berjalan pada host produksi kanonik yang dikonfigurasi dan diungkapkan dalam Kebijakan Privasi; host lokal dan pratinjau menolaknya. Nilai, token, URL, dan konten file yang ditempelkan dikecualikan dari peristiwa analisis ToolAcre sendiri. Periklanan dinonaktifkan dalam konfigurasi saat ini.
- Artinya: kunci JWT atau API adalah kredensial aktif. Kebiasaan yang aman adalah jangan pernah menempelkannya ke halaman web yang tidak Anda tulis, betapapun dapat dipercayanya klaim tersebut — termasuk yang ini.
Pertanyaan
Apakah alat ini memverifikasi tanda tangan?
Tidak, dan itu tidak akan pernah terjadi. Ini menerjemahkan header dan payload dan menunjukkan kepada Anda apa isinya. Itu tidak memeriksa tanda tangannya, jadi tidak ada yang ditampilkan yang membuktikan bahwa token itu asli, tidak diubah, atau dikeluarkan oleh siapa pun yang namanya.
Lalu bagaimana saya tahu suatu token itu asli?
Dengan memverifikasi tanda tangan dengan kunci penerbit, menggunakan perpustakaan yang terverifikasi, dengan algoritme yang disematkan dalam konfigurasi Anda sendiri, bukan membaca dari token. Hal ini berfungsi untuk layanan yang memercayai token, dalam lingkungan yang secara sah memegang kunci.
Apakah token saya dikirim ke mana saja ketika saya memecahkan kodenya di sini?
Tidak. Penguraian kode terjadi di tab browser Anda menggunakan JavaScript milik laman itu sendiri, dan laman tersebut tidak membuat permintaan jaringan setelah dimuat. Anda dapat memverifikasi ini di panel jaringan browser Anda. Anda tetap tidak boleh menempelkan token produksi ke alat web sebagai kebiasaan, karena kebiasaan itu harus diterapkan pada situs yang tidak jujur.
Mengapa ada orang yang bisa membaca payload JWT saya?
Karena payloadnya dikodekan base64url, bukan dienkripsi. JWS adalah pernyataan yang ditandatangani, bukan pernyataan yang disegel. Jika Anda ingin kontennya tidak dapat dibaca, Anda memerlukan JWE, format token terenkripsi — dan kemudian dekoder tidak dapat menampilkan apa pun tanpa kuncinya.
Apa itu alg: "tidak ada"?
Nilai header yang menyatakan bahwa token tidak ditandatangani. Ini ada dalam spesifikasi untuk konteks di mana integritas dijamin dengan cara lain, dan ini adalah jebakan yang tetap: pemverifikasi yang mempercayai algoritma header akan menerima token apa pun yang mengklaim "tidak ada". Alat ini menandainya setiap kali muncul.
Token saya memiliki lima segmen dan tidak dapat didekodekan. Mengapa?
Lima segmen berarti JWE — token terenkripsi — dan bukan JWS yang ditandatangani. Isinya tidak dapat dibaca tanpa kunci dekripsi, jadi tidak ada apa pun yang dapat ditampilkan oleh dekoder. Alat ini mengidentifikasi kasus tersebut secara eksplisit alih-alih melaporkan kegagalan penguraian yang tidak jelas.
Kedaluwarsa terlihat salah dengan faktor 1000.
JWT klaim waktu adalah Tanggal Numerik: detik sejak zaman, bukan milidetik. Nilai yang dihasilkan oleh Date.now() seribu kali terlalu besar. Utilitas stempel waktu dalam toolkit ini mengkonversi keduanya dan selalu memberi tahu Anda unit mana yang digunakan.
Apakah aman menyimpan JWT di Penyimpanan lokal?
Ini adalah trade-off, bukan ya atau tidak. localStorage dapat dibaca oleh JavaScript mana pun yang berjalan di tempat asal Anda, sehingga satu kerentanan XSS mengekstrak token tersebut. Cookie httpOnly tidak dapat dibaca oleh JavaScript tetapi memerlukan perlindungan CSRF. Kesimpulan jujurnya adalah bahwa keduanya tidak gratis, dan keputusan ada di tangan model ancaman aplikasi Anda.
Keterbatasan
- Alat ini hanya menerjemahkan kode. Itu tidak memverifikasi tanda tangan, dan itu adalah keputusan desain permanen dan bukan fitur yang hilang — lihat panduan di atas untuk mengetahui alasannya.
- Token terenkripsi (JWE, lima segmen) tidak dapat didekodekan sama sekali tanpa kuncinya. Alat ini mengidentifikasi mereka dan berhenti.
- JWT yang disarangkan — token yang payloadnya sendiri merupakan token — tidak dibuka secara otomatis. Dekode token bagian dalam sebagai langkah terpisah.
- Arti klaim di luar kumpulan terdaftar yang ditentukan dalam RFC 7519 bersifat khusus aplikasi, sehingga alat menampilkan nilainya tanpa menafsirkannya.
- Kedaluwarsa yang ditampilkan di sini hanya mencerminkan klaim token tentang dirinya sendiri. Apakah klaim tersebut bermakna atau tidak bergantung pada tanda tangan yang tidak diperiksa oleh alat ini.
- Token yang lebih besar dari 200,000 karakter ditolak. JWT asli mana pun berukuran lipat lebih kecil.