PKCE trong OAuth 2.0
Chuyện là mình vừa được phỏng vấn 1 câu về security trong OAuth, làm thế nào để bảo mật client secret trong các ứng dụng SPAs? Nên là mình đã note lại những gì mình tìm hiểu được.
Vấn đề của Public Clients
Như chúng ta đã biết trong OAuth 2.0, sẽ có 4 thành phần chính bao gồm Client, Resource Server, Resource Owner, Authorization Server. Nôm na thì Client chính là ứng dụng của chúng ta, còn 3 ông còn lại thuộc về OAuth Provider (như Google, Facebook, …).
Bạn vào các trang web có nút Login with Google hoặc Login with Facebook, thì đó chính là OAuth.
Sau đây là ví dụ về flow Login with Google với ứng dụng Pinterest:
Ở bước số 3, để mà exchange được cái access_token, thì cần phải có 1 thứ đó là client secret (cái này do Resource Owner quản lý), và câu hỏi là lưu trữ cái client secret đó ở đâu là tốt nhất?
Hầu hết các ứng dụng hiện nay đều tách thành hai phần: front-end và back-end. Trong OAuth, front-end được gọi là Public Client và back-end được gọi là Confidential Client.
Và lẽ thông thường chúng ta sẽ lưu trữ các cái client secret ở phía back-end sẽ là an toàn và bảo mật nhất.
Nhưng nếu ứng dụng không có back-end thì sao? Chẳng hạn như các ứng dụng SPAs, mobile, hoặc browser extensions, …
Liệu có thể lưu client secret ở front-end không?
Câu trả lời ngắn gọn là không, vì code trên front-end (e.g. trình duyệt, mobile, …) rất dễ bị reverse-engineered, hoặc bị leak data trong local storage/shared preferences, dẫn đến client secret có nguy cơ bị đánh cắp.
Vậy nếu không lưu ở back-end hay front-end thì lưu ở đâu?
Không lưu ở đâu cả, mà thay vào đó sử dụng một giải pháp khác mang tên PKCE (đọc là ‘pixy’).
PKCE (Proof key of Code Exchange)
Thay vì sử dụng client secret thì PKCE sẽ sử dụng 2 yếu tố sau:
-
code verifier là 1 chuỗi ngẫu nhiên được generate bởi Client trước khi bắt đầu OAuth Flow.
-
code challenge là phiên bản băm của code verifier và phương thức băm thường được dùng là SHA256
Khi bắt đầu flow, Client sẽ gửi code challenge kèm theo phương thức băm (e.g. SHA256, …) đến Authorization Server, và khi đến bước exchange authorization code để lấy access_token thì Client sẽ gửi thêm code verifier. Lúc này, Authorization Server sẽ verify code verifier với code challenge đã nhận ở step trước, nếu hợp lệ thì trả về access_token.
PKCE cực kỳ hiệu quả trong việc ngăn chặn các cuộc tấn công đánh chặn authorization code vì kẻ tấn công không thể sử dụng authorization code để lấy access_token nếu không có code verifier.
Hơn nữa, code verifier được lưu trên memory của thiết bị nên rất khó để bị đánh cắp.
Với những lợi ích trên, PKCE là một giải pháp quan trọng để bảo vệ ứng dụng của bạn. Và trên đây là những gì mình tìm hiểu về PKCE. Các bạn có thắc mắc hay góp ý, cứ để lại bình luận bên dưới để cùng trao đổi nhé!
All rights reserved