Pisahkan JWT antara payload dan tanda tangan

Aug 19 2020

Konteks: Saya sedang mencari solusi penyimpanan untuk token JWT pada aplikasi satu halaman.

  1. Menyimpan JWT di penyimpanan lokal tidak aman dan rentan terhadap serangan XSS.
  2. Menyimpan JWT dalam cookie yang aman / khusus HTTP lebih aman, tetapi rentan terhadap serangan CSRF.

Saya mempelajari skenario berikut:

Setelah autentikasi, token penyegaran disimpan dalam kuki aman khusus http. Ini hanya dapat digunakan untuk mendapatkan token akses.

Setelah otorisasi, backend merespons dengan token akses JWT. Bagian header dan payload JWT ada di dalam isi respons. Tanda tangan token tidak dikirim dan disetel dalam kuki aman hanya http (situs yang sama ketat jika memungkinkan, tetapi anggap saja tidak demikian). Header + payload disimpan dalam memori.

JWT berisi klaim berikut

  • iat, nbf, exp (IMO yang dapat ditebak)
  • klaim relatif terhadap identitas pengguna dan izin (dapat ditebak jika identitas pengguna diketahui)
  • jti, berisi nomor acak yang aman secara kriptografis (dalam kasus saya dibuat dengan rahasia python )

Saat membuat permintaan, header + payload dikirim melalui XHR / fetch oleh SPA di header Otorisasi. Tanda tangan dikirim bersama dengan cookie. Backend menggabungkan keduanya dan memverifikasi tanda tangan.

  1. Apakah mekanisme ini aman dari serangan CSRF? Apakah klaim jti menjadikan token Otorisasi + cookie tanda tangan sebagai teknik mitigasi CSRF yang valid?
  2. Apakah mekanisme ini memang lebih aman terhadap serangan XSS daripada menyimpan JWT di dalam penyimpanan lokal? (Mungkinkah serangan menggunakan XSS juga dengan mudah mencuri tanda tangan, seperti dengan eksploitasi TRACE ).

Catatan: Saya telah membaca pertanyaan ini yang serupa, tetapi terlalu luas, jadi saya memposting ini untuk mendapatkan jawaban yang lebih tepat.

Jawaban

1 Amey Aug 19 2020 at 12:45

Apakah mekanisme ini aman dari serangan CSRF?

Metode pemisahan JWT dan penyimpanan tanda tangan di cookie dan token lainnya di Penyimpanan Browser tidak memberikan perlindungan tambahan apa pun terhadap serangan CSRF dibandingkan jika seluruh JWT disimpan di Penyimpanan Lokal atau Sesi. Ya, ini akan mengurangi serangan CSRF, tetapi Anda tidak perlu menambahkan overhead yang tidak perlu untuk memisahkan dan menggabungkan JWT di server. Menyimpan JWT di Penyimpanan Lokal dan menerimanya hanya di header Otorisasi sudah cukup untuk melindungi aplikasi Anda dari serangan CSRF.

Apakah mekanisme ini memang lebih aman terhadap serangan XSS daripada menyimpan JWT di dalam penyimpanan lokal? (Mungkinkah serangan menggunakan XSS juga dengan mudah mencuri tanda tangan, seperti dengan eksploitasi TRACE)

Jika fokus Anda hanya pada penyerang yang dapat mencuri JWT, pendekatan ini aman kecuali, seperti yang Anda sebutkan dengan benar, TRACE diaktifkan di server.

Namun, ini tidak membuat aplikasi Anda lebih aman dari serangan XSS. Misalnya, jika saya dapat mengeksekusi Javascript sewenang-wenang pada aplikasi Anda, saya dapat mengambil header JWT + payload dari Penyimpanan Lokal dan hanya mengirim XHR ke titik akhir sensitif dengan menjaga Kredensial disetel ke True. Titik akhir ini mungkin dirancang untuk mengubah alamat email akun, misalnya. Itu langsung mengarah pada pengambilalihan akun. Tidak perlu mencuri cookie atau JWT.

Kesimpulan: Pendekatan ini memberikan beberapa perlindungan terhadap token sesi dengan memisahkan tanda tangan dari token lainnya. Namun, dalam hal XSS, mencuri token sesi bukanlah satu-satunya risiko yang harus Anda perhatikan.