Agent tìm được 30 lỗ hổng đã xác nhận. Dev không thể fix cả 30 cùng lúc. Câu hỏi sống còn: fix cái nào trước? Bài này xây bộ chấm điểm để xếp hạng, tránh việc "lỗ hổng nhỏ ở trang admin nội bộ" lại được ưu tiên hơn "SQLi ở endpoint đăng nhập public".
1. Bốn yếu tố quyết định độ ưu tiên
Severity thực tế ≠ chỉ loại lỗ hổng. Nó phụ thuộc:
- Impact (mức thiệt hại): SQLi rò toàn bộ DB > XSS phản chiếu ở trang lỗi.
- Exploitability (dễ khai thác): endpoint public, không cần đăng nhập > route admin sau 2 lớp xác thực.
- Exposure (mức phơi nhiễm): Internet-facing > mạng nội bộ.
- Data sensitivity (độ nhạy dữ liệu): bảng
users/payments> bảnglogs.
2. Công thức chấm điểm
priority = impact * exploitability * exposure * sensitivity * confidence
Mỗi yếu tố 1–5. Nhân với confidence (0–1) từ bước phản biện để finding chắc chắn được đẩy lên. Ví dụ trọng số gợi ý:
IMPACT = {"SQLi": 5, "IDOR": 4, "XSS": 3}
def score(f):
base = IMPACT[f["type"]]
expl = 5 if f["auth_required"] is False else 2
expo = 5 if f["internet_facing"] else 2
sens = 5 if f["touches_pii"] else 2
return base * expl * expo * sens * f["final_confidence"]
3. Cho LLM chấm các yếu tố ngữ cảnh
Các yếu tố như internet_facing, touches_pii cần hiểu ngữ cảnh — hãy để agent chấm:
Cho finding và code xung quanh, đánh giá:
- auth_required: route này có yêu cầu đăng nhập trước không? (true/false)
- internet_facing: endpoint public hay chỉ nội bộ/admin?
- touches_pii: dữ liệu liên quan có nhạy cảm (user, payment, token)?
- blast_radius: 1 bản ghi hay toàn bảng?
Trả JSON đúng các trường trên.
4. Ánh xạ điểm sang nhãn hành động
priority >= 250 -> P0: chặn merge, fix ngay
100–249 -> P1: fix trong sprint này
30–99 -> P2: đưa vào backlog
< 30 -> P3: ghi nhận, review định kỳ
Nhãn hành động quan trọng hơn con số — dev cần biết phải làm gì, không phải một số trừu tượng.
5. Ví dụ so sánh
| Finding | Loại | Auth | Public | PII | Conf | Điểm | Nhãn |
|---|---|---|---|---|---|---|---|
| Login SQLi | SQLi(5) | No(5) | Yes(5) | Yes(5) | 0.9 | 281 | P0 |
| Admin XSS | XSS(3) | Yes(2) | No(2) | No(2) | 0.8 | 19 | P3 |
| Invoice IDOR | IDOR(4) | Yes(2) | Yes(5) | Yes(5) | 0.85 | 170 | P1 |
6. Đề xuất fix kèm theo
Agent nên đính kèm bản vá gợi ý cho mỗi finding P0/P1:
Với finding CONFIRMED, đề xuất fix tối thiểu, đúng loại:
- SQLi -> prepared statement / parameter binding (code cụ thể).
- XSS -> escape đúng ngữ cảnh output.
- IDOR -> thêm kiểm tra owner == current_user trước khi trả dữ liệu.
Ưu tiên fix an toàn nhất, ít thay đổi hành vi nhất.
Khung tư duy ưu tiên
> Ưu tiên = (thiệt hại nếu bị khai thác) × (khả năng bị khai thác) × (độ tin cậy của finding). Đừng để loại lỗ hổng nghe kêu to đánh lừa; hãy để ngữ cảnh và dữ liệu quyết định.
Các bước triển khai
- Định nghĩa trọng số impact cho từng loại.
- Cho agent chấm auth/public/pii/blast_radius.
- Tính điểm, nhân confidence.
- Ánh xạ sang P0–P3.
- Đính kèm fix gợi ý cho P0/P1.
- Sắp báo cáo giảm dần theo điểm.
Checklist
- [ ] Có xét exploitability (auth/public), không chỉ loại lỗ?
- [ ] Có nhân confidence từ bước phản biện?
- [ ] Có nhãn hành động P0–P3, không chỉ con số?
- [ ] Có fix gợi ý đúng loại lỗ hổng?
Sai lầm thường gặp
- Xếp hạng chỉ theo loại: mọi SQLi thành P0 kể cả ở script nội bộ chạy tay.
- Bỏ qua confidence: đẩy finding mong manh lên đầu, gây nhiễu.
- Chỉ đưa con số: dev không biết phải hành động thế nào.
- Fix sai loại: khuyên escape HTML cho lỗi SQLi.