In diesem Beitrag aus unserer Reihe zur OWASP Top 10, den zehn häufigsten Sicherheitslücken in Webapplikationen, beschäftigen wir uns mit Injections – also der Einschleusung von Schadcode.

Injection-Sicherheitslücken nutzen eine ungesicherte Verarbeitung von Nutzereingaben aus, z. B. in Eingabefeldern für Namen und Adressen. Statt die vorgesehenen Daten einzugeben, kann ein Angreifer z. B. Programmcode oder Datenbankbefehle in das Feld eingeben. Eine unsichere Webapplikation interpretiert diese Eingabe und führt den eingegebenen Code aus, statt die Eingabe auf ihre Gültigkeit zu überprüfen und ggf. zu verwerfen. Injections werden je nach Art des übermittelten Schadcodes unterschieden.

SQL-Injection

Die am häufigsten auftretende Injection-Attacke, welche auch am häufigsten für den Datenverlust von unzähligen Kundendatensätzen verantwortlich ist, wird als SQL-Injection bezeichnet. SQL steht für „Structured Query Language“ und ist eine Sprache zur Datenbankabfrage. Ein SQL-Statement sieht z. B. so aus:

SELECT * FROM Kunden WHERE Kundennummer = X;

Dieses Beispiel sucht aus der Kunden-Tabelle den Datensatz heraus, der die Kundennummer X hat, wobei X als Eingabeparameter frei durch den Benutzer der Suche gewählt werden kann. Wenn der Nutzer beispielsweise nach der Kundennummer 89075 sucht, würde das exakte SQL-Statement folgendermaßen aussehen:

SELECT * FROM Kunden WHERE Kundennummer = 89075;

SQL bietet noch wesentlich mehr Funktionen als diese einfache Suche und beinhaltet auch Funktionen zum Bearbeiten von Datensätzen.

Der Trick an einer SQL-Injection ist nun, dass ein Angreifer hinter einem Eingabefeld (z. B. für die Suche eines Kunden anhand der Kundennummer) ein SQL-Statement wie oben vermutet: Die Webapplikation fügt die vom Benutzer in das Feld eingegebene Kundennummer in das Statement ein. Gibt der Angreifer statt einer korrekten Kundennummer jetzt aber z. B. „89075 OR 1=1“ ein, wird das folgende SQL-Statement ausgeführt:

SELECT * FROM Kunden WHERE Kundennummer = 89075 OR 1=1;

Das Statement sucht also alle Datensätze heraus, die die Kundennummer 89075 haben oder auf die die Bedingung „1=1“ zutrifft. Da die Bedingung „1=1“ immer zutrifft, liefert die Datenbank als Ergebnis die gesamte Kundentabelle zurück. So entstehen Datenlecks.

OS-Injection und weitere

Eine weitere, folgenschwere Lücke ist die OS-Injection, bei der ein Angreifer durch Eingabefelder in der Webapplikation Befehle an das Betriebssystem des Webservers weiterleiten kann. Dadurch kann er z. B. Dateien vom Server kopieren, löschen oder verändern, Passwörter auslesen oder Schadsoftware einschleusen, die ihm permanenten Zugang zum System verschafft.

Bei der etwas allgemeineren Code-Injection kann der Angreifer über Eingabefelder Programmcode in der Programmiersprache der Webapplikation einschleusen und beliebige Befehle ausführen. Unter Umständen besteht im Kontext einer Code-Injection auch die Möglichkeit für eine OS-Injection, da viele Programmiersprachen die Möglichkeit bieten, Befehle an das Betriebssystem des Servers weiterzugeben. Darüber hinaus gibt es noch diverse weitere Injection-Angriffe, die z. B. auch LDAP oder XML betreffen können, aber vom Grundkonzept für alle Interpreter gleich sind.

Gegenmaßnahmen

Injection-Lücken kann vorgebeugt werden, in dem sämtliche Benutzereingaben validiert werden. Es gilt der Grundsatz: „Never trust user input“ – Vertraue niemals Benutzereingaben. Dies beinhaltet auch die korrekte Filterung von Sonderzeichen. Noch besser ist es, im Rahmen einer Allow-List überhaupt nur die für das entsprechende Eingabefeld benötigten Zeichen zuzulassen. Benutzereingaben oder Teile von ihnen sollten niemals ungefiltert in Anfragen an eine Datenbank oder an das Betriebssystem verwendet werden. Weiterhin sollten die Webapplikationen bzw. deren Server-Prozesse mit möglichst eingeschränkten Rechten agieren, damit im Falle einer Code-Injection nicht das gesamte Betriebssystem des Servers kompromittiert werden kann. Zusätzlich sollten SQL-Statements immer parametrisiert werden, sodass die Logik einer Abfrage durch das Einsetzen der Parameter nicht verändert werden kann. Die obige SQL-Abfrage kann bspw. mit Hilfe der Standard-Java-Funktionen wie folgt parametrisiert werden:

String kundennummer = request.getParameter(„Kundennummer“); // Eingabeparameter „Kundennummer“ wird in eine Variable geladen

String query = „SELECT * FROM Kunden WHERE Kundennummer = ?“;  // Definition der SQL-Abfrage zur Ermittlung eines Kunden anhand der Kundennummer mit „Kundennummer“ als Parameter

PreparedStatement pstmt = connection.prepareStatement(query); // Initialisierung der SQL-Abfrage; die Logik des Statements kann danach nicht mehr verändert werden

pstmt.setString(1, kundennummer);  // Einsetzen des Eingabeparameters „Kundennummer“

ResultSet results = pstmt.executeQuery( ); // Ausführung der SQL-Abfrage

Zusammenfassung

Injection-Attacken sind die häufigsten Sicherheitslücken, da jede Webapplikation mit Benutzereingaben arbeitet, und können die schwerwiegendsten Folgen haben. Deshalb sind sie in der OWASP Top 10 weiterhin auf Platz eins zu finden und sollten fester Bestandteil jedes Penetrationstests von Webapplikationen sein. Übrigens gibt es bei uns durch das Förderprogramm „go-digital“ des BMWi sogar eine finanzielle Unterstützung für Beratungsdienstleistungen im Bereich IT-Sicherheit.

Update 26.03.2021

Wir haben eine Bild aus dem Text entfernt.