C# Hochkomma maskieren für SQL-Statements (SQL-Escape)

Ein häufiges Problem im Umgang mit Strings oder SQL-Statements sind Hochkommas. Diese unscheinbaren Zeichen (’ oder „) bereiten immer wieder Probleme. Manchmal auch an Stellen, die man die erwartet hätte.
Gerade beim Zugriff auf SQL-Datenbanken kann sich ein solches Problem zur Laufzeit einschleichen. Dann nämlich, wenn in einem SQL-Statement beispielsweise Benutzer-Eingaben verarbeitet werden. Aber nicht nur der Benutzer, der in ein Textfeld Hochkommas platziert, auch in der Datenverarbeitung stößt man auf dieses Problem. Spätestens, wenn der erste Datensatz mit dem Namen „O’Henry“ auftaucht. Und in jeder Stadt gibt es ein Irish-Pub-Besitzer, der so heißt …

Warum Hochkommas ein Problem sind
In einer Stringzuweisung bereitet das folgende Beispiel kein Problem:

string sHochkommaTest = „Mein Name ist O’Henry“;

Doch dieses Beispiel wird sofort zu Problemen führen:

string sHochkommaTest = „Bitte drücken Sie die „OK“-Taste“;

Was hier hilft ist eine Maskierung des Hochkommas. In C# behilft man sich dem Backslash („“). So ist das folgende Beispiel valider Code:

string sHochkommaTest = „Bitte drücken Sie die „OK“-Taste“;

Hochkommas in jeder Ausprägung werden dann zum Problem, wenn das Hochkomma selbst in einem Statement eine bestimmte Funktion erfüllen. So das doppelte Hochkomma („) bei einer Stringzuweisung, oder das einfache Hochkomma (‚) in einem SQL-Statement.

Hochkomma in einem SQL-Statement maskieren
Hier kann es sehr schnell gefährlich werden. Nehmen wir an, sie nehmen eine Benutzereingabe entgegen wie beispielsweise den Benutzername des Users, den sie in einer Datenbank gespeichert haben und nun prüfen möchten, ob der Benutzer dem System bekannt ist. So könnte das folgende Beispiel aussehen:

SELECT id, name, vorname, pw FROM benutzer WHERE name=’$benutzereingabe’;

In der Variable „$benutzereingabe“ ist der eingegeben Benutzer gespeichert. Und nun kommt unser Herr O’Henry, gibt seinen Namen ein und erzeugt einen Fehler (was das kleinste Problem ist). Er macht nämlich aus unserem SELECT folgendes:

SELECT id, name, vorname, pw FROM benutzer WHERE name=’O’Henry’;

Jeder SQL-Parser wird hier einen Fehler melden. Damit nicht genüg: Solche Fehler sind ein Einfallstor für Hacker in eine Anwendung. Wenn Benutzereingaben gegen eine Datenbank nicht von der Anwendung schon geprüft und maskiert werden, kann dies eine böse Sicherheitslücke ergeben.

Also muss unsere Benutzereingabe geprüft und gegebenenfalls maskiert werden. Man wünscht sich in C# eine Funktion wie in PHP die Funktion mysql_real_escape_string, die dafür sorgt, dass alle Sonderzeigen in der übergebenen Variable auf Sonderzeigen geprüft und ordentlich maskiert werden. Doch meines Wissens gibt es in C# so etwas (einfaches und sicheres) nicht. Weder String-Literale noch LINQ bringen wirkliche Verbesserung.
Während das String-Literal („@“) doppelte Hochkommas filtert (und einige nette weitere Erleichterungen bereithält), löst er jedoch nicht das Problem des einfachen Hochkommas:

string x = @"Joe said ""Hello"" to me";   // Joe said "Hello" to me
string y = @"Joe said ''Hello'' to me";
Console.WriteLine(x);
Console.WriteLine(y);
Console.ReadLine();

So sind beide Zeilen gültiger C#-Code, doch zwei hintereinander folgende einzelne Hochkommas bleiben erhalten. Zumal diese Idee ein „WHERE name =’O’Henry’“ auch nicht lösen würde.

Maskierung für SQL-Statements
Eine ganz einfache Hilfe ist die untenstehende Funktion, über die jede Variable, die in ein SQL-Statement eingebaut werden soll, geschickt werden muss. Diese Funktion macht nichts anderes, als ein einfaches Hochkomma in zwei Hochkommas zu maskieren. Der SQL-Parser wird dieses Ergebnis ohne Fehler verarbeiten.

private static string maskiere(string sValue)
{
    return sValue.Replace("'", "''");
}

Problem der Maskierung
Diese Lösung wird vielleicht folgendes Problem erzeugen: Wenn Sie ein SQL-Ergebnis haben, das Sie bereits durch diese Funktion geschickt haben, das Ergebnis also zwei Hochkommas hintereinander hat, und Sie speichern diesen Code erneut (mit dieser Funktion), werden aus zwei Hochkommas hintereinander (“) vier Hochkommas (““). Und dies wird Ihnen der SQL-Parser sehr übelnehmen.

Die SQL-Lösung zur Maskierung eines SQL-Statements
Wir haben nun viele Möglichkeiten beleuchtet, haben aber noch nicht die wirklich allumfassende perfekte Lösung für C# gefunden. Aber keine Sorge, es gibt sie. Einfach im Artikel „PHP-Funktion mysql_real_escape_string in C# umsetzen“ weiterlesen …

Schreibe einen Kommentar