SQL-Injection in C# mit Entity Framework verhindern
30. Juli 2024
0 Min. LesezeitWarum es wichtig ist, SQL-Injection zu verhindern
SQL-Injection (SQLi) zählt zu den schwerwiegendsten Sicherheitslücken in Webanwendungen. Sie tritt auf, wenn Angreifer:innen die von einer Anwendung ausgeführten SQL-Abfragen manipulieren können, indem sie schädlichen SQL-Code in Benutzereingaben einschleusen. SQLi kann zu unbefugtem Zugriff auf sensible Daten, Datenbeschädigung oder sogar zur vollständigen Kontrolle über den Datenbankserver führen. SQLi zu verhindern, ist entscheidend, um Integrität, Vertraulichkeit und Verfügbarkeit der Daten sowie die allgemeine Sicherheit der Anwendung zu gewährleisten.
Einer der häufigsten Fehler von Entwickler:innen ist es, SQL-Abfragen durch das Verketten von Zeichenfolgen zu erstellen. Bei diesem Ansatz werden vom Benutzer eingegebene Parameter Teil der SQL-Abfrage und können deren Ausführungspfad beeinflussen. Hier ein Beispiel für anfälligen C#-Code:
Mit Zeichen wie ; und -- lässt sich der Ausführungspfad der Abfrage beeinflussen, indem sie vorzeitig beendet wird (;) und der Rest der Zeichenfolge als Kommentar definiert wird (--).
Wird als Name Brian'; DROP TABLE Users;-- angegeben, sieht die Abfrage so aus:
Die ursprüngliche Abfrage endet nach dem ;. Anschließend wird eine neue Abfrage ausgeführt, die die Tabelle Users löscht. Der Rest der ursprünglichen Abfrage wird als Kommentar behandelt. Auf ähnliche Weise lassen sich Daten in der Datenbank ändern oder neue Daten einfügen, wenn SQL-Abfragen auf diese Weise implementiert werden.
Escaping oder vorbereitete Anweisungen
Entscheidend ist, die Eingabeparameter von der eigentlichen Abfrage zu trennen, damit Benutzereingaben den Ausführungspfad der Abfrage nicht mehr beeinflussen können. In vielen Programmiersprachen stehen Funktionen für parametrisierte Abfragen zur Verfügung, die Benutzereingaben von der eigentlichen Abfrage trennen.
Die Frage ist, wie dies unter der Haube umgesetzt wird. Dafür gibt es im Wesentlichen zwei Möglichkeiten: Escaping oder vorbereitete Anweisungen.
Escaping
Beim Escaping werden Benutzereingaben bereinigt, indem vor potenziell gefährlichen Zeichen, etwa Anführungszeichen, Escape-Zeichen eingefügt werden. Dieser Vorgang ist jedoch fehleranfällig und bietet keine absolute Sicherheit. Das Escaping erfolgt clientseitig, also in der Anwendung, und die escapte Abfrage wird als einzelne Anweisung an die Datenbank gesendet. Dabei müssen verschiedene Sonderfälle sorgfältig berücksichtigt werden. Als primäre Schutzmaßnahme gegen SQLi wird Escaping daher generell nicht empfohlen.
Vorbereitete Anweisungen
Vorbereitete Anweisungen mit parametrisierten SQL-Abfragen funktionieren dagegen etwas anders. Die SQL-Struktur wird separat definiert und in einem ersten Schritt an den Datenbankserver gesendet. Die Datenbank kann den Ausführungspfad bereits festlegen, bevor die Parameter ins Spiel kommen. In einem zweiten Schritt werden die Parameter an die Datenbank gesendet. Da der Ausführungsplan bereits erstellt wurde, werden die Parameter immer als Daten und nicht als ausführbarer Code behandelt und können die Ausführung nicht beeinflussen.
SQL-Injection mit Entity Framework verhindern
Entity Framework (EF) bietet mehrere Methoden, um sicher mit der Datenbank zu interagieren, ohne die Anwendung SQLi-Schwachstellen auszusetzen. Dazu gehören LINQ-Abfragen, FromSqlInterpolated und FromSqlRaw mit expliziten Parametern.
LINQ verwenden
Language Integrated Query (LINQ) ermöglicht eine sichere Interaktion mit Datenbanken. Für die meisten Abfragen ist dies die empfohlene Methode, um mit EF die Datenbank abzufragen. LINQ bietet einen hohen Abstraktionsgrad: Sie können Abfragen direkt in C# schreiben, ohne die SQL-Syntax kennen zu müssen. Da LINQ in C# integriert ist, profitieren Sie von der Syntaxprüfung zur Kompilierzeit.
Entity Framework wandelt LINQ-Abfragen automatisch mithilfe vorbereiteter Anweisungen und Parametrisierung in SQL um und verhindert so SQL-Injection.
LINQ ist zwar sehr komfortabel und sicher, kann aber mitunter weniger effizientes SQL erzeugen als manuell erstellte SQL-Abfragen – insbesondere bei komplexen Abfragen. Die Übersetzung kann zusätzlichen Performance-Aufwand verursachen. Außerdem ist LINQ durch die Möglichkeiten des EF-Providers eingeschränkt, C#-Code in SQL zu übersetzen. Manche komplexen SQL-Funktionen, etwa bestimmte Arten von Joins, Unterabfragen oder Fensterfunktionen, lassen sich in LINQ nur umständlich oder gar nicht ausdrücken.
FromSqlInterpolated verwenden
FromSqlInterpolated ist eine weitere sichere Möglichkeit, rohe SQL-Abfragen auszuführen. Die Funktion verwendet Zeichenfolgeninterpolation und übernimmt die Parametrisierung automatisch – ebenfalls mithilfe vorbereiteter Anweisungen.
Mit FromSqlInterpolated stellt EF sicher, dass die Variable name sicher parametrisiert wird und schützt so vor SQL-Injection. Entity Framework Core analysiert die interpolierte Zeichenfolge und erkennt die interpolierten Ausdrücke. Anschließend ersetzt es diese Ausdrücke im SQL-Befehl durch Parameterplatzhalter. Die entsprechenden SQL-Parameter werden erstellt und die Werte der interpolierten Ausdrücke diesen Parametern zugewiesen.
Unter der Haube verwendet die Funktion FromSqlInterpolated eine vorbereitete Anweisung mit parametrisierten Abfragen. Sie ist daher vor SQL-Injection geschützt. Wenn Sie komplexere Abfragen benötigen, die sich in SQL einfacher ausdrücken lassen als mit der LINQ-Syntax, ist FromSqlInterpolated eine hervorragende Alternative.
FromSqlRaw mit expliziten Parametern verwenden
Im ursprünglichen Beispiel haben wir zuerst die Abfrage erstellt und sie dann als Ganzes an die FromSQLRaw-Anweisung übergeben. FromSqlRaw lässt sich jedoch auch sicher verwenden. Wenn Sie explizite Parameter mit FromSqlRaw verwenden, stellt EF sicher, dass die Benutzereingabe korrekt parametrisiert wird, und verhindert so SQL-Injection. Dabei werden SQL-Abfragen mit Parameterplatzhaltern definiert und die Werte separat übergeben. So werden Benutzereingaben als Daten und nicht als ausführbarer Code behandelt.
In dieser Version wird der Platzhalter {0} in der SQL-Abfragezeichenfolge verwendet und der Parameterwert direkt als Argument an FromSqlRaw übergeben. Dadurch wird die Benutzereingabe sicher parametrisiert und vor SQL-Injection geschützt.
Finden, beheben und verhindern
Der Unterschied zwischen der sicheren und der unsicheren Verwendung von FromSqlRaw ist gering und leicht zu übersehen. Deshalb sollten alle Entwickler:innen Tools wie Snyk Code verwenden, die vor unsicherer Code-Erstellung in C# warnen.

Im obigen Beispiel wird ein ähnliches SQL-Injection-Problem mithilfe der Git-Integration erkannt. Es ist entscheidend, solche Probleme während des Entwicklungslebenszyklus zu prüfen, wenn Ihnen Sicherheit wichtig ist, Sie aber nicht auf Entwicklungsgeschwindigkeit verzichten möchten.
Ebenso wichtig sind umfassende Schulungen und Kenntnisse der verwendeten Frameworks. Bei der Arbeit mit EF sollten Sie standardmäßig die LINQ-Syntax verwenden. LINQ ist ausreichend, sofern Sie keine besonders hohe Performance benötigen oder sehr komplexe Abfragen erstellen müssen. Für sehr spezifische und komplexe SQL-Abfragen empfiehlt sich der oben beschriebene Ansatz mit FromSqlInterpolated. Mein Rat: Vermeiden Sie FromSqlRaw. Obwohl sich FromSqlRaw sicher verwenden lässt, ist der Unterschied zwischen dem richtigen und dem falschen Ansatz subtil und leicht zu übersehen.
Hier die wichtigsten Punkte noch einmal übersichtlich zusammengefasst. Bei der Verwendung von Entity Framework:
Verwenden Sie für die Interaktion mit der Datenbank die LINQ-Syntax und vermeiden Sie SQL.
Verwenden Sie FromSQLInterpolated nur in komplexen Fällen.
Verwenden Sie ein Code-Scanning-Tool wie Snyk Code, um Fehler zu erkennen.
Jetzt wissen Sie mehr und können Entity Framework in C# einsetzen, um Ihren Code vor SQL-Injection-Schwachstellen zu schützen. Damit Ihnen der Einstieg leichter fällt, erstellen Sie ein kostenloses Snyk-Konto oder buchen Sie eine Demo und erfahren Sie noch heute, wie Snyk Ihren Code während der Entwicklung schützt.
Starten Sie mit Capture the Flag
Erfahren Sie in unserem virtuellen On-Demand-Workshop für Einsteiger, wie Sie Capture-the-Flag-Herausforderungen lösen.



