Product Management
Đăng nhập
ESC

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

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

Bài 1 — SAST bằng LLM là gì và tại sao dùng agent

Đã đọc 0/7 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.

SAST (Static Application Security Testing) là kỹ thuật soi mã nguồn mà không chạy chương trình để tìm lỗ hổng. Các công cụ SAST truyền thống (Semgrep, CodeQL, SonarQube) dựa trên rule và pattern matching: bạn viết luật, nó khớp. Điểm mạnh là nhanh, xác định (deterministic), chạy trong CI. Điểm yếu là chúng không hiểu ngữ cảnh: một hàm tên escape() do dev tự viết nhưng escape sai, rule vẫn coi là an toàn; hoặc một luồng dữ liệu người dùng đi qua 5 file rồi mới tới câu SQL — rule khó bắt được taint xuyên tầng.

LLM lấp đúng khoảng trống đó: nó đọc code như một senior reviewer, hiểu luồng dữ liệu, đoán được ý định của hàm, và giải thích lỗ hổng bằng ngôn ngữ tự nhiên. Nhưng LLM một mình thì bịa (hallucinate), báo lỗi không tồn tại, và không nhất quán. Vì vậy ta không gọi LLM một lần rồi tin — ta xây một agent: một vòng lặp có công cụ (tools), có bộ nhớ ngữ cảnh, có bước tự kiểm chứng.

Vì sao là "agent", không phải một prompt

Một prompt đơn lẻ giống như hỏi một người chưa từng thấy repo: "file này có lỗi không?". Agent thì khác — nó có thể:

  • Lấy thêm ngữ cảnh: đọc định nghĩa hàm ở file khác, tra schema DB.
  • Lập luận nhiều bước: xác định nguồn (source) dữ liệu bẩn → theo dấu tới đích (sink) nguy hiểm.
  • Tự phản biện: sau khi báo lỗi, chạy lại một "agent phản biện" để bác bỏ.
  • Xếp hạng: chấm mức độ nghiêm trọng để bạn fix cái nào trước.

Ví dụ cụ thể

Đoạn PHP sau, Semgrep có thể bỏ sót nếu $db->raw không nằm trong rule:

$role = $_GET['role'];
$rows = $db->raw("SELECT * FROM users WHERE role = '$role'");

Một agent LLM sẽ nhận ra: $_GET['role'] là source (dữ liệu do người dùng kiểm soát), nối chuỗi trực tiếp vào SQL, $db->raw là sink thực thi thô → SQL Injection. Nó còn đề xuất: dùng prepared statement.

Hãy hình dung một tình huống thực tế: đội của bạn có 200 nghìn dòng code PHP kế thừa từ nhiều năm, không ai nhớ hết luồng dữ liệu. Semgrep chạy xong trả về 400 cảnh báo, phần lớn là nhiễu vì rule không hiểu ngữ cảnh. Một reviewer con người đọc hết thì mất cả tuần. Đây chính là chỗ agent LLM tỏa sáng: nó đọc từng route như một senior, ưu tiên đúng chỗ nguy hiểm, và giải thích để dev tin. Nhưng để đạt được điều đó, agent phải được thiết kế kỷ luật — có tool, có phản biện, có đo lường — chứ không phải một prompt tùy hứng. Cả khóa học này xoay quanh việc xây đúng bộ kỷ luật đó.

Khung tư duy Source → Sink

Mọi lỗ hổng injection đều là một đường đi từ Source tới Sink mà không qua Sanitizer:

  • Source: $_GET, $_POST, header, body request, tham số URL, file upload.
  • Sink: câu SQL, echo/HTML output, eval, lệnh shell, đường dẫn file.
  • Sanitizer: prepared statement, htmlspecialchars, whitelist, kiểm tra quyền.
Nếu có Source → Sink mà thiếu Sanitizer đúng loại → lỗ hổng. Đây là la bàn xuyên suốt khóa học.

Các bước tổng quan của một agent SAST

  • Nhận diff hoặc file cần quét.
  • Chunk code theo hàm/route để không tràn context.
  • Với mỗi chunk, prompt LLM tìm ứng viên lỗ hổng (candidate findings).
  • Với mỗi ứng viên, chạy agent phản biện để loại false positive.
  • Chấm severity + độ tin cậy (confidence).
  • Xuất báo cáo đã ưu tiên (SARIF/Markdown), có thể chặn CI.

Checklist trước khi bắt đầu

  • [ ] Xác định phạm vi: quét toàn repo hay chỉ diff của PR?
  • [ ] Xác định loại lỗ hổng mục tiêu: SQLi, XSS, IDOR (khóa này tập trung 3 loại).
  • [ ] Chọn model có cửa sổ ngữ cảnh đủ lớn cho file điển hình.
  • [ ] Chuẩn bị dữ liệu thật để đo false positive rate.

Sai lầm thường gặp

  • Tin LLM ngay lần đầu: bỏ qua bước phản biện → báo cáo đầy nhiễu, dev mất niềm tin và tắt tool.
  • Ném cả repo vào một prompt: vượt context, model "quên" giữa chừng, bỏ sót lỗi.
  • Coi LLM thay thế hoàn toàn Semgrep/CodeQL: sai. LLM bổ sung cho SAST truyền thống, không thay thế bước xác định.
  • Không đo lường: không có tập ground-truth thì không biết agent tốt hay tệ.
Bài sau: dựng môi trường và bộ khung agent tối thiểu chạy được.

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