Endpoint mà UI không hiện
BOLA (API1) là "được đọc bản ghi này không". BFLA (API5) là "được gọi hàm này không" — và nó là lỗi dễ bỏ sót hơn, vì nó thường nằm ở endpoint mà giao diện chưa bao giờ gọi tới.
Cơ chế điển hình, và nó lặp lại ở mọi sản phẩm:
- Có một endpoint
DELETE /api/users/{id}cho trang quản trị. - UI chỉ hiện nút Delete khi người dùng có vai admin. Về mặt sản phẩm, thế là xong.
- Không ai kiểm endpoint đó, vì "không ai gọi được nó".
- Swagger ở production liệt kê nó, kèm cả schema.
Điểm cần nói thẳng: UI không phải một biện pháp bảo mật. Nó là một gợi ý về ý định. Không hiện nút không ngăn được một request; nó chỉ ngăn một người dùng tình cờ gửi request đó.
Ba biến thể hay gặp, xếp theo thứ tự tôi thấy nhiều nhất trong code thật:
| Biến thể | Trông như thế nào | Vì sao nó lọt qua review |
|---|---|---|
| Endpoint "nội bộ" | /api/internal/reindex, không attribute nào | Chữ "internal" trong đường dẫn tạo cảm giác đã được bảo vệ |
| Method mới trên controller cũ | Controller có [Authorize(Roles="Admin")] ở class, một action mới thêm [AllowAnonymous] để test rồi quên bỏ | Diff chỉ một dòng và nó nằm ở dòng cuối |
| HTTP method chưa được nghĩ tới | GET /api/reports/{id} có kiểm quyền, DELETE cùng route thì không | Review đọc theo route, không theo cặp route × method |
Vì sao đếm bằng mắt không đủ: một API cỡ trung có 200–400 cặp route × method. Con người đọc hết một lần thì bỏ sót, và đọc lại mỗi sprint thì không ai làm. Cách duy nhất bền là mặc định từ chối — xem bước vá.
Bình luận
Bình luận cần tài khoản đã hoàn thành ít nhất một bài học. Điều kiện đó là thứ giữ cho luồng thảo luận này còn đáng đọc: mỗi ý kiến gắn với một người có thể bị hỏi lại, và reputation tích luỹ theo thời gian.
Bạn vẫn đọc được toàn bộ bình luận dưới đây mà không cần tài khoản. Đăng nhập xong bạn sẽ quay lại đúng chỗ này, không phải đầu trang.
Đang tải bình luận…