Có an toàn để lưu trữ một jwt trong localStorage với Reacjs không?


147

Tôi hiện đang xây dựng một ứng dụng trang duy nhất bằng Reacjs. Tôi đọc được rằng nhiều lý do không sử dụng localStorage là do các lỗ hổng XSS. Vì React thoát khỏi tất cả đầu vào của người dùng, giờ đây nó có an toàn khi sử dụng localStorage không?


4
thích Lưu trữ phiên
Praneet Rohida


3
"Chúng tôi khuyên bạn không nên lưu trữ bất kỳ thông tin nhạy cảm nào trong bộ nhớ cục bộ." -OWASP "lưu trữ chúng trong bộ nhớ mà không cần bất kỳ sự kiên trì nào" -Auth0
avejidah

Tôi nghĩ Auth0 có thể đã thay đổi quan điểm của họ về điều này - bởi vì tôi không thể tìm thấy trích dẫn ở trên trong liên kết được cung cấp
DauleDK

Câu trả lời:


141

Trong hầu hết các ứng dụng trang đơn hiện đại, chúng tôi thực sự phải lưu trữ mã thông báo ở đâu đó ở phía máy khách (trường hợp sử dụng phổ biến nhất - để giữ cho người dùng đăng nhập sau khi làm mới trang).

Có tổng cộng 2 tùy chọn có sẵn: Lưu trữ web (lưu trữ phiên, lưu trữ cục bộ) và cookie phía máy khách. Cả hai tùy chọn đều được sử dụng rộng rãi, nhưng điều này không có nghĩa là chúng rất an toàn.

Tom Abbott tóm tắt tốt bảo mật phiên JWTStorage và localStorage :

Lưu trữ web (localStorage / sessionStorage) có thể truy cập thông qua JavaScript trên cùng một tên miền. Điều này có nghĩa là bất kỳ JavaScript nào chạy trên trang web của bạn đều có quyền truy cập vào bộ lưu trữ web và do điều này có thể dễ bị tấn công bởi kịch bản chéo trang (XSS) . XSS, tóm lại, là một loại lỗ hổng trong đó kẻ tấn công có thể tiêm JavaScript sẽ chạy trên trang của bạn. Các cuộc tấn công XSS cơ bản cố gắng tiêm JavaScript thông qua các đầu vào của biểu mẫu, trong đó kẻ tấn công đưa <script>alert('You are Hacked');</script>vào một biểu mẫu để xem nó có được trình duyệt chạy hay không và có thể được xem bởi những người dùng khác.

Để ngăn XSS, phản ứng phổ biến là thoát và mã hóa tất cả dữ liệu không đáng tin cậy. React (chủ yếu) làm điều đó cho bạn! Đây là một cuộc thảo luận tuyệt vời về mức độ bảo vệ lỗ hổng XSS mà React chịu trách nhiệm .

Nhưng điều đó không bao gồm tất cả các lỗ hổng có thể! Một mối đe dọa tiềm năng khác là việc sử dụng JavaScript được lưu trữ trên CDN hoặc cơ sở hạ tầng bên ngoài .

Lại là Tom:

Các ứng dụng web hiện đại bao gồm các thư viện JavaScript của bên thứ 3 để thử nghiệm A / B, phân tích kênh / thị trường và quảng cáo. Chúng tôi sử dụng các trình quản lý gói như Bower để nhập mã của người khác vào ứng dụng của mình.

Điều gì nếu chỉ một trong các tập lệnh bạn sử dụng bị xâm phạm? JavaScript độc hại có thể được nhúng trên trang và Lưu trữ web bị xâm phạm. Các loại tấn công XSS này có thể khiến Web Storage của mọi người truy cập trang web của bạn mà không cần biết. Đây có lẽ là lý do tại sao một loạt các tổ chức khuyên không nên lưu trữ bất cứ thứ gì có giá trị hoặc tin tưởng bất kỳ thông tin nào trong lưu trữ web. Điều này bao gồm định danh phiên và mã thông báo.

Do đó, kết luận của tôi là với tư cách là một cơ chế lưu trữ, Web Storage không thực thi bất kỳ tiêu chuẩn bảo mật nào trong quá trình chuyển . Bất cứ ai đọc Lưu trữ web và sử dụng nó đều phải thực hiện trách nhiệm của mình để đảm bảo họ luôn gửi JWT qua HTTPS và không bao giờ HTTP.


10
Vì vậy, nếu tôi hiểu bạn chính xác, bạn đề nghị cookie? Chỉ để chắc chắn. Cảm ơn!
SuperLemon

7
Đúng. Tôi khuyên dùng cookie vì bảo mật bổ sung mà họ cung cấp và tính đơn giản của việc bảo vệ chống lại CSRF với các khung web hiện đại. Lưu trữ web (localStorage / sessionStorage) dễ bị tổn thương bởi XSS, có diện tích bề mặt tấn công lớn hơn và có thể tác động đến tất cả người dùng ứng dụng trong một cuộc tấn công thành công.
Kaloyan Kosev

48
Tôi nghĩ rằng bạn có những hỗn hợp? Các khung web hiện đại đã được xây dựng mạnh mẽ để bảo vệ XSS. Nhưng không nhiều cho xsrf. Cách phòng thủ tốt nhất cho xsrf là ​​tránh sử dụng cookie hoàn toàn. Bộ nhớ cục bộ được hộp cát đến một miền cụ thể, có nghĩa là miền kẻ tấn công không thể truy cập được. Các khung web bảo vệ chống lại xss bằng cách tự động mã hóa và vệ sinh đầu vào của người dùng. Xem angular.io/guide/securance
mikejones1477

47
Nếu "bạn đề xuất cookie [thay vào đó]", thì tôi có thể khuyên bạn nên nói điều đó ở đâu đó trong câu trả lời không? Thay vì chỉ trong các ý kiến?
spechter

7
Tôi đến đây hơi muộn, chỉ đọc những chủ đề này bây giờ và tôi bối rối về một điều, rất nhiều người nói về việc bạn được bảo vệ bằng cookie chỉ http nếu bạn bị buộc tội với Xss, nhưng, nếu bạn có xss Atacker không cần phải ăn cắp bất cứ thứ gì của bạn, anh ta có thể đơn giản tạo một bài đăng từ trang để mạo danh bạn bằng cách sử dụng cookie đó (ngay cả khi anh ta không thể đánh cắp nó). Tui bỏ lỡ điều gì vậy???
Borja Alvarez

35

Tôi biết đây là một câu hỏi cũ nhưng theo những gì @ mikejones1477 đã nói, các thư viện và khung công tác hiện đại thoát khỏi văn bản giúp bạn bảo vệ chống lại XSS. Lý do tại sao cookie không phải là một phương pháp an toàn khi sử dụng thông tin đăng nhập là vì cookie không ngăn CSRF khi localStorage thực hiện (cũng nhớ rằng cookie cũng có thể truy cập bằng javascript, vì vậy XSS không phải là vấn đề lớn ở đây), câu trả lời này tiếp tục tại sao .

Lý do lưu trữ mã thông báo xác thực trong bộ nhớ cục bộ và thêm thủ công vào từng yêu cầu bảo vệ chống lại CSRF là từ khóa đó: thủ công. Vì trình duyệt không tự động gửi mã thông báo xác thực đó, nếu tôi truy cập evil.com và nó quản lý để gửi POST http://example.com/delete-my-account , vì vậy nó sẽ không thể gửi mã thông báo authn của tôi, vì vậy yêu cầu bị bỏ qua.

Tất nhiên httpOnly là chén thánh nhưng bạn không thể truy cập từ Reacjs hoặc bất kỳ khung js nào bên cạnh bạn vẫn có lỗ hổng CSRF. Đề xuất của tôi sẽ là lưu trữ cục bộ hoặc nếu bạn muốn sử dụng cookie, hãy đảm bảo thực hiện một số giải pháp cho vấn đề CSRF của bạn như django .

Liên quan đến CDN, đảm bảo bạn không sử dụng một số CDN kỳ lạ, ví dụ CDN như google hoặc bootstrap cung cấp, được cộng đồng duy trì và không chứa mã độc, nếu bạn không chắc chắn, bạn có thể xem xét miễn phí.


2
Không chắc chắn lý do tại sao bạn nói bạn vẫn dễ bị CSRF khi sử dụng cookie. Sử dụng cookie với các cờ HttpOnly SameSite=strictsecure, sẽ giữ thông tin bạn đặt trong cookie an toàn. Sau đó, chống lại XSS, bạn chỉ cần đảm bảo rằng JavaScript của bạn không biết về bất kỳ dữ liệu liên quan đến xác thực nào, như mã thông báo và mật khẩu (nghĩa là không lưu trữ chúng trong Bộ lưu trữ web) - nếu bạn nhập tập lệnh độc hại, tập lệnh đó sẽ không có quyền truy cập dữ liệu nhạy cảm. Có, bạn cũng sẽ không có quyền truy cập vào mã thông báo thông qua JS, nhưng đó thực sự không phải là vấn đề.
miphe

@miphe đó là những gì tôi nói. Nhưng OP đang yêu cầu một cách để truy cập từ javascript. Ở đây tôi chỉ giải thích cách tốt nhất để lưu trữ mã thông báo có thể truy cập từ js.
Mauricio Cortazar

21

Về cơ bản, bạn có thể lưu trữ JWT của mình trong LocalStorage.

Và tôi nghĩ rằng đây là một cách tốt. Nếu chúng ta đang nói về XSS, XSS bằng CDN, thì đó cũng có nguy cơ tiềm ẩn trong việc đăng nhập / vượt qua của khách hàng của bạn. Lưu trữ dữ liệu trong bộ nhớ cục bộ sẽ ngăn chặn các cuộc tấn công CSRF ít nhất.

Bạn cần nhận thức được cả hai và chọn những gì bạn muốn. Cả hai cuộc tấn công không phải là tất cả những gì bạn cần phải biết, chỉ cần nhớ: ỨNG DỤNG ENTIRE CỦA BẠN CHỈ ĐƯỢC BẢO ĐẢM LÀ ĐIỂM BẢO MẬT MỚI NHẤT CỦA ỨNG DỤNG CỦA BẠN.

Một lần nữa lưu trữ là OK, dễ bị XSS, CSRF, ... không


2
Đây là lý do tại sao bạn có thể thực hiện các thao tác sau: - Lưu trữ JWT trong cookie để không thể truy xuất từ ​​XSS - Lưu mã thông báo CSRF trong localStorage để không thể truy xuất từ ​​CSRF
Alejandro Cavazos

33
Bạn đưa ra một điểm tốt: nếu trang web của bạn chạy một tập lệnh độc hại, dù sao thì đó cũng là trò chơi. Họ chỉ có thể liên kết các sự kiện khóa phím với đầu vào của mật khẩu loại và đánh cắp thông tin xác thực người dùng của bạn theo cách đó (điều này tệ hơn nhiều so với việc đánh cắp mã thông báo xác thực JWT). Lưu trữ JWT trong localStorage không làm tăng thêm thiệt hại có thể có từ XSS.
Carl Leth

8

Sẽ không an toàn nếu bạn sử dụng CDN:

JavaScript độc hại có thể được nhúng trên trang và Lưu trữ web bị xâm phạm. Các loại tấn công XSS này có thể khiến Web Storage của mọi người truy cập trang web của bạn mà không cần biết. Đây có lẽ là lý do tại sao một loạt các tổ chức khuyên không nên lưu trữ bất cứ thứ gì có giá trị hoặc tin tưởng bất kỳ thông tin nào trong lưu trữ web. Điều này bao gồm định danh phiên và mã thông báo.

thông qua cơn bão

Bất kỳ tập lệnh nào bạn yêu cầu từ bên ngoài đều có khả năng bị xâm phạm và có thể lấy bất kỳ JWTS nào từ bộ lưu trữ của khách hàng của bạn và gửi dữ liệu cá nhân trở lại máy chủ của kẻ tấn công.


6
Nếu tôi không có kế hoạch sử dụng cdns thì có an toàn không?

1
Tác giả của bài viết không bao giờ phân biệt giữa XSS trên các trang được phân phát qua CDN hoặc trực tiếp từ máy chủ trung tâm. Không phải lời giải thích của bạn ở đây cũng áp dụng chung, không chỉ cho CDN?
Vlad

5

Localst Storage được thiết kế để có thể truy cập bằng javascript, do đó nó không cung cấp bất kỳ sự bảo vệ XSS nào. Như đã đề cập trong các câu trả lời khác, có một loạt các cách có thể để thực hiện một cuộc tấn công XSS, từ đó lưu trữ cục bộ không được bảo vệ theo mặc định.

Tuy nhiên, cookie có cờ bảo mật bảo vệ khỏi các cuộc tấn công XSS và CSRF. Cờ httpOnly ngăn javascript phía máy khách truy cập cookie, Cờ bảo mật chỉ cho phép trình duyệt chuyển cookie qua ssl và cờ SameSite đảm bảo rằng cookie chỉ được gửi đến nguồn gốc. Mặc dù tôi mới kiểm tra và SameSite hiện chỉ được hỗ trợ trong Opera và Chrome, vì vậy để bảo vệ khỏi CSRF, tốt hơn là sử dụng các chiến lược khác. Ví dụ: gửi mã thông báo được mã hóa trong cookie khác với một số dữ liệu người dùng công khai.

Vì vậy, cookie là một lựa chọn an toàn hơn để lưu trữ dữ liệu xác thực.


Không thể nhận được: làm thế nào HTTPOnly có thể bảo vệ bạn khỏi CSRF?
Alex Lyalka

@AlexLyalka Không có nghĩa là nói rằng HTTPOnly ngăn CSRF, thay vì tất cả các cờ cookie có thể bảo vệ khỏi XSS và CSRF. SameSite cung cấp một số bảo vệ, ngăn chặn các cookie được gửi đến một trang web khác với nguồn gốc. Mặc dù tôi chỉ kiểm tra và hỗ trợ cho lá cờ đó là rất thấp. Cũng có thể tránh CSRF bằng mã thông báo được mã hóa riêng với một số nhận dạng người dùng, được kiểm tra trên máy chủ.
Ivan

1
Chà, nếu ai đó có thể thực thi mã trong trang web của bạn, bạn có thể chỉ cần tạo một bài đăng lên web của bạn dưới tên người dùng của bạn không? Ok, anh ấy không thể nhận được cookie chỉ http của bạn, nhưng anh ấy có thể thực hiện cuộc gọi bằng các cookie đó, vì vậy tôi vẫn không thể thấy được vấn đề
Borja Alvarez

2
@BorjaAlverez Có một sự khác biệt lớn. Có, thông qua XSS, ai đó có thể thực hiện các yêu cầu thay mặt cho người dùng đã đăng nhập, nhưng việc xâm phạm mã thông báo còn tệ hơn. Ví dụ: mã thông báo có thể cung cấp quyền truy cập vào API mà ứng dụng khách không sử dụng; mã thông báo có thể có thông tin khác về người dùng (địa chỉ email, hồ sơ và các khoản trợ cấp); mã thông báo có thể được sử dụng trong các cuộc tấn công phát lại đối với ứng dụng của bạn; mã thông báo có thể được chuyển dưới dạng id_token_hintmáy chủ xác thực OIDC; mã thông báo cung cấp thông tin kẻ tấn công về mật mã được sử dụng để ký tên; v.v.
avejidah

3

Một cách để xem xét điều này là xem xét mức độ rủi ro hoặc tác hại.

Bạn đang xây dựng một ứng dụng không có người dùng, POC / MVP? Bạn có phải là một người khởi nghiệp cần tiếp cận và kiểm tra ứng dụng của bạn một cách nhanh chóng? Nếu có, tôi có lẽ sẽ chỉ thực hiện giải pháp đơn giản nhất và duy trì sự tập trung vào việc tìm kiếm sản phẩm phù hợp với thị trường. Sử dụng localStorage vì nó thường dễ thực hiện hơn.

Bạn đang xây dựng một v2 của một ứng dụng có nhiều người dùng hoạt động hàng ngày hay một ứng dụng mà mọi người / doanh nghiệp phụ thuộc rất nhiều vào. Sẽ bị hack có nghĩa là ít hoặc không có chỗ để phục hồi? Nếu vậy, tôi sẽ xem xét kỹ lưỡng các phụ thuộc của bạn và xem xét việc lưu trữ thông tin mã thông báo trong cookie chỉ có http.

Sử dụng cả localStorage và lưu trữ cookie / phiên đều có ưu và nhược điểm riêng.

Như đã nêu trong câu trả lời đầu tiên: Nếu ứng dụng của bạn có lỗ hổng XSS, thì cả hai sẽ không bảo vệ người dùng của bạn. Vì hầu hết các ứng dụng hiện đại có hàng tá phụ thuộc khác nhau, nên ngày càng khó đảm bảo rằng một trong các phụ thuộc của ứng dụng của bạn không dễ bị XSS.

Nếu ứng dụng của bạn có lỗ hổng XSS và tin tặc đã có thể khai thác nó, tin tặc sẽ có thể thực hiện các hành động thay mặt cho người dùng của bạn. Tin tặc có thể thực hiện các yêu cầu GET / POST bằng cách truy xuất mã thông báo từ localStorage hoặc có thể thực hiện các yêu cầu POST nếu mã thông báo được lưu trữ trong cookie chỉ http.

Mặt trái duy nhất của việc lưu trữ mã thông báo của bạn trong bộ nhớ cục bộ là tin tặc sẽ có thể đọc mã thông báo của bạn.


1

Không phải cookie cục bộ hoặc httpOnly không được chấp nhận? Liên quan đến thư viện bên thứ 3 bị xâm nhập, giải pháp duy nhất tôi biết là sẽ giảm / ngăn chặn thông tin nhạy cảm bị đánh cắp sẽ được thực thi toàn vẹn Subresource .

Subresource Integrity (SRI) là một tính năng bảo mật cho phép các trình duyệt xác minh rằng các tài nguyên mà họ tìm nạp (ví dụ: từ CDN) được phân phối mà không cần thao tác bất ngờ. Nó hoạt động bằng cách cho phép bạn cung cấp hàm băm mật mã mà tài nguyên tìm nạp phải khớp.

Miễn là thư viện bên thứ 3 bị xâm nhập hoạt động trên trang web của bạn, một keylogger có thể bắt đầu thu thập thông tin như tên người dùng, mật khẩu và bất cứ điều gì khác mà bạn nhập vào trang web.

Cookie httpOnly sẽ ngăn truy cập từ một máy tính khác nhưng sẽ không làm gì để ngăn chặn tin tặc thao túng máy tính của người dùng.


-10

Việc lưu trữ mã thông báo của bạn trong localStorage là an toàn miễn là bạn mã hóa nó. Dưới đây là một đoạn mã nén cho thấy một trong nhiều cách bạn có thể làm điều đó.

    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);
     }

Sau đó, trước khi sử dụng mã thông báo của bạn giải mã nó bằng cách sử dụng PRIVATE_KEY_STORED_IN_ENV_FILE


@HassanAlthaf bạn đang thiếu điểm ở đây, sẽ không bao giờ có ứng dụng bằng chứng an toàn 100%, chỉ là, bạn đang giảm bề mặt tấn công và ít nhất tệp env sẽ không được xuất bản trực tiếp trên github. Ngoài ra, mã được gói sẽ bị xáo trộn và xáo trộn, khiến những kẻ tấn công khó tìm thấy chúng.
Kidali Kevin

Khóa riêng không được tiết lộ. Bạn sẽ thỏa hiệp toàn bộ API.
Hassan Althaf

Từ kinh nghiệm của tôi Nếu bạn đã làm mọi thứ một cách thông minh và chính xác, khóa riêng của bạn sẽ không bị lộ trong bản dựng sản xuất của bạn, nếu vậy, ảnh chụp màn hình để hỗ trợ điều này hoặc thậm chí là một url.
Kidali Kevin
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.