JWT có nên được lưu trữ trong localStorage hoặc cookie không? [bản sao]


101

Với mục đích bảo mật REST API bằng JWT, theo một số tài liệu (như hướng dẫn này và câu hỏi này ), JWT có thể được lưu trữ trong localStorage hoặc Cookies . Dựa trên sự hiểu biết của tôi:

  • localStorage phải tuân theo XSS và nói chung không nên lưu trữ bất kỳ thông tin nhạy cảm nào trong đó.
  • Với Cookie, chúng tôi có thể áp dụng cờ "httpOnly" để giảm nguy cơ XSS. Tuy nhiên, nếu chúng ta đọc JWT từ Cookie trên chương trình phụ trợ, thì chúng ta phải chịu CSRF.

Vì vậy, dựa trên tiền đề trên - sẽ tốt nhất nếu chúng ta lưu trữ JWT trong Cookie. Đối với mọi yêu cầu đến máy chủ, JWT sẽ được đọc từ Cookie và được thêm vào tiêu đề Ủy quyền bằng lược đồ Bearer. Sau đó máy chủ có thể xác minh JWT trong tiêu đề yêu cầu (trái ngược với việc đọc nó từ cookie).

Tôi hiểu có đúng không? Nếu vậy, cách tiếp cận trên có bất kỳ mối quan tâm bảo mật nào không? Hay thực sự chúng ta chỉ có thể sử dụng localStorage ngay từ đầu?



@ lrn2prgrm như người ta không nên sử dụng (stateless) JWT ngữ nghĩa (stateful) phiên nhau.
ozanmuyes

Câu trả lời:


56

Tôi thích phương pháp XSRF Double Submit Cookies được đề cập trong bài viết mà @ pkid169 đã nói, nhưng có một điều mà bài viết không cho bạn biết. Bạn vẫn không được bảo vệ trước XSS vì những gì kẻ tấn công có thể làm là chèn tập lệnh đọc cookie CSRF của bạn (không phải là HttpOnly) và sau đó thực hiện yêu cầu đến một trong các điểm cuối API của bạn bằng cách sử dụng mã thông báo CSRF này với cookie JWT được gửi tự động.

Vì vậy, trong thực tế, bạn vẫn dễ bị ảnh hưởng bởi XSS, chỉ là kẻ tấn công không thể đánh cắp mã thông báo JWT của bạn để sử dụng sau này, nhưng anh ta vẫn có thể thay mặt người dùng của bạn yêu cầu bằng XSS.

Cho dù bạn lưu trữ JWT của mình trong localStorage hay bạn lưu trữ mã thông báo XSRF của mình trong cookie không chỉ http, cả hai đều có thể bị XSS nắm bắt dễ dàng. Ngay cả cookie JWT trong HttpOnly của bạn cũng có thể bị tấn công XSS nâng cao.

Vì vậy, ngoài phương pháp Double Submit Cookies, bạn phải luôn tuân theo các phương pháp hay nhất chống lại XSS bao gồm cả nội dung thoát. Điều này có nghĩa là loại bỏ bất kỳ mã thực thi nào có thể khiến trình duyệt làm điều gì đó mà bạn không muốn. Thông thường, điều này có nghĩa là xóa các thẻ // <! [CDATA [và các thuộc tính HTML khiến JavaScript được đánh giá.


11
Bạn có thể làm rõ cách lấy một cookie JWT trong HttpOnly không? Nó có thể được sử dụng bởi XSRF nếu mã thông báo XSRF bị xâm phạm bởi XSS, nhưng nó thực sự có thể tự lấy được không?
Jacek Gorgoń

1
Tôi biết đây là một bài đăng cũ, nhưng tôi muốn hỏi một số câu hỏi ... Điều đó có nghĩa là các tập lệnh được xây dựng tốt có thể đọc cả localStorage và cookie? Nếu vậy, liệu có an toàn khi cho rằng JWT có thể bị đánh cắp cho dù chúng ta lưu trữ nó ở đâu trong trình duyệt? Sau đó, tôi cảm thấy chỉ dựa vào JWT là rất rủi ro.
Hiroki

2
"Ngay cả JWT trong cookie HttpOnly của bạn cũng có thể bị tấn công XSS nâng cao." là sai. Đã chỉnh sửa bài gốc để sửa điều này.
java-boldct301

"Ngay cả cookie JWT trong HttpOnly của bạn cũng có thể bị tấn công XSS nâng cao" Tôi có thể tưởng tượng rằng ai đó lấy cookie bằng cách gửi nó đến máy chủ của chính anh ta. Vì vậy, anh ta có thể sử dụng tìm nạp với giá trị phù hợp của cờ thông tin xác thực. Vấn đề chính ở đây là bảo vệ CORS nhưng trong một số trường hợp, tôi nghĩ là có thể.
bartnikiewi.cz 30/07/19

"tiêm tập lệnh đọc cookie CSRF của bạn (không phải là HttpOnly)" Việc triển khai mặc định Html.AntiForgeryToken()trong ASP.NET MVC sử dụng cookie HttpOnly cho mã thông báo CSRF. Tôi nghĩ rằng bạn vẫn còn nhạy cảm với một số XSS nhất định, nhưng nghĩ rằng điều này đáng nói.
Lovethenakedgun

21

Một bài đăng kịp thời từ Stormpath đã giải thích khá nhiều quan điểm của tôi và trả lời câu hỏi của tôi.

TL; DR

Lưu trữ JWT trong cookie, sau đó chuyển JWT trong tiêu đề Ủy quyền đối với mọi yêu cầu như tôi đã đề cập hoặc như bài viết đề xuất, dựa vào phụ trợ để ngăn CSRF (ví dụ: sử dụng xsrfTokentrong trường hợp Angular).


2
Xin chào, Tôi không chắc điều này có đúng không nhưng có một số nhược điểm cụ thể khi sử dụng cookie để lưu trữ jwt khi bạn triển khai CrossOrigin cho bộ điều khiển của mình, đó là cảnh mà ứng dụng máy chủ của tôi được đặt ở một nơi khác và chúng tôi đang gọi api từ nó trong ứng dụng khách hàng của chúng tôi được đặt ở thành phố khác? Đó không phải là lý do tại sao nhiều nhà cung cấp dịch vụ web từ chối sử dụng cookie?
valik

CrossOrigin không có nghĩa là vị trí thực tế. Nó đề cập đến các yêu cầu đến từ các miền khác. Trong lõi .net khi bạn quyết định sử dụng CORS, bạn chỉ định miền nào bạn sẽ cho phép; những tiêu đề nào bạn sẽ cho phép, v.v.
Brian Allan West

11
  • Không lưu trữ mã thông báo của bạn trong LocalStorage hoặc SessionStorage, vì mã thông báo đó có thể được đọc từ javascript và do đó, nó có thể bị tấn công XSS.
  • Không lưu trữ mã thông báo của bạn trong Cookie. Cookie (với cờ HttpOnly) là một lựa chọn tốt hơn - nó dễ bị XSS, nhưng nó dễ bị tấn công CSRF

Thay vào đó, khi đăng nhập, bạn có thể phân phối hai mã thông báo: mã thông báo truy cập và mã thông báo làm mới. Mã thông báo truy cập phải được lưu trữ trong bộ nhớ Javascript và mã thông báo Làm mới phải được lưu trữ trong HttpOnly Cookie. Mã làm mới chỉ được sử dụng và chỉ để tạo mã thông báo truy cập mới - không có gì khác.

Khi người dùng mở tab mới hoặc khi làm mới trang web, bạn cần thực hiện yêu cầu tạo mã thông báo truy cập mới, dựa trên mã thông báo làm mới được lưu trữ trong Cookie.

Tôi cũng đặc biệt khuyên bạn nên đọc bài viết này: https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/


5
Tại sao lại tăng thêm độ phức tạp khi bạn chỉ có thể coi mã làm mới như một mã thông báo truy cập? Làm thế nào là phương pháp này an toàn hơn cho tôi đánh dấu truy cập của tôi mã thông báo như secure, samesite: strict, http-only?
Charming Robot

nó không an toàn hơn
Chris Hawkes

2

Để giúp ngăn chặn các cuộc tấn công CSRF tận dụng các cookie hiện có, bạn có thể đặt cookie của mình bằng lệnh SameSite. Đặt nó thành laxhoặc strict.

Đây vẫn là bản nháp và tính đến năm 2019 không được hỗ trợ đầy đủ bởi tất cả các trình duyệt hiện tại , nhưng tùy thuộc vào độ nhạy của dữ liệu và / hoặc quyền kiểm soát của bạn đối với các trình duyệt mà người dùng của bạn sử dụng, đây có thể là một lựa chọn khả thi. Đặt chỉ thị với SameSite=laxsẽ cho phép "điều hướng cấp cao nhất sử dụng phương thức HTTP 'an toàn' ...".

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.