SecLab
Injection & Output EncodingwalkthroughĐộ khó 3/524 phút

Những cửa sau mà ORM vẫn để ngỏ

Mục tiêu: Sau bài này bạn biết chính xác những API nào của EF Core còn nhận SQL thô, và biết một test chặn được chúng.

V1CWE-89A05:2025sql-injection
Bước 1 / 5 · read5 phút

"Chúng ta dùng ORM nên không bị SQL injection"

Câu đó gần đúng, và phần "gần" là phần đáng học.

EF Core tham số hoá mọi truy vấn LINQ. Không có cách nào viết _db.Users.Where(u => u.Email == email) mà bị injection — giá trị luôn thành tham số. Nếu 100% truy vấn của bạn là LINQ thì câu nói trên là đúng.

Vấn đề là 100% không bao giờ xảy ra, vì ba lý do đều hợp lý:

  1. Có truy vấn LINQ không diễn tả được — window function, CTE đệ quy, INSERT ... ON CONFLICT, full-text search.
  2. Có truy vấn LINQ diễn tả được nhưng dịch ra SQL tệ — và ai đó đo được, rồi viết lại bằng SQL thô.
  3. Có người copy một câu SQL từ pgAdmin vào code vì nó đã chạy đúng ở đó.

Nên câu hỏi đúng không phải "chúng ta có dùng ORM không" mà "những cửa sau của ORM đang được dùng ở đâu, và ai đọc lại chúng".

Danh sách cửa sau của EF Core — đây là danh sách đáng dán lên tường:

APICó tham số hoá tự động?
FromSqlInterpolated, ExecuteSqlInterpolated — giá trị nội suy thành tham số
FromSql (EF 7+, nhận FormattableString) — cùng cơ chế
FromSqlRaw, ExecuteSqlRawKhông — chuỗi vào nguyên văn
Database.GetDbConnection() + CommandTextKhông — ADO.NET thô
EF.Functions.Like với pattern ghép chuỗiCó tham số, nhưng pattern có thể là injection logic
Dapper Query<T>("... " + x)Không — Dapper không phải ORM sinh SQL

Cái bẫy tinh vi nhất nằm ở hai dòng đầu và dòng thứ ba: FromSqlInterpolated($"...{x}") an toàn, còn FromSqlRaw($"...{x}") không — và hai dòng đó khác nhau đúng ba ký tự. Đây là chỗ một cái test đáng giá hơn một quy ước.

Xem lộ trình

Bình luận

Tham gia thảo luận
Đăng ký để 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.

Đăng kýĐăng nhập

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…