Chúng ta cần lưu trữ JWT trên máy khách. Nếu chúng ta lưu trữ nó trong LocalStorage / SessionStorage thì nó có thể dễ dàng bị bắt bởi một cuộc tấn công XSS. Nếu chúng tôi lưu trữ nó trong cookie thì tin tặc có thể sử dụng nó (mà không cần đọc) trong một cuộc tấn công CSRF và mạo danh người dùng và liên hệ với API của chúng tôi và gửi yêu cầu thực hiện hành động hoặc lấy thông tin thay mặt cho người dùng.
Nhưng có một số cách để bảo mật JWT trong cookie để không bị đánh cắp dễ dàng (nhưng vẫn có một số kỹ thuật tiên tiến để đánh cắp chúng). Nhưng nếu bạn muốn dựa vào LocalStorage / SessionStorage, thì nó có thể được truy cập bằng một cuộc tấn công XSS đơn giản.
Vì vậy, để giải quyết vấn đề CSRF, tôi sử dụng Double Gửi Cookies trong ứng dụng của mình.
Phương pháp gửi đôi
Lưu trữ JWT trong cookie httpOnly và sử dụng nó trong chế độ bảo mật để chuyển qua HTTPS.
Hầu hết các cuộc tấn công CSRF có tiêu đề nguồn gốc hoặc người giới thiệu khác với máy chủ ban đầu của bạn trong các yêu cầu của họ. Vì vậy, hãy kiểm tra xem bạn có bất kỳ ai trong số họ trong tiêu đề không, họ có đến từ miền của bạn hay không! Nếu không từ chối họ. Nếu cả nguồn gốc và người giới thiệu đều không có sẵn trong yêu cầu thì không phải lo lắng. Bạn có thể dựa vào kết quả xác thực tiêu đề X-XSRF-TOKEN mà tôi giải thích trong bước tiếp theo.
Mặc dù trình duyệt sẽ tự động cung cấp cookie của bạn cho miền yêu cầu, nhưng có một hạn chế hữu ích: mã JavaScript đang chạy trên trang web không thể đọc cookie của các trang web khác. Chúng ta có thể tận dụng điều này để tạo ra giải pháp CSRF của mình. Để ngăn chặn các cuộc tấn công CSRF, chúng tôi phải tạo một cookie có thể đọc thêm Javascript được gọi là: XSRF-TOKEN. Cookie này phải được tạo khi người dùng đăng nhập và phải chứa một chuỗi ngẫu nhiên, không thể đoán được. Chúng tôi cũng lưu số này trong chính JWT như một yêu cầu riêng. Mỗi khi ứng dụng JavaScript muốn thực hiện một yêu cầu, nó sẽ cần đọc mã thông báo này và gửi nó trong một tiêu đề HTTP tùy chỉnh. Bởi vì các thao tác này (đọc cookie, đặt tiêu đề) chỉ có thể được thực hiện trên cùng một miền của ứng dụng JavaScript,
Angular JS làm cho cuộc sống của bạn dễ dàng
May mắn thay, tôi đang sử dụng Angular JS trong nền tảng của chúng tôi và các gói Angular tiếp cận mã thông báo CSRF, giúp chúng tôi thực hiện đơn giản hơn. Đối với mọi yêu cầu mà ứng dụng Angular của chúng tôi thực hiện đối với máy chủ, $http
dịch vụ Angular sẽ tự động thực hiện những việc này:
- Hãy tìm một cookie có tên XSRF-TOKEN trên tên miền hiện tại.
- Nếu cookie đó được tìm thấy, nó sẽ đọc giá trị và thêm nó vào yêu cầu dưới dạng tiêu đề X-XSRF-TOKEN.
Do đó, việc thực hiện phía máy khách được xử lý cho bạn, tự động! Chúng ta chỉ cần đặt một cookie có tên XSRF-TOKEN
trên miền hiện tại ở phía máy chủ và khi API của chúng tôi nhận được bất kỳ cuộc gọi nào từ máy khách, nó phải kiểm tra X-XSRF-TOKEN
tiêu đề và so sánh nó với XSRF-TOKEN
JWT. Nếu chúng phù hợp, thì người dùng là có thật. Mặt khác, đó là một yêu cầu giả mạo và bạn có thể bỏ qua nó. Phương pháp này được lấy cảm hứng từ phương pháp "Double Gửi Cookie".
Thận trọng
Trên thực tế, bạn vẫn dễ bị 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ể yêu cầu thay mặt người dùng của bạn bằng XSS.
Cho dù bạn lưu trữ JWT của mình trong localStorage
hoặc bạn lưu mã thông báo XSRF của bạn trong cookie không phải là HTTPOnly, cả hai đều có thể được XSS lấy một cách dễ dàng. Ngay cả JWT của bạn trong cookie HTTPOnly cũng có thể bị bắt bởi một cuộc tấn công XSS nâng cao như phương pháp XST .
Vì vậy, ngoài phương pháp Double Gửi Cookies, bạn phải luôn tuân theo các thực tiễn tốt nhất chống lại XSS bao gồm cả thoát nội dung. Đ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à loại bỏ // <![CDATA[
các thẻ và thuộc tính HTML khiến JavaScript được đánh giá.
Đọc thêm tại đây: