Danh mục kiểm tra bảo mật
Tám mục cần kiểm tra trước khi phát hành — vì sao cần và điều gì xảy ra nếu bỏ qua.
Hãy xem qua danh sách này trước khi phát hành. Mỗi mục đều nêu kèm vì sao cần thiết và điều gì xảy ra nếu bỏ qua.
1. Chỉ để client_secret ở máy chủ
Vì sao — secret là giá trị duy nhất chứng minh «yêu cầu này thực sự đến từ dịch vụ đó».
Nếu bỏ qua — nếu đặt vào JS giao diện hoặc gói ứng dụng di động, bất kỳ ai cũng lấy ra xem được, và người khác có thể giả danh dịch vụ của bạn để xin cấp token.
Việc đổi token (POST /oauth/token) bắt buộc thực hiện trên máy chủ.
Đừng commit vào kho mã nguồn; hãy đặt trong biến môi trường (environment variable) hoặc kho lưu trữ bí mật (secret store).
2. Tạo state và luôn đối chiếu khi nhận lại
Vì sao — để chặn kiểu tấn công (CSRF khi đăng nhập) trong đó kẻ tấn công đưa authorization code của chính mình vào trình duyệt nạn nhân để liên kết tài khoản của kẻ tấn công vào tài khoản của nạn nhân.
Nếu bỏ qua — người dùng có thể vô tình bị đăng nhập vào tài khoản của kẻ tấn công, hoặc ngược lại.
Tài khoản 놀아 yêu cầu state là bắt buộc. Nhưng việc kiểm tra giá trị nhận lại là trách nhiệm của dịch vụ.
Chỉ gửi mà không kiểm tra thì không có ý nghĩa gì.
if (!hash_equals($_SESSION['nolaa_state'] ?? '', $_GET['state'] ?? '')) {
// Dừng lại. Đừng chuyển sang bước đổi token
}
3. Lưu code_verifier của PKCE trong phiên
Vì sao — ngay cả khi authorization code bị chặn giữa đường, nếu không biết code_verifier thì không đổi được thành token.
Nếu bỏ qua — nếu mang nó theo trong cookie hoặc tham số URL, PKCE mất hết ý nghĩa.
Tài khoản 놀아 bắt buộc PKCE và chỉ chấp nhận S256.
Hãy tạo code_verifier mới cho mỗi yêu cầu, lưu vào phiên trên máy chủ, và xóa đi sau khi dùng một lần.
4. Chỉ dùng redirect_uri đúng như giá trị đã đăng ký
Vì sao — đây là địa chỉ mà authorization code sẽ được gửi tới. Nếu kiểm tra này lỏng lẻo, code sẽ đi nhầm chỗ.
Nếu bỏ qua — Tài khoản 놀아 từ chối mọi giá trị không hoàn toàn khớp với giá trị đã đăng ký, nên đăng nhập sẽ không thực hiện được. (Cách này an toàn hơn là mở lỏng.)
Đừng ghép redirect_uri từ dữ liệu người dùng nhập. Hãy cố định nó thành hằng số.
5. Lưu token ở máy chủ, không đưa xuống trình duyệt
Vì sao — bản thân access_token là chìa khóa để đọc thông tin người dùng.
Nếu bỏ qua — nếu để trong localStorage, chỉ một lỗ hổng XSS (tấn công chèn mã script xuyên trang) là mất hết.
Hãy giữ trong phiên trên máy chủ, và chỉ gửi xuống trình duyệt cookie phiên của dịch vụ bạn.
Hãy đặt HttpOnly, Secure và SameSite cho cookie.
6. Dùng HTTPS trên toàn bộ đường truyền
Vì sao — authorization code và token sẽ đi qua lại dưới dạng văn bản thuần.
Nếu bỏ qua — bất kỳ ai trong cùng mạng đều có thể chặn lấy.
Cả URL dịch vụ và callback URL đều phải bắt đầu bằng https://.
7. Khi nhận 401, lặng lẽ đăng xuất
Vì sao — Tài khoản 놀아 không có điểm cuối revoke công khai, nên
cách duy nhất để dịch vụ biết người dùng đã dọn dẹp kết nối là 401 invalid_token.
Nếu bỏ qua — dịch vụ sẽ tiếp tục gửi yêu cầu qua một kết nối đã ngắt và hiện ra màn hình lỗi.
Khi nhận invalid_token, hãy xóa token đã lưu và đưa người dùng về màn hình đăng nhập.
8. Chỉ yêu cầu scope cần thiết
Vì sao — các scope đã yêu cầu được hiển thị nguyên vẹn ở màn hình đồng ý.
Nếu bỏ qua — nếu xin cả thông tin không dùng tới, màn hình đồng ý sẽ dài ra và người dùng bỏ dở. Hơn nữa, thông tin đã nhận kéo theo trách nhiệm lưu giữ.
Kiểm tra lần cuối trước khi phát hành
- Trong kho mã nguồn và mã giao diện có hoàn toàn không có client_secret không
- Có đang kiểm tra state không (chứ không chỉ gửi)
- code_verifier có nằm trong phiên trên máy chủ không
- redirect_uri có được cố định thành hằng số không
- Token có được giữ kín, không lộ ra trình duyệt không
- Callback có dùng HTTPS không
- Có xử lý khi nhận 401 không