Apakah aman untuk menyimpan jwt di localStorage dengan reactjs?

147

Saat ini saya sedang membangun satu aplikasi halaman menggunakan reactjs. Saya membaca bahwa banyak alasan untuk tidak menggunakan localStorage adalah karena kerentanan XSS. Karena Bereaksi lolos dari semua input pengguna, apakah sekarang aman menggunakan localStorage?

Kaloyan Kosev
sumber
4
lebih suka Session Storage
Praneet Rohida
3
"Dianjurkan untuk tidak menyimpan informasi sensitif di penyimpanan lokal." -OWASP "menyimpannya dalam memori tanpa kegigihan" -Auth0
avejidah
Saya pikir Auth0 mungkin telah mengubah perspektif mereka tentang ini - karena saya tidak dapat menemukan kutipan di atas di tautan yang disediakan
DauleDK

Jawaban:

141

Di sebagian besar aplikasi satu halaman modern, kita memang harus menyimpan token di suatu tempat di sisi klien (kasus penggunaan paling umum - untuk menjaga pengguna tetap masuk setelah penyegaran halaman).

Ada total 2 opsi yang tersedia: Penyimpanan Web (penyimpanan sesi, penyimpanan lokal) dan cookie sisi klien. Kedua opsi ini banyak digunakan, tetapi ini tidak berarti mereka sangat aman.

Tom Abbott merangkum dengan baik sesi JWTSageage dan keamanan localStorage :

Penyimpanan Web (localStorage / sessionStorage) dapat diakses melalui JavaScript pada domain yang sama. Ini berarti bahwa setiap JavaScript yang berjalan di situs Anda akan memiliki akses ke penyimpanan web, dan karena ini dapat rentan terhadap serangan lintas situs (XSS) . Singkatnya, XSS, adalah jenis kerentanan di mana penyerang dapat menyuntikkan JavaScript yang akan berjalan di halaman Anda. Serangan XSS dasar mencoba untuk menyuntikkan JavaScript melalui input formulir, di mana penyerang memasukkan <script>alert('You are Hacked');</script>ke dalam formulir untuk melihat apakah itu dijalankan oleh browser dan dapat dilihat oleh pengguna lain.

Untuk mencegah XSS, respons umum adalah melarikan diri dan menyandikan semua data yang tidak dipercaya. Bereaksi (kebanyakan) melakukannya untuk Anda! Berikut adalah diskusi hebat tentang seberapa banyak perlindungan kerentanan XSS yang Bereaksi bertanggung jawab atas .

Tapi itu tidak mencakup semua kemungkinan kerentanan! Ancaman potensial lainnya adalah penggunaan JavaScript yang diinangi pada CDN atau infrastruktur luar .

Ini Tom lagi:

Aplikasi web modern termasuk perpustakaan JavaScript pihak ketiga untuk pengujian A / B, analisis saluran / pasar, dan iklan. Kami menggunakan manajer paket seperti Bower untuk mengimpor kode orang lain ke dalam aplikasi kami.

Bagaimana jika hanya satu dari skrip yang Anda gunakan yang dikompromikan? JavaScript berbahaya dapat disematkan pada halaman, dan Penyimpanan Web dikompromikan. Jenis serangan XSS ini dapat membuat Penyimpanan Web semua orang yang mengunjungi situs Anda, tanpa sepengetahuan mereka. Ini mungkin sebabnya banyak organisasi menyarankan untuk tidak menyimpan sesuatu yang bernilai atau mempercayai informasi apa pun dalam penyimpanan web. Ini termasuk pengidentifikasi dan token sesi.

Oleh karena itu, kesimpulan saya adalah bahwa sebagai mekanisme penyimpanan, Penyimpanan Web tidak memberlakukan standar keamanan apa pun selama transfer . Siapa pun yang membaca Penyimpanan Web dan menggunakannya harus melakukan uji tuntas untuk memastikan mereka selalu mengirim JWT melalui HTTPS dan tidak pernah HTTP.

Kaloyan Kosev
sumber
10
Jadi, jika saya memahami Anda dengan benar, Anda merekomendasikan cookie? Hanya untuk memastikan. Terima kasih!
SuperLemon
7
Iya. Saya merekomendasikan cookie karena keamanan tambahan yang mereka berikan, dan kesederhanaan melindungi terhadap CSRF dengan kerangka kerja web modern. Penyimpanan Web (localStorage / sessionStorage) rentan terhadap XSS, memiliki area permukaan serangan yang lebih besar, dan dapat berdampak pada semua pengguna aplikasi pada serangan yang berhasil.
Kaloyan Kosev
48
Saya pikir Anda memiliki ini dicampur? Kerangka kerja web modern memiliki pertahanan bawaan yang kuat untuk XSS. Tapi tidak terlalu untuk xsrf. Pertahanan terbaik untuk xsrf adalah menghindari menggunakan cookie sepenuhnya. Penyimpanan lokal di-sandbox ke domain tertentu, yang berarti domain penyerang tidak bisa mengaksesnya. Kerangka kerja web mempertahankan xss dengan secara otomatis menyandikan dan membersihkan input pengguna. Lihat angular.io/guide/security
mikejones1477
47
Jika "Anda merekomendasikan cookie [sebagai gantinya]", maka, dapatkah saya merekomendasikan Anda mengatakannya di suatu tempat di jawabannya? Daripada hanya di komentar?
spechter
7
Saya di sini agak terlambat, hanya membaca topik ini sekarang dan saya bingung tentang satu hal, banyak orang berbicara tentang Anda dilindungi dengan cookie hanya http jika Anda dikompilasi dengan Xss, tetapi, jika Anda memiliki xss atacker tidak perlu mencuri apa pun, ia dapat dengan mudah membuat posting dari halaman untuk menyamar sebagai Anda menggunakan cookie itu (bahkan jika ia tidak bisa mencuri). Apakah saya melewatkan sesuatu ???
Borja Alvarez
35

Saya tahu ini adalah pertanyaan lama tetapi menurut apa yang dikatakan @ mikejones1477, pustaka dan kerangka kerja modern modern luput dari teks yang memberi Anda perlindungan terhadap XSS. Alasan mengapa cookie bukan metode aman menggunakan kredensial adalah bahwa cookie tidak mencegah CSRF ketika localStorage melakukannya (juga ingat bahwa cookie dapat diakses oleh javascript juga, jadi XSS bukan masalah besar di sini), jawaban ini melanjutkan alasannya .

Alasan menyimpan token otentikasi di penyimpanan lokal dan menambahkannya secara manual ke setiap permintaan melindungi terhadap CSRF adalah kata kunci: manual. Karena browser tidak secara otomatis mengirim token autentikasi itu, jika saya mengunjungi evil.com dan mengatur untuk mengirim POST http://example.com/delete-my-account , ia tidak akan dapat mengirim token authn saya, jadi permintaan itu diabaikan.

Tentu saja httpOnly adalah grail suci tetapi Anda tidak dapat mengakses dari reactjs atau kerangka js di samping Anda masih memiliki kerentanan CSRF. Rekomendasi saya adalah penyimpanan lokal atau jika Anda ingin menggunakan cookie, pastikan Anda menerapkan beberapa solusi untuk masalah CSRF Anda seperti yang dilakukan Django .

Mengenai CDN, pastikan Anda tidak menggunakan beberapa CDN aneh, misalnya CDN seperti google atau bootstrap berikan, dikelola oleh komunitas dan tidak mengandung kode berbahaya, jika Anda tidak yakin, Anda bebas untuk meninjau.

Mauricio Cortazar
sumber
2
Tidak yakin mengapa Anda mengatakan bahwa Anda masih rentan terhadap CSRF saat menggunakan cookie. Menggunakan cookie dengan bendera HttpOnly SameSite=strictdan secure, akan membuat informasi yang Anda atur di cookie aman. Kemudian terhadap XSS, Anda cukup memastikan JavaScript Anda tidak mengetahui adanya data terkait otentikasi, seperti token dan kata sandi (artinya, jangan menyimpannya di Penyimpanan Web) - jika Anda mengimpor skrip berbahaya, skrip itu tidak akan memiliki akses untuk data sensitif. Ya, Anda juga tidak akan memiliki akses ke token melalui JS, tetapi itu seharusnya tidak menjadi masalah.
miphe
@miphe itulah yang saya katakan. Tetapi OP meminta cara untuk mengakses dari javascript. Di sini saya hanya menjelaskan apa cara terbaik untuk menyimpan token yang dapat diakses dari js.
Mauricio Cortazar
21

Pada dasarnya tidak apa-apa untuk menyimpan JWT Anda di Penyimpanan lokal Anda.

Dan saya pikir ini cara yang baik. Jika kita berbicara tentang XSS, XSS menggunakan CDN, itu juga berpotensi menimbulkan risiko masuk / lulus klien Anda juga. Menyimpan data dalam penyimpanan lokal setidaknya akan mencegah serangan CSRF.

Anda harus menyadari keduanya dan memilih apa yang Anda inginkan. Kedua serangan itu tidak semua yang perlu Anda waspadai, hanya ingat: SELURUH APLIKASI ANDA HANYA SEPERTI AMAN SEBAGAI TITIK AMAN TERTAMBAH DARI APLIKASI ANDA.

Sekali lagi menyimpan tidak masalah, menjadi rentan terhadap XSS, CSRF, ... tidak

Alex Lyalka
sumber
2
Inilah sebabnya mengapa aman untuk melakukan hal berikut: - Simpan JWT dalam cookie sehingga tidak dapat diambil dari XSS - Simpan token CSRF di localStorage sehingga tidak dapat diambil dari CSRF
Alejandro Cavazos
33
Anda memunculkan poin yang bagus: jika situs Anda menjalankan skrip berbahaya, permainan tetap berakhir. Mereka hanya dapat mengikat peristiwa keydown ke input kata sandi jenis dan mencuri informasi otentikasi pengguna Anda dengan cara itu (yang jauh lebih buruk daripada mencuri token autentikasi JWT). Menyimpan JWT di localStorage tidak sedikit untuk meningkatkan kemungkinan kerusakan yang sudah sangat besar dari XSS.
Carl Leth
8

Tidak aman jika Anda menggunakan CDN:

JavaScript berbahaya dapat disematkan pada halaman, dan Penyimpanan Web dikompromikan. Jenis serangan XSS ini dapat membuat Penyimpanan Web semua orang yang mengunjungi situs Anda, tanpa sepengetahuan mereka. Ini mungkin sebabnya banyak organisasi menyarankan untuk tidak menyimpan sesuatu yang bernilai atau mempercayai informasi apa pun dalam penyimpanan web. Ini termasuk pengidentifikasi dan token sesi.

melalui stormpath

Setiap skrip yang Anda butuhkan dari luar berpotensi dikompromikan dan dapat mengambil JWTS dari penyimpanan klien Anda dan mengirim data pribadi kembali ke server penyerang.

Stephen L.
sumber
6
Jika saya tidak berencana menggunakan cdns apakah aman?
1
Penulis artikel tidak pernah membuat perbedaan antara XSS di situs yang dilayani melalui CDN atau langsung dari server pusat. Bukankah penjelasan Anda di sini juga berlaku secara umum, bukan hanya untuk CDN?
Vlad
5

Penyimpanan lokal dirancang agar dapat diakses oleh javascript, sehingga tidak memberikan perlindungan XSS. Seperti disebutkan dalam jawaban lain, ada banyak cara yang memungkinkan untuk melakukan serangan XSS, dari mana penyimpanan lokal tidak dilindungi secara default.

Namun, cookie memiliki bendera keamanan yang melindungi dari serangan XSS dan CSRF. Bendera HttpOnly mencegah javascript sisi klien mengakses cookie, Bendera aman hanya memungkinkan browser untuk mentransfer cookie melalui ssl, dan bendera SameSite memastikan bahwa cookie dikirim hanya ke tempat asal. Meskipun saya baru saja memeriksa dan SameSite saat ini hanya didukung di Opera dan Chrome, jadi untuk melindungi dari CSRF lebih baik menggunakan strategi lain. Misalnya, mengirim token terenkripsi di cookie lain dengan beberapa data pengguna publik.

Jadi cookie adalah pilihan yang lebih aman untuk menyimpan data otentikasi.

Ivan
sumber
tidak bisa mendapatkan: bagaimana HttpOnly dapat melindungi Anda dari CSRF?
Alex Lyalka
@AlexLyalka Tidak bermaksud mengatakan bahwa HttpOnly mencegah CSRF, daripada semua flag cookie bersama-sama dapat melindungi dari XSS dan CSRF. SameSite memberikan perlindungan, mencegah cookie dikirim ke situs yang berbeda dari asalnya. Meskipun saya baru saja memeriksa dan dukungan untuk bendera itu sangat rendah. Dimungkinkan juga untuk menghindari CSRF dengan token terenkripsi terpisah dengan beberapa identifikasi pengguna, yang diperiksa di server.
Ivan
1
Nah, jika seseorang dapat mengeksekusi kode di web Anda, tidak bisakah dia membuat posting ke web Anda atas nama pengguna Anda? Oke, dia tidak bisa mendapatkan cookie http saja, tetapi dia bisa membuat panggilan menggunakan cookie itu, jadi saya masih tidak bisa mengerti intinya
Borja Alvarez
2
@ BorjaAlverez Ada perbedaan besar. Ya, melalui XSS seseorang dapat membuat permintaan atas nama pengguna yang masuk, tetapi kompromi token lebih buruk. Misalnya: token dapat menyediakan akses ke API yang tidak digunakan aplikasi klien; token dapat memiliki informasi lain tentang pengguna (alamat email, profil, dan hibah); token dapat digunakan dalam serangan replay terhadap aplikasi Anda; token dapat diteruskan sebagai id_token_hintke server autentikasi OIDC; token menyediakan informasi penyerang tentang sandi yang digunakan untuk menandatanganinya; dll
avejidah
3

Cara untuk melihatnya adalah dengan mempertimbangkan tingkat risiko atau bahaya.

Apakah Anda membangun aplikasi tanpa pengguna, POC / MVP? Apakah Anda seorang pemula yang perlu memasarkan dan menguji aplikasi Anda dengan cepat? Jika ya, saya mungkin hanya akan menerapkan solusi paling sederhana dan mempertahankan fokus pada menemukan produk yang sesuai pasar. Gunakan localStorage karena seringkali lebih mudah diterapkan.

Apakah Anda membuat v2 aplikasi dengan banyak pengguna aktif harian atau aplikasi yang sangat bergantung pada orang / bisnis. Apakah diretas berarti sedikit atau tidak ada ruang untuk pemulihan? Jika demikian, saya akan lama melihat ketergantungan Anda dan mempertimbangkan untuk menyimpan informasi token dalam cookie http-only.

Menggunakan penyimpanan lokal dan penyimpanan cookie / sesi memiliki pro dan kontra mereka sendiri.

Seperti yang dinyatakan oleh jawaban pertama: Jika aplikasi Anda memiliki kerentanan XSS, tidak ada yang akan melindungi pengguna Anda. Karena sebagian besar aplikasi modern memiliki selusin atau lebih dependensi berbeda, menjadi semakin sulit untuk menjamin bahwa salah satu dependensi aplikasi Anda tidak rentan terhadap XSS.

Jika aplikasi Anda memang memiliki kerentanan XSS dan seorang peretas telah dapat memanfaatkannya, peretas akan dapat melakukan tindakan atas nama pengguna Anda. Peretas dapat melakukan permintaan GET / POST dengan mengambil token dari localStorage atau dapat melakukan permintaan POST jika token disimpan dalam cookie http-only.

Satu-satunya sisi buruk dari penyimpanan token Anda di penyimpanan lokal adalah peretas akan dapat membaca token Anda.

HenokG
sumber
1

Apakah localStorage atau httpOnly cookie tidak dapat diterima? Sehubungan dengan perpustakaan pihak ke-3 yang dikompromikan, satu-satunya solusi yang saya tahu yang akan mengurangi / mencegah informasi sensitif dicuri akan diberlakukan Integritas Subresource .

Subresource Integrity (SRI) adalah fitur keamanan yang memungkinkan browser untuk memverifikasi bahwa sumber daya yang mereka ambil (misalnya, dari CDN) dikirimkan tanpa manipulasi yang tidak terduga. Ini bekerja dengan memungkinkan Anda untuk memberikan hash kriptografi yang harus diambil oleh sumber daya yang diambil.

Selama pustaka pihak ketiga yang dikompromikan aktif di situs web Anda, keylogger dapat mulai mengumpulkan info seperti nama pengguna, kata sandi, dan apa pun yang Anda masukkan ke dalam situs.

Cookie httpOnly akan mencegah akses dari komputer lain tetapi tidak akan melakukan apa pun untuk mencegah peretas memanipulasi komputer pengguna.

DIAM
sumber
-10

Aman untuk menyimpan token Anda di Penyimpanan lokal selama Anda mengenkripsi itu. Di bawah ini adalah cuplikan kode terkompresi yang menunjukkan salah satu dari banyak cara Anda dapat melakukannya.

    import SimpleCrypto from 'simple-crypto-js';

    const saveToken = (token = '') => {
          const encryptInit = new SimpleCrypto('PRIVATE_KEY_STORED_IN_ENV_FILE');
          const encryptedToken = encryptInit.encrypt(token);

          localStorage.setItem('token', encryptedToken);
     }

Lalu, sebelum menggunakan token Anda dekripsi menggunakan PRIVATE_KEY_STORED_IN_ENV_FILE

Kidali Kevin
sumber
@HassanAlthaf Anda kehilangan intinya di sini, tidak akan pernah ada aplikasi bukti 100% aman, Hanya saja, Anda mengurangi permukaan serangan dan setidaknya file env tidak akan dipublikasikan di github secara langsung. Selain itu, kode yang dibundel akan dikaburkan dan dihancurkan, sehingga sulit bagi penyerang untuk menemukannya.
Kidali Kevin
Kunci pribadi tidak seharusnya terbuka. Anda akan membahayakan seluruh API.
Hassan Althaf
Dari pengalaman saya Jika Anda melakukan hal-hal dengan cerdas dan benar, kunci pribadi Anda tidak akan terekspos di build produksi Anda, jika demikian, tangkapan layar untuk mendukung ini atau bahkan url.
Kidali Kevin