Xác thực dựa trên mã thông báo bằng cách sử dụng quyền truy cập và làm mới mã thông báo


8

Tôi đang triển khai hệ thống xác thực dựa trên mã thông báo cho API REST bằng cách sử dụng mã thông báo truy cập ngắn hạn và mã thông báo làm mới tồn tại lâu. Đây là tổng quan trừu tượng về các điểm cuối API có liên quan (HTTPS được thi hành cho tất cả các điểm cuối):

Điểm cuối:

POST /register/
POST /login/
POST /logout/
POST /password/change/

Thực hiện:

POST /register/:

  • Yêu cầu: Khách hàng gửi tên người dùng, email và mật khẩu trong JSON.
  • Hành động của máy chủ:
    1. Xác thực đầu vào, tạo người dùng trong cơ sở dữ liệu (lưu trữ id người dùng, tên người dùng, email và mật khẩu băm).
    2. Tạo mã thông báo truy cập ngắn hạn ở định dạng JWT (chứa id người dùng, ngày phát hành và ngày hết hạn).
    3. Tạo mã thông báo làm mới tồn tại lâu dưới dạng chuỗi UUID và lưu trữ nó trong cơ sở dữ liệu (lưu trữ mã người dùng và mã thông báo làm mới).
  • Trả lời: Máy chủ trả về mã thông báo truy cập và làm mới mã thông báo trong JSON.

POST /login/:

  • Yêu cầu: Khách hàng gửi tên người dùng và mật khẩu trong JSON.
  • Hành động của máy chủ:
    1. Xác thực đầu vào, kiểm tra nếu thông tin đăng nhập hợp lệ bằng cách kiểm tra cơ sở dữ liệu.
    2. Nếu thông tin đăng nhập hợp lệ, hãy tạo mã thông báo truy cập ngắn hạn và mã thông báo làm mới tồn tại lâu như đã đề cập trước đó.
  • Trả lời: Tương tự như /register/, trả về mã thông báo truy cập và mã thông báo làm mới trong JSON.

POST /logout/:

  • Yêu cầu: Khách hàng gửi mã thông báo làm mới trong Authorizationtiêu đề dưới dạng Bearermã thông báo.
  • Hành động của máy chủ:
    1. Xác thực mã thông báo làm mới bằng cách kiểm tra cơ sở dữ liệu mã thông báo làm mới.
    2. Xóa mã thông báo làm mới khỏi cơ sở dữ liệu.
      Lưu ý: Điều này để mã thông báo truy cập hợp lệ, nhưng vì nó sẽ tồn tại trong thời gian ngắn (1 giờ hoặc lâu hơn, tôi nghĩ rằng nó sẽ ổn).
  • Trả lời: Trả về việc yêu cầu đăng xuất đã được xử lý thành công trong JSON.

POST /password/change/:

  • Yêu cầu: Khách hàng gửi mã thông báo truy cập trong Authorizationtiêu đề dưới dạng Bearermã thông báo và cũng gửi mật khẩu cũ và mật khẩu mới trong JSON thông qua HTTPS.
  • Hành động của máy chủ:
    1. Giải mã mã thông báo truy cập để truy xuất người dùng và kiểm tra mật khẩu cũ của người dùng với cơ sở dữ liệu.
    2. Đặt băm mật khẩu của người dùng trong cơ sở dữ liệu thành băm mật khẩu mới.
    3. Xóa tất cả các mã thông báo làm mới được liên kết với người dùng trong cơ sở dữ liệu mã thông báo làm mới để cơ bản đăng xuất các phiên hiện có (để lại các mã thông báo truy cập ngắn hạn hợp lệ).
  • Trả lời: Trả về việc yêu cầu thay đổi mật khẩu đã được xử lý thành công trong JSON.

Câu hỏi:

  1. Cách tiếp cận này có an toàn không? Đặc biệt:
    • Việc gửi tên người dùng và mật khẩu qua JSON có an toàn không nếu được thực hiện qua HTTPS? Làm cách nào để ngăn chặn các tên miền trái phép thực hiện cuộc gọi đến điểm cuối này? Hơn nữa, làm thế nào tôi có thể ngăn chặn đăng nhập theo chương trình?
    • Các mã thông báo làm mới có nên được băm trước khi lưu trữ chúng trong cơ sở dữ liệu hay tôi chỉ bị hoang tưởng?
  2. Nếu ứng dụng khách là trình duyệt web, làm cách nào tôi có thể lưu trữ mã thông báo làm mới trên máy khách một cách an toàn?
    • Một ý tưởng tôi có để lưu trữ mã thông báo làm mới là: khi người dùng đăng nhập, ngoài việc gửi mã thông báo làm mới cho khách hàng, máy chủ lưu trữ mã thông báo trong HttpOnlycookie có securecờ. Việc ủy ​​quyền vẫn sẽ được thực hiện thông qua Authorizationtiêu đề, nhưng khi máy khách ban đầu tải lên, nó có thể gửi GETyêu cầu đến điểm cuối để kiểm tra xem cookie có chứa mã thông báo làm mới hợp lệ hay không, và nếu vậy, hãy trả lại cho người dùng trong JSON. Nói cách khác, lần duy nhất cookie thực sự sẽ được sử dụng là trả lại mã thông báo làm mới bên trong cookie cho khách hàng. Cách tiếp cận này có an toàn không? Tôi nghĩ rằng nó sẽ ngăn CSRF vì không có tác dụng phụ khi yêu cầu mã thông báo làm mới từ cookie, nhưng có cách nào khác để kẻ tấn công có thể chặn mã thông báo làm mới (giả sử HTTPS) không?

2
Tại sao không sử dụng Open ID Connect thay vì cố gắng thực hiện cơ chế bảo mật đăng nhập của riêng bạn?
Erik Eidt

Tôi không muốn phải xử lý một máy chủ bổ sung để hoạt động như nhà cung cấp kết nối OpenID. Ngoài ra, tôi muốn có toàn quyền kiểm soát luồng xác thực để tôi có thể dễ dàng xác định các lỗi và lỗ hổng bảo mật.
Kootling

2
Tôi không nghĩ rằng cần một máy chủ bổ sung nếu bạn chỉ sử dụng nó. Ngoài ra, thực hiện việc thực hiện của riêng bạn với giao thức của riêng bạn có những rủi ro bảo mật riêng có thể nhiều hơn so với sử dụng phương pháp tiêu chuẩn mới nổi, nhưng ai biết chắc chắn?
Erik Eidt

Câu trả lời:


2

Cách tiếp cận này có an toàn không? Đặc biệt:

  • Việc gửi tên người dùng và mật khẩu qua JSON có an toàn không nếu được thực hiện qua HTTPS?

Đúng. Các tiêu đề, thông số yêu cầu và phần yêu cầu được mã hóa trong quá trình giao tiếp.

Khi ở phía máy chủ, không đăng nhập phần yêu cầu :-)

  • Làm cách nào để ngăn chặn các tên miền trái phép thực hiện cuộc gọi đến điểm cuối này?

Bạn không thể. Về cơ bản, một khi API có trên WWW, nó sẽ tự động tiếp xúc với tất cả các loại ác ý. Điều tốt nhất bạn có thể làm là chuẩn bị và nhận thức được các mối đe dọa. Ít nhất là về những người quan tâm đến bạn. Hãy nhìn vào đây .

Cách tiếp cận khả thi cho vấn đề có thể là triển khai (hoặc ký hợp đồng) Trình quản lý API .

Người quản lý API tại chỗ có thể giảm bề mặt tấn công vì tất cả các điểm cuối phía sau AM không nhất thiết phải công khai.

Bạn có thể đạt được kết quả tương tự với một số sản phẩm trong đám mây, nhưng chúng đắt một cách vô lý cho dòng chính.

Dù sao, các điểm cuối Quản lý API sẽ vẫn tiếp xúc với các cuộc tấn công.

  • Hơn nữa, làm thế nào tôi có thể ngăn chặn đăng nhập theo chương trình?

Nếu theo thông tin đăng nhập theo chương trình, bạn có nghĩa là các cuộc tấn công bằng vũ lực, thì một ngưỡng (số lượng yêu cầu tối đa được phép mỗi giây) và một danh sách đen sẽ đủ để ngăn chặn sự khăng khăng của kẻ tấn công. Để biết thêm thông tin, hãy xem ở đây .

Nhiều người quản lý API cung cấp các cấu hình và danh sách trắng giới hạn tỷ lệ API .

Nếu bạn quen thuộc với Bảng điều khiển API của Google, thì bạn có thể đoán Trình quản lý API có thể làm gì.

  • Các mã thông báo làm mới có nên được băm trước khi lưu trữ chúng trong cơ sở dữ liệu hay tôi chỉ bị hoang tưởng?

Cho dù mã thông báo làm mới là UUID đơn giản hay bất cứ thứ gì khác, tôi không muốn tiết lộ loại chi tiết triển khai này. Vì vậy, tôi sẽ đề nghị để băm nó. Đối với tôi, các chi tiết triển khai của lớp bảo mật càng mờ thì càng tốt.

Về bảo mật JWT, hãy xem ở đây .

  • Nếu ứng dụng khách là trình duyệt web, làm cách nào tôi có thể lưu trữ mã thông báo làm mới trên máy khách một cách an toàn?

Bạn có thể quan tâm đến Mã thông báo Web JSON (JWT) - Lưu trữ ở phía máy khách .


Về thông tin đăng nhập theo chương trình, tôi muốn ngăn người khác tự tạo giao diện người dùng cho API (mặc dù như bạn đã nói điều này thực tế là không thể). Ngoài ra, các mã thông báo làm mới (là UUID, không phải JWT) hiện đang được lưu trữ dưới dạng văn bản gốc trong cơ sở dữ liệu, vì vậy tôi chắc chắn nên băm chúng, phải không? Về lưu trữ mã thông báo phía máy khách, tôi muốn lưu trữ mã thông báo làm mới và duy trì chúng qua các phiên, vì vậy sessionStoragesẽ không hoạt động. Ngoài ra, localStoragedocument.cookiecó vẻ không an toàn vì chúng có thể được truy cập bằng JavaScript. Liệu cách tiếp cận của tôi có ý nghĩa, hoặc nó có khả năng không an toàn?
Kootling

1. Có, tôi sẽ lưu trữ mã thông báo băm thay vì văn bản thuần túy. Chỉ để làm cho nội dung của bảng mờ đục cho các quy trình khác. 2. Nếu tôi phải chọn giữa localStorage và cookie, tôi chọn cookie. Tuy nhiên, trước tiên tôi sẽ thực hiện một nghiên cứu nhỏ về các lỗ hổng của nó. Ngoài ra, hãy xem xét thêm vào bảo mật một cơ chế để vô hiệu hóa mã thông báo theo cách thủ công.
Laiv

Theo "cookie", bạn có nghĩa là document.cookiehoặc một cookie HTTPOnly có cờ bảo mật, tương tự như cách tiếp cận tôi đã đề cập ở trên?
Kootling

Cờ an toàn và an toàn không ngăn bạn khỏi XST và XSRF. Nhưng nó làm cho cookie an toàn trước các cuộc tấn công XSS, mà tôi coi là một cơ bản. Vì vậy, Có, httpOnly và cờ an toàn. Chỉ cần nhớ rằng bạn sẽ không có quyền truy cập vào cookie từ Javascript
Laiv

Dù sao, tôi khuyến khích bạn kiểm tra các dự án OWASP khác nhau liên quan đến các ứng dụng Web, API, REST và JWT. Bạn sẽ tìm thấy nhiều thông tin hơn nhiều so với thông tin tôi có thể cung cấp cho bạn ở đây.
Laiv
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.