flawopen.com/SQL Injection di C#/EF Core FromSqlRaw
Apakah FromSqlRaw Entity Framework Core aman?
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.
// 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);
// 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.
- ✓Untuk nilai, gunakan FromSqlInterpolated/FromSql dengan interpolasi langsung, atau FromSqlRaw dengan parameter terpisah.
- ✓Jangan pernah memberikan data pengguna yang digabung atau diinterpolasi ke FromSqlRaw. Jangan ubah FormattableString menjadi string terlebih dahulu.
- ✓Pilih identifier dinamis hanya dari allow-list tetap. Periksa secara terpisah otorisasi atas kolom terpilih dan indeks yang efisien.
- ✓Utamakan LINQ jika dapat menyatakan kueri dengan jelas; parameterisasi mencegah injeksi sintaks SQL, tetapi tidak menerapkan otorisasi atau aturan bisnis.
Cara meninjau basis kode
rg -n -g '*.cs' '(FromSqlRaw|FromSqlInterpolated|FromSql)\s*\(' .Pertanyaan umum
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.
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.
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
- Microsoft Learn — kueri SQL dan parameter EF Core
- Microsoft Learn — API FromSqlRaw
- Microsoft Learn — API FromSqlInterpolated
- OWASP — panduan pencegahan SQL Injection
- FlawOpen — SQL Injection di C#