Frontend HTML/CSS

Lưu trữ JWT thế nào cho an toàn?

5.261 lượt xem - Thời gian đọc: 5 phút đọc

Lưu trữ JWT thế nào cho an toàn?

Trong những năm gần đây, JWT đã được sử dụng rộng rãi như một phương pháp xác thực và uỷ quyền sử dụng trong các ứng dụng web/app. Chúng cho phép backend có thể xác minh được người dùng mà không cần thực hiện đến cơ sở dữ liệu hoặc bất kỳ loại lưu trữ nào khác. Dễ sử dụng và chúng cũng sử dụng các định dạng phổ biến nhất hiện nay được sử dụng cho dữ liệu trên mạng. Đó là JSON.

Nhưng trên thực tế, ngày càng có nhiều trường hợp người dùng lưu trữ mã xác thực JWT sai cách, khiến các ứng dụng web dễ bị tấn công bởi các loại tấn công khác nhau.

JWT Token là cái gì ?

JWT là viết tắt của JSON Web Tokens. JWT không khác gì so với đại diện mã hoá base64. Bằng cách signing token, chúng đảm bảo rằng nội dung, dữ liệu được mã hoá không bị thay đổi theo bất kỳ cách nào sau quá trình đó. Thực hiện điều này bằng cách xác minh secret key, và loại hình mã hoá cung cấp ban đầu. Trong trường hợp signature mà chúng ta cung cấp không khớp với thông tin mã xác minh đã tạo, chúng sẽ được xem như không hợp lệ'

Mã xác thực JWT gồm có ba phần, tất cả đều dưới dạng base64:

headerpayload được lưu trự ở dạng JSON trước khi sign. Mã xác thực cuối cùng là sự kết hợp của 2 đối tượng trên dưới dạng base64, được phân tách với nhau bằng dấu chấm. Vì vậy, mã xác thực JWT sẽ có dạng:

header.payload.signature

Có nên lưu trữ JWT ở LocalStorage?

Rất nhiều người thường có xu hướng lưu trữ mã xác thực JWT của họ ở LocalStorage trên trình duyệt (browser). Đây là nơi dễ bị tấn công bởi các cuộc tấn công XSS. Chúng ta sẽ chỉ thảo luận về XSS trong ngữ cảnh JWT, bạn có thể tìm hiểu thông tin đó tại đây. Trong kiểu tấn công này, kế tấn công sẽ lợi dụng thực tế là mã xác thực được lưu trữ tại LocalStorage có thể được truy cập bằng bất kỳ mã javascript nào chạy trên cùng một tên miền mà các ứng dụng web lưu trữ.

Nếu kẻ tấn công có thể tìm cách đưa đoạn mã độc hại vào bên trong ứng dụng mà bạn đang truy cập, bạn sẽ là nạn nhân trong việc bị khai thác mã xác thực và sử dụng chúng để làm phương tiện lấy thông tin dữ liệu của bạn và nặng hơn là có thể truy vấn toàn bộ hệ thống nếu tài khoản thuộc quyền hạn cao cấp.

Vì vậy, để trả lời cho câu hỏi này, thì đừng, đừng nên lưu trữ JWT trong LocalStorage.

Vậy còn SessionStorage?

Chúng ta cùng xem có vấn đề gì trong trường hợp này không!.

Giống LocalStorage, SessionStorage được truy cập bởi bất kì mã JavaScript nào được chạy trên cùng một domain của ứng dụng đó. Vì vậy, điều duy nhất thay đổi ở đây là, khi người dùng tắt trình duyệt, mã JWT cũng sẽ bị xoá và người dùng phải đăng nhập lại sau đó để tiếp tục sử dụng ứng dụng web/app của bạn.

Như LocalStorage, không nên lưu trữ JWT trong SessionStorage.

Sử dụng Cookies?

Từ nhiều lập trình viên, chuyên gia có tay nghề. Họ vẫn khuyên chúng ta sử dụng Cookie mặc dù nó đã sinh ra được khá lâu, nhưng vẫn cực kì bảo mật.

Nhưng cookie cũng có thể truy cập được thông qua javascript.

Điều này đúng, nhưng chỉ khi máy chũ không đặt httpOnly cho một gì đó bạn phải luôn đặt cho cookie xác thực hoặc uỷ quyền.

Điều gì sẽ xảy ra nếu ai đó gửi chúng thông qua một yêu cầu HTTP không an toàn?

Trước hết, ngày nay, ít ai sử dụng HTTP, ngay cả theo cách này, chúng ta có thể đặt cờ bảo mật khi tạo cookie, vì vậy nó sẽ không bao giờ được gửi qua một kết nối không an toàn.

Bạn có đang quên tấn công CSRF

Khoan đã, nhưng CSRF Attack là gì ?

Một cuộc tấn công CSRF được thực hiện khi kẻ tấn công lợi dụng hành vi mặc định của trình duyệt, để gửi tất cả cookie ngay cả trên các yêu cầu từ tên miền chéo. Điều này có thể dẫn đến các lỗ hỏng bảo mật lớn nếu không được xử lý đúng cách. Một ví dụ về cuộc tấn công này như sau

Nhẹ nhàng, người dùng không thể đăng nhập vào tài khoản của họ nữa nếu kẻ tấn công chỉ muốn phơi bày kỹ năng. Nhưng các hoạt động nghiêm trọng hơn có thể được thực hiện như yêu cầu người dùng nâng cấp dịch vụ, yêu cầu chuyển khoản của họ sang tài khoản giả mạo của kẻ thù. Thay vì của bạn.

Vậy chúng ta phải làm gì?

Bạn có thể sử dụng mã JWT được tạo từ phần phụ trợ trong mọi yêu cầu mà bạn thực hiện với máy chủ (thường với bất kỳ yêu cầu nào từ POST, PUT, PATCH, DELETE. Vì vậy, khi người dùng thực hiện yêu cầu chúng ta có thể kiểm tra nếu mã đó hợp lệ hay không bằng cách tìm nạp nó từ một số bộ nhớ cache hoặc thâm5 chí trực tiếp từ cơ sở dữ liệu. Nhưng điều này đòi hỏi bạn phải tạo một mã JWT mới mổi khi người dùng chuyển hướng tới một trang mới. Vậy, giải pháp thay thế nó là gì ?

Trong nhiều năm nay, thật không may, cách duy nhất để giữ an toàn là sử dụng mã xác thực CSRF khi sử dụng xác thực dựa trên cookie. Từ năm 2016, các trình duyệt hiện đại bắt đầu triển khai chính sách cookie được gọi là SameSite. SameSite có thể nhận một trong 3 giá trị.

Lax là gì ?

Lax cho phép gửi cookie trong các yêu cầu tên miền chéo từ yêu cầu là GET. Tất cả các yêu cầu khác sẽ không chứa cookie với chính sách Lax SameSite. Bằng cách này, nó cho phép cookie được sử dụng khi, ví dụ trường hợp chuyển hướng người dùng từ email đến màn hình trang tổng quan của ứng dụng, nhưng không cho phép một biểu mẫu độc hại chèn mã độc hại lên điểm cuối.

Chúng ta phải đề cập rằng Lax hoạt động cho tất cả các yêu chuyển hướng. Nó sẽ không gửi cookie theo yêu cầu ajax. Vì vậy, không ai có thể thêm một số mã vào web của họ và đặt yêu cầu điểm đến để khai thác dữ liệu cá nhân của người dùng đã đăng nhập. Nó cũng sẽ bị bỏ qua trong trường hợp iframe, ngay cả đối với các yêu cầu chưởng hướng.

Vì vậy, các cách thông thường nhất mà cookie Lax được gửi từ một yêu cầu GET trên nhiều miền như sau.

Giờ đây, chính xác SameSite strict sẽ không cho phép cookie được chuyển qua các yêu cầu từ tên miền chéo theo bất kỳ cách nào. Điều này có thể hữu ích trong một số trường hợp phức tạp, nhưgn bạn phải hiểu rằng ngay cả một chuyển hướng liên kết đơn giản cũng sẽ khiến người dùng đăng xuất khỏi web của bạn nếu bạn sử dụng chính sách này. Tất nhiên, đó là cách an toàn nhất.

Có thể bạn sẽ cần !

Bài viết liên quan