flawopen.com/SQL Injection in C#/EF Core FromSqlRaw
Ist Entity Framework Core FromSqlRaw sicher?
Ja, wenn Werte vom SQL-Text getrennt bleiben. FromSqlRaw akzeptiert rohes SQL; nicht vertrauenswürdige Eingaben anzuhängen oder in den String zu interpolieren, kann die Abfrage verändern. Verwenden Sie separate Parameterargumente oder übergeben Sie einen interpolierten FormattableString an FromSqlInterpolated (oder ab EF Core 7 an FromSql). Ein Parameter ist wie ein versiegeltes Wertfach: Die Datenbank erhält den Wert, keine neuen SQL-Anweisungen.
// Die Interpolation wird zuerst zu einem String ausgewertet. var sql = $"SELECT * FROM Users WHERE Id = {id}"; // FromSqlRaw erhält SQL-Text, keinen FormattableString. var query = context.Users.FromSqlRaw(sql);
// EF Core 3–6: Positionsplatzhalter und separater Wert. var byRawParameter = context.Users.FromSqlRaw( "SELECT * FROM Users WHERE Id = {0}", id); // EF Core 3+: Interpolation an die Parameter-API übergeben. var byInterpolation = context.Users.FromSqlInterpolated( $"SELECT * FROM Users WHERE Id = {id}"); // EF Core 7+: FromSql akzeptiert ebenfalls FormattableString. var byFromSql = context.Users.FromSql( $"SELECT * FROM Users WHERE Id = {id}");
Der kontraintuitive Punkt
FromSqlInterpolated erhält einen FormattableString. EF Core liest Format und Argumente und sendet jeden interpolierten Wert als separaten Datenbankparameter; eine Kompilierzeit-Interception findet nicht statt. EF Core 7 führte FromSql mit demselben sicheren Verhalten für interpolierte Strings ein. Ältere Versionen verwenden FromSqlInterpolated. FromSqlRaw ist ebenfalls sicher, wenn Platzhalter wie {0} zu separat übergebenen Werten passen. Ein interpolierter String, der zuerst in einem string gespeichert wird, hat seine Parameter-Metadaten bereits verloren.
Parameter binden Werte, keine Spaltennamen
Ein Datenbankparameter steht für einen Wert, nicht für Tabellen- oder Spaltennamen, SQL-Operatoren oder Sortierrichtungen. Wenn sich die Abfragestruktur ändern muss, wählen Sie jeden Bezeichner aus einer festen Allowlist im Anwendungscode. Versuchen Sie nicht, Bezeichner zu parametrisieren, und ersetzen Sie die Allowlist nicht durch Zeichenfilter. Prüfen Sie außerdem Berechtigungen und Abfragekosten: Eine gültige Spalte kann vertrauliche Daten offenlegen oder teure Scans auslösen.
- ✓Für Werte verwenden Sie FromSqlInterpolated/FromSql mit direkter Interpolation oder FromSqlRaw mit separaten Parametern.
- ✓Übergeben Sie niemals verkettete oder interpolierte Benutzerdaten an FromSqlRaw. Wandeln Sie einen FormattableString nicht vorher in string um.
- ✓Wählen Sie dynamische Bezeichner ausschließlich aus einer festen Allowlist. Prüfen Sie Berechtigungen und effiziente Indizierung des Feldes getrennt.
- ✓Bevorzugen Sie LINQ, wenn sich die Abfrage damit klar ausdrücken lässt; Parametrisierung verhindert SQL-Syntax-Injection, setzt aber keine Berechtigungen oder Geschäftsregeln durch.
So prüfen Sie Ihre Codebasis
rg -n -g '*.cs' '(FromSqlRaw|FromSqlInterpolated|FromSql)\s*\(' .Häufige Fragen
Ja, wenn das SQL Platzhalter enthält und Werte als separate Argumente übergeben werden, zum Beispiel FromSqlRaw("... {0}", value). Verketten oder interpolieren Sie den Wert nicht vorher in den SQL-String.
Die Methode erhält einen FormattableString, der Format und Werte getrennt erhält. EF Core wandelt jeden Wert in einen Datenbankparameter um. Wird die Interpolation zuerst einem string zugewiesen oder an FromSqlRaw übergeben, geht dieser Schutz verloren.
Nein. Parameter stehen nur für Werte. Ordnen Sie Benutzerauswahlen dynamischer Bezeichner einer festen Allowlist bekannter Bezeichner zu und prüfen Sie Berechtigungen sowie Abfragekosten.
Quellen
- Microsoft Learn — EF-Core-SQL-Abfragen und Parameter
- Microsoft Learn — FromSqlRaw-API
- Microsoft Learn — FromSqlInterpolated-API
- OWASP — Leitfaden zur Vermeidung von SQL Injection
- FlawOpen — SQL Injection in C#