Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 5 — Xác thực đối kháng (adversarial verification) giảm false positive

Đã đọc 0/10 mục · còn khoảng 4 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Đây là bài quan trọng nhất. False positive (báo lỗi sai) là kẻ giết chết mọi tool bảo mật: dev nhận 50 cảnh báo, 40 cái sai, họ mất niềm tin và tắt tool. Giải pháp: sau khi "agent finder" báo lỗi, ta cho một "agent verifier" đóng vai luật sư bào chữa, cố hết sức bác bỏ finding. Chỉ finding nào sống sót qua phản biện mới được giữ.

1. Nguyên lý: tách vai Tìm và Phản biện

Dùng cùng một prompt để "tìm rồi tự kiểm" không hiệu quả — mô hình thiên vị bảo vệ kết luận của chính nó (confirmation bias). Tách thành hai lời gọi độc lập với hai vai đối lập cho kết quả khách quan hơn nhiều:

  • Finder: "tìm mọi lỗ hổng khả nghi" (recall cao, chấp nhận nhiễu).
  • Verifier: "chứng minh finding này SAI" (precision cao, cắt nhiễu).

2. Prompt phản biện

<!-- prompts/verifier.md -->
Bạn là kỹ sư bảo mật hoài nghi. Nhiệm vụ: cố BÁC BỎ finding dưới đây.
Một finding chỉ HỢP LỆ nếu tồn tại đường đi khai thác THỰC SỰ.

Hãy kiểm tra từng lý do có thể khiến finding SAI:
1. Đầu vào có thực sự do người dùng kiểm soát? (không phải hằng số)
2. Có sanitizer đúng loại ở đâu đó trên đường đi không?
3. Có middleware/guard/ACL chặn trước khi tới sink không?
4. Sink có thực sự nguy hiểm, hay chỉ là log/biến nội bộ?
5. Framework có auto-bảo vệ (auto-escape, ORM binding) không?

Trả JSON: {
  "verdict": "CONFIRMED|REJECTED|UNCERTAIN",
  "reason": "<lập luận>",
  "exploit_sketch": "<payload minh họa nếu CONFIRMED>",
  "confidence": <0..1>
}
Nếu không dựng nổi payload khai thác cụ thể -> nghiêng về REJECTED/UNCERTAIN.

Yêu cầu exploit_sketch (phác thảo payload) là bộ lọc vàng: nếu verifier không nghĩ ra nổi một payload cụ thể, khả năng cao đó là false positive.

3. Vòng lặp xác thực

def verify(finding, code_ctx):
    out = ask(VERIFIER, json.dumps(finding) + "\n\nCODE:\n" + code_ctx)
    return out

def pipeline(findings, code_ctx):
    kept = []
    for f in findings:
        v = verify(f, code_ctx)
        if v["verdict"] == "CONFIRMED" and v["confidence"] >= 0.6:
            f["exploit"] = v["exploit_sketch"]
            f["final_confidence"] = (f["confidence"] + v["confidence"]) / 2
            kept.append(f)
        # REJECTED -> loại; UNCERTAIN -> đưa vào hàng chờ review người
    return kept

4. Ví dụ verifier cứu bạn khỏi false positive

Finder báo SQLi ở:

$status = $_GET['status'];
$db->query("SELECT * FROM orders WHERE status = ?", [$status]);

Verifier phát hiện: có ? placeholder và tham số truyền qua mảng bind → prepared statement → REJECTED. Không có payload nào thoát được. Một finding sai bị chặn trước khi tới mắt dev.

5. Ba mức phán quyết và cách xử lý

  • CONFIRMED: giữ, đưa vào báo cáo, xếp severity.
  • REJECTED: loại bỏ khỏi báo cáo (nhưng log lại để audit).
  • UNCERTAIN: đưa vào hàng chờ review người — không tự chặn CI, không tự bỏ.
Mức UNCERTAIN cực kỳ quan trọng: nó thừa nhận giới hạn của agent thay vì đoán bừa.

Khung tư duy "phản biện đối kháng"

> Một finding chỉ đáng tin khi nó sống sót qua nỗ lực bác bỏ nghiêm túc. Nếu bạn không dựng được payload khai thác, đừng báo là lỗ hổng — hãy hạ xuống UNCERTAIN.

Các bước triển khai

  • Tạo prompt verifier riêng, vai "hoài nghi".
  • Bắt buộc verifier xuất verdict + exploit_sketch.
  • Chỉ giữ CONFIRMED trên ngưỡng confidence.
  • Định tuyến UNCERTAIN sang review người.
  • Log REJECTED để đo tỷ lệ và tinh chỉnh finder.
  • Đo lại false positive rate trước/sau khi thêm verifier.

Checklist

  • [ ] Finder và Verifier là hai lời gọi tách biệt?
  • [ ] Verifier được yêu cầu BÁC BỎ, không phải xác nhận?
  • [ ] Có bắt buộc phác thảo payload khai thác?
  • [ ] UNCERTAIN được định tuyến sang người, không tự bỏ?
  • [ ] Có đo FP rate trước/sau?

Sai lầm thường gặp

  • Gộp tìm và kiểm vào một prompt: confirmation bias, không giảm được FP.
  • Verifier vai trung lập: phải là "luật sư bào chữa" mới cắt nhiễu mạnh.
  • Vứt luôn UNCERTAIN: bỏ sót lỗi thật (false negative). Đưa cho người.
  • Không log REJECTED: mất dữ liệu để cải thiện finder.
Bài sau: chấm severity và ưu tiên fix theo rủi ro thực tế.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi