Di mana menyimpan JWT di browser? Bagaimana cara melindungi dari CSRF?

159

Saya tahu otentikasi berbasis cookie. Bendera SSL dan HttpOnly dapat diterapkan untuk melindungi otentikasi berbasis cookie dari MITM dan XSS. Namun, tindakan yang lebih khusus akan diperlukan untuk diterapkan untuk melindunginya dari CSRF. Mereka sedikit rumit. ( referensi )

Baru-baru ini, saya menemukan bahwa JSON Web Token (JWT) cukup panas sebagai solusi untuk otentikasi. Saya tahu hal-hal tentang penyandian, pengodean dan verifikasi JWT. Namun, saya tidak mengerti mengapa beberapa situs web / tutorial mengatakan tidak perlu perlindungan CSRF jika JWT digunakan. Saya telah membaca cukup banyak dan mencoba merangkum masalah di bawah ini. Saya hanya ingin seseorang dapat memberikan gambaran besar tentang JWT dan mengklarifikasi konsep yang saya salah pahami tentang JWT.

  1. Jika JWT disimpan dalam cookie, saya pikir itu sama dengan otentikasi berbasis cookie kecuali bahwa server tidak perlu memiliki sesi untuk memverifikasi cookie / token. Masih ada risiko tentang CSRF jika tidak ada tindakan khusus yang diterapkan. Bukankah JWT disimpan dalam cookie?

  2. Jika JWT disimpan dalam penyimpanan / sessionStorage lokal, maka tidak ada cookie jadi tidak perlu melindungi terhadap CRSF. Pertanyaannya adalah bagaimana mengirim JWT ke server. Saya menemukan di sini menyarankan menggunakan jQuery untuk mengirim JWT dengan HTTP header permintaan ajax. Jadi, hanya permintaan ajax yang dapat melakukan otentikasi?

  3. Juga, saya menemukan satu lagi acara blog untuk menggunakan "header Otorisasi" dan "Pembawa" untuk mengirim JWT. Saya tidak mengerti metode yang dibicarakan blog. Bisakah seseorang tolong jelaskan lebih lanjut tentang "header Otorisasi" dan "Pembawa"? Apakah ini membuat JWT dikirim oleh header HTTP dari SEMUA permintaan? Jika ya, bagaimana dengan CSRF?

Timespace7
sumber

Jawaban:

70

Token JWT populer karena mereka digunakan sebagai format token default dalam protokol otorisasi dan otentikasi baru seperti OAuth 2.0 dan OpenID Connect .

Ketika token disimpan dalam cookie, browser akan secara otomatis mengirimkannya bersama dengan setiap permintaan ke domain yang sama dan ini masih rentan terhadap serangan CSRF.

Otentikasi pembawa adalah salah satu skema otentikasi yang didefinisikan dalam HTTP. Ini pada dasarnya berarti bahwa YOUmenempelkan token (JWT) di header HTTP Otorisasi permintaan. Browser akan NOTmelakukan ini untuk Anda secara otomatis, sehingga tidak cocok untuk melindungi situs web Anda. Karena browser tidak secara otomatis menambahkan header ke permintaan Anda, itu tidak rentan terhadap serangan CSRF, yang tergantung pada info otentikasi Anda yang dikirimkan secara otomatis ke domain asli.

Skema pembawa sering digunakan untuk melindungi API web (layanan REST) ​​yang dikonsumsi melalui panggilan AJAX atau dari klien seluler.

MvdD
sumber
1
@ Timespace7 Tidak, token JWT juga sering digunakan dari klien asli. OAuth 2.0 memiliki aliran khusus menargetkan klien asli (seluler). Hal yang tidak mereka lakukan adalah otentikasi browser tersirat (seperti cookie atau autentikasi dasar.).
MvdD
5
Saya mengatakan bahwa jika API Anda hanya mengambil token JWT dari header Otorisasi, itu tidak rentan terhadap CSRF. Setiap situs atau API yang mendapatkan token dari cookie memerlukan mitigasi CSRF.
MvdD
13
Apakah ini berarti kita dapat secara efektif menyimpan jwt dalam cookie dan itu akan aman jika kita mengirim permintaan dengannya di header Otorisasi?
cameronroe
10
@cameronjroe Anda dapat menyimpannya di cookie Anda tetapi hanya jika Anda tidak menggunakan cookie Anda untuk otentikasi (Anda menggunakan header Anda dalam hal ini)
Jaakko
1
Panggilan AJAX juga berasal dari browser. Token JWT sebagian besar digunakan untuk mengautentikasi API web (menyajikan data) vs. cookie yang digunakan untuk mengautentikasi aplikasi web (melayani markup, gambar, css, dan JavaScript)
MvdD
144

Kita perlu menyimpan JWT di komputer klien. Jika kita menyimpannya dalam LocalStorage / SessionStorage maka itu dapat dengan mudah ditangkap oleh serangan XSS. Jika kami menyimpannya dalam cookie, maka peretas dapat menggunakannya (tanpa membacanya) dalam serangan CSRF dan menyamar sebagai pengguna dan menghubungi API kami dan mengirim permintaan untuk melakukan tindakan atau mendapatkan informasi atas nama pengguna.

Tetapi ada beberapa cara untuk mengamankan JWT dalam cookie agar tidak mudah dicuri (tetapi masih ada beberapa teknik canggih untuk mencuri mereka). Tetapi jika Anda ingin mengandalkan LocalStorage / SessionStorage, maka itu dapat diakses dengan serangan XSS sederhana.

Jadi untuk mengatasi masalah CSRF, saya menggunakan Cookie Kirim Ganda dalam aplikasi saya.

Metode Kirim Cookie Ganda

  1. Simpan JWT dalam cookie HttpOnly dan gunakan dalam mode aman untuk mentransfer melalui HTTPS.

  2. Sebagian besar serangan CSRF memiliki header asal atau pengarah yang berbeda dengan host asli Anda dalam permintaan mereka. Jadi, periksa apakah Anda memiliki salah satu dari mereka di header, apakah mereka berasal dari domain Anda atau tidak! Jika tidak tolak mereka. Jika asal dan pengarah tidak tersedia dalam permintaan, maka tidak perlu khawatir. Anda bisa mengandalkan hasil hasil validasi header X-XSRF-TOKEN yang saya jelaskan di langkah berikutnya.

  3. Meskipun browser akan secara otomatis menyediakan cookie Anda untuk domain permintaan, ada satu batasan berguna: kode JavaScript yang berjalan di situs web tidak dapat membaca cookie dari situs web lain. Kami dapat memanfaatkan ini untuk menciptakan solusi CSRF kami. Untuk mencegah serangan CSRF, kita harus membuat cookie Javascript tambahan yang bisa dibaca yang disebut: XSRF-TOKEN. Cookie ini harus dibuat ketika pengguna masuk dan harus berisi string acak yang tidak dapat ditebak. Kami juga menyimpan nomor ini di JWT sendiri sebagai klaim pribadi. Setiap kali aplikasi JavaScript ingin membuat permintaan, ia harus membaca token ini dan mengirimkannya dalam header HTTP khusus. Karena operasi ini (membaca cookie, mengatur header) hanya dapat dilakukan pada domain yang sama dari aplikasi JavaScript,

Angular JS membuat hidup Anda mudah

Untungnya, saya menggunakan Angular JS di platform kami dan mengemas paket pendekatan CSRF token, membuatnya lebih mudah bagi kami untuk diimplementasikan. Untuk setiap permintaan yang dibuat aplikasi Angular kami dari server, $httplayanan Angular akan melakukan hal-hal ini secara otomatis:

  • Cari cookie bernama XSRF-TOKEN di domain saat ini.
  • Jika cookie itu ditemukan, itu membaca nilai dan menambahkannya ke permintaan sebagai header X-XSRF-TOKEN.

Dengan demikian implementasi sisi klien ditangani untuk Anda, secara otomatis! Kami hanya perlu mengatur cookie yang dinamai XSRF-TOKENpada domain saat ini di sisi server dan ketika API kami mendapat panggilan dari klien, ia harus memeriksa X-XSRF-TOKENheader dan membandingkannya dengan XSRF-TOKENdi JWT. Jika mereka cocok, maka pengguna itu nyata. Kalau tidak, itu permintaan palsu dan Anda bisa mengabaikannya. Metode ini terinspirasi oleh metode "Kirim Cookie Ganda".

Peringatan

Pada kenyataannya, Anda masih rentan terhadap XSS, hanya saja penyerang tidak dapat mencuri token JWT Anda untuk digunakan nanti, tetapi dia masih bisa membuat permintaan atas nama pengguna Anda menggunakan XSS.

Apakah Anda menyimpan JWT Anda di localStorageatau Anda menyimpan token XSRF Anda di bukan HttpOnly cookie, keduanya dapat diambil dengan mudah oleh XSS. Bahkan JWT Anda dalam cookie HttpOnly dapat diambil dengan serangan XSS canggih seperti metode XST .

Jadi selain metode Cookie Kirim Ganda, Anda harus selalu mengikuti praktik terbaik terhadap XSS termasuk melarikan diri konten. Ini berarti menghapus kode yang dapat dieksekusi yang akan menyebabkan browser melakukan sesuatu yang tidak Anda inginkan. Biasanya ini berarti menghapus // <![CDATA[tag dan atribut HTML yang menyebabkan JavaScript dievaluasi.

Baca lebih lanjut di sini:

Iman Sedighi
sumber
1
@AranDehkharghani ya saya kira itu mencegah serangan replay terutama jika Anda mengubah JWT dan berakhir JWT sebelumnya setiap kali digunakan oleh API. itu berarti JWT Anda akan menjadi seperti kata sandi satu kali (OTP). Anda dapat menggunakan JWT dengan berbagai cara tergantung pada seberapa banyak Anda peduli tentang keamanan di platform Anda.
Iman Sedighi
7
Seperti yang Anda sebutkan, jika situs web rentan terhadap XSS, maka itu hanya masalah waktu sebelum pengguna dieksploitasi. Sepertinya kita melakukan perdagangan kompleksitas yang signifikan untuk peningkatan keamanan yang sangat kecil.
shusson
3
@shusson Anda harus menangani serangan XSS dan XSRF untuk melindungi JWT Anda. Saya tidak setuju bahwa Anda melakukan perdagangan kompleksitas yang signifikan untuk peningkatan keamanan yang sangat kecil. Jika masalah keamanan, maka Anda perlu melakukan semua upaya untuk tidak memiliki kerentanan XSS. Metode ini dirancang untuk melindungi token Anda dari serangan XSRF. tetapi itu tidak berarti bahwa Anda dapat mengabaikan kerentanan XSS.
Iman Sedighi
5
@ImanSedighi Saya tidak jelas, dengan menyimpan jwt dalam cookie Anda menambahkan kompleksitas dan Anda sekarang harus melindungi terhadap XSRF. Jadi mengapa tidak menggunakan penyimpanan lokal dengan token yang pendek dan berkonsentrasi untuk mencegah XSS?
shusson
2
@Royi Namir: Spoofing oleh Wireshark seharusnya tidak menjadi masalah jika Anda menggunakan sertifikat SSL $ 10! Jika keamanan situs web penting maka Anda harus mengenkripsi data dan menggunakan protokol HTTPS.
Iman Sedighi
2

Sudut lain untuk seluruh masalah penyimpanan JWT:

  1. JWT tidak boleh disimpan di Penyimpanan lokal Anda
  2. Bahkan, mereka seharusnya tidak disimpan di cookie Anda , kecuali Anda mampu menerapkan perlindungan CSRF yang sangat ketat

Lihat ini untuk motivasi

  • JWT sebagai id_token seperti kredensial pengguna Anda
  • JWT sebagai access_token seperti token sesi Anda

Opsi paling aman adalah di dalam memori . Lihat ini untuk menyelam dalam-dalam

manusia
sumber