FlawOpen

flawopen.com/SQL Injection di C#/EF Core FromSqlRaw

Apakah FromSqlRaw Entity Framework Core aman?

Panduan referensi
Jawaban singkat

Aman jika nilai tetap terpisah dari teks SQL. FromSqlRaw menerima SQL mentah; menggabungkan atau menginterpolasi input yang tidak tepercaya ke dalam string-nya dapat mengubah kueri. Gunakan argumen parameter terpisah atau berikan FormattableString hasil interpolasi ke FromSqlInterpolated (atau FromSql pada EF Core 7+). Anggap parameter sebagai slot nilai tersegel: database menerima nilainya, bukan instruksi SQL baru.

TIDAK AMAN — interpolasi menjadi string biasa
// Interpolasi dievaluasi lebih dulu menjadi string.
var sql = $"SELECT * FROM Users WHERE Id = {id}";

// FromSqlRaw menerima teks SQL, bukan FormattableString.
var query = context.Users.FromSqlRaw(sql);
AMAN — nilai tetap menjadi parameter
// EF Core 3–6: placeholder posisi dan nilai terpisah.
var byRawParameter = context.Users.FromSqlRaw(
    "SELECT * FROM Users WHERE Id = {0}", id);

// EF Core 3+: berikan interpolasi ke API berparameter.
var byInterpolation = context.Users.FromSqlInterpolated(
    $"SELECT * FROM Users WHERE Id = {id}");

// EF Core 7+: FromSql juga menerima FormattableString.
var byFromSql = context.Users.FromSql(
    $"SELECT * FROM Users WHERE Id = {id}");

Bagian yang terasa berlawanan intuisi

FromSqlInterpolated menerima FormattableString. EF Core membaca format dan argumennya, lalu mengirim setiap nilai interpolasi sebagai parameter database terpisah; tidak ada intersepsi saat kompilasi. EF Core 7 menambahkan FromSql dengan perilaku aman yang sama untuk string interpolasi. Versi sebelumnya menggunakan FromSqlInterpolated. FromSqlRaw juga aman jika placeholder seperti {0} cocok dengan nilai yang diberikan sebagai argumen terpisah. Jika string interpolasi lebih dulu disimpan sebagai string, metadata parameternya sudah hilang.

Parameter mengikat nilai, bukan nama kolom

Parameter database mewakili nilai, bukan nama tabel atau kolom, operator SQL, maupun arah pengurutan. Jika struktur kueri harus berubah, pilih setiap identifier dari allow-list tetap di kode aplikasi; jangan mencoba memparameterkan identifier atau mengganti allow-list dengan penyaringan karakter. Periksa juga otorisasi dan biaya kueri: kolom yang valid tetap dapat membuka data sensitif atau memicu pemindaian yang mahal.

Cara meninjau basis kode

rg -n -g '*.cs' '(FromSqlRaw|FromSqlInterpolated|FromSql)\s*\(' .
Untuk setiap pemanggilan, periksa overload dan tipe argumennya. Telusuri data tak tepercaya untuk menemukan penggabungan string, interpolasi yang diberikan ke FromSqlRaw, atau FormattableString yang diubah menjadi string; tinjau identifier dinamis secara terpisah.

Pertanyaan umum

Apakah FromSqlRaw aman jika menerima parameter?

Ya, jika SQL berisi placeholder dan nilainya diberikan sebagai argumen terpisah, misalnya FromSqlRaw("... {0}", value). Jangan gabungkan atau interpolasikan nilai ke string SQL terlebih dahulu.

Mengapa FromSqlInterpolated aman dengan string interpolasi C#?

Metode ini menerima FormattableString yang menyimpan format dan nilai secara terpisah. EF Core mengubah setiap nilai menjadi parameter database. Jika interpolasi lebih dulu disimpan ke string atau diberikan ke FromSqlRaw, perlindungan itu hilang.

Bisakah parameter mengganti nama tabel atau kolom?

Tidak. Parameter hanya mewakili nilai. Untuk identifier dinamis, petakan pilihan pengguna ke allow-list tetap berisi identifier yang dikenal, lalu tinjau otorisasi dan biaya kueri.

Referensi

Lihat juga SQL Injection (CWE-89): cara kerja dan cara mencegahnya di setiap bahasa — flawopen.com Injeksi SQL FastAPI: Yang Dicegah dan Tidak Dicegah Pydantic GORM Raw SQL: Cegah Injeksi SQL di Go Apakah Escape Tanda Kutip Cukup untuk Mencegah SQL Injection? Apakah memakai ORM cukup untuk mencegah SQL Injection? Apakah Knex.js aman dari SQL Injection? MyBatis ${} vs #{}: mencegah SQL Injection