Coders Conquer Security: Teilen & Lernen - SQL-Injektion

Veröffentlicht am 06. Dez. 2018
von Jaap Karan Singh
FALLSTUDIE

Coders Conquer Security: Teilen & Lernen - SQL-Injektion

Veröffentlicht am 06. Dez. 2018
von Jaap Karan Singh
Ressource anzeigen
Ressource anzeigen

Vereinfacht ausgedrückt ist SQL (oder Structured Query Language) die Sprache, die für die Kommunikation mit relationalen Datenbanken verwendet wird; es ist die Abfragesprache, die von Entwicklern, Datenbankadministratoren und Anwendungen verwendet wird, um die riesigen Datenmengen zu verwalten , die jeden Tag erzeugt werden.

Unsere Daten werden schnell zu einem der wertvollsten Güter der Welt... und wenn etwas wertvoll ist, wollen Bösewichte es zu ihrem Vorteil in die Finger bekommen.

Angreifer nutzen SQL-Injection - eine der ältesten(seit 1998!) und lästigsten Datenschwachstellen, die es gibt - um sensible Informationen zu stehlen und zu verändern, die in Millionen von Datenbanken auf der ganzen Welt vorhanden sind. Es ist heimtückisch, und Entwickler müssen SQL-Injection verstehen (und wissen, wie man sich dagegen verteidigt), wenn wir unsere Daten sicher halten wollen.

Zu diesem Zweck werden wir drei Hauptaspekte der SQL-Injektion besprechen:

  • Wie es funktioniert
  • Warum es so gefährlich ist
  • Wie man sich dagegen verteidigt

SQL-Injektion verstehen

SQL-Injection kann mit einem Wort verstanden werden: Kontext.

Innerhalb einer Anwendung existieren zwei Kontexte: einer für Daten, der andere für Code. Der Code-Kontext sagt dem Computer, was er ausführen soll und trennt ihn von den zu verarbeitenden Daten.

SQL-Injection tritt auf, wenn ein Angreifer Daten eingibt, die vom SQL-Interpreter fälschlicherweise als Code behandelt werden.

Ein Beispiel ist ein Eingabefeld auf einer Website, in das ein Angreifer ''' OR 1=1" eingibt und das an das Ende einer SQL-Abfrage angehängt wird. Wenn diese Abfrage ausgeführt wird, gibt sie für jede Zeile in der Datenbank "true" zurück. Das heißt, es werden alle Datensätze aus der abgefragten Tabelle zurückgegeben.

Die Auswirkungen einer SQL-Injection können katastrophal sein. Wenn dies auf einer Anmeldeseite geschieht, könnte sie alle Benutzerdatensätze zurückgeben, möglicherweise einschließlich Benutzernamen und Kennwörtern. Wenn eine einfache Abfrage zum Herausnehmen von Daten erfolgreich ist, dann würden auch Abfragen zum Ändern von Daten erfolgreich sein.

Lassen Sie uns einen Blick auf verwundbaren Code werfen, damit Sie sehen können, wie eine SQL-Injection-Schwachstelle in Fleisch und Blut aussieht.

Sehen Sie sich diesen Code an:

String query = "SELECT account balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
   Statement statement = connection.createStatement( ... );
   ResultSet results = statement.executeQuery( query );
}

Der Code hier fügt die Parameterinformationen vom Client einfach an das Ende der SQL-Abfrage an, ohne sie zu validieren. Wenn dies geschieht, kann ein Angreifer Code in ein Eingabefeld oder URL-Parameter eingeben und dieser wird ausgeführt.

Der springende Punkt ist nicht, dass Angreifer nur ''' OR 1=1" zu jeder SELECT-Abfrage hinzufügen können, sondern dass ein Angreifer jede Art von SQL-Abfrage (INSERT, UPDATE, DELETE, DROP usw.) manipulieren und mit allem erweitern kann, was die Datenbank unterstützt. Es gibt großartige Ressourcen und Tools im öffentlichen Bereich, die zeigen, was möglich ist.

Wir werden bald lernen, wie man dieses Problem beheben kann. Zuerst wollen wir verstehen, wie viel Schaden angerichtet werden kann.

Warum SQL-Injection so gefährlich ist

Hier sind nur drei Beispiele für Sicherheitsverletzungen, die durch SQL-Injection verursacht wurden:

  • Die Website des Illinois Board of Election wurde aufgrund von SQL-Injection-Schwachstellen angegriffen. Die Angreifer stahlen die persönlichen Daten von 200.000 US-Bürgern. Die Art der gefundenen Schwachstelle bedeutete, dass die Angreifer die Daten auch hätten ändern können, was sie jedoch nicht taten.
  • Hetzner, ein südafrikanisches Website-Hosting-Unternehmen, wurde in Höhe von 40.000 Kundendatensätzen angegriffen. Eine SQL-Injection-Schwachstelle führte zum möglichen Diebstahl jedes Kundendatensatzes in ihrer Datenbank.
  • Ein katholischer Finanzdienstleister in Minnesota, USA, wurde mittels SQL-Injection angegriffen. Kontodaten, einschließlich Kontonummern, von fast 130.000 Kunden wurden gestohlen.

Sensible Daten können verwendet werden, um Konten zu übernehmen, Passwörter zurückzusetzen, Geld zu stehlen oder Betrug zu begehen.

Selbst Informationen, die nicht als sensibel oder persönlich identifizierbar gelten, können für andere Angriffe verwendet werden. Adressdaten oder die letzten vier Ziffern Ihrer staatlichen Identifikationsnummer können verwendet werden, um sich gegenüber Unternehmen als Sie auszugeben oder Ihr Passwort zurückzusetzen.

Wenn ein Angriff erfolgreich ist, können Kunden das Vertrauen in das Unternehmen verlieren. Die Behebung von Schäden an Systemen oder behördlichen Geldstrafen kann Millionen von Dollar kosten.

Aber so muss es für Sie nicht enden.

SQL-Injektion besiegen

SQL-Injection kann vereitelt werden, indem Sie Teile Ihrer Anwendung eindeutig kennzeichnen, so dass der Computer weiß, ob ein bestimmter Teil Daten oder auszuführender Code ist. Dies kann durch parametrisierte Abfragen geschehen.

Wenn SQL-Abfragen Parameter verwenden, verwendet der SQL-Interpreter den Parameter nur als Daten. Er führt ihn nicht als Code aus.

Zum Beispiel wird ein Angriff wie ''' OR 1=1" nicht funktionieren. Die Datenbank wird nach der Zeichenfolge "OR 1=1" suchen und sie nicht in der Datenbank finden. Sie wird einfach mit den Schultern zucken und sagen: "Tut mir leid, ich kann das nicht für Sie finden."

Ein Beispiel für eine parametrisierte Abfrage in Java sieht so aus:

Die meisten Entwicklungsframeworks bieten eingebaute Schutzmechanismen gegen SQL-Injection.

Objektrelationale Mapper (ORMs), wie z. B. Entity Framework in der .NET-Familie, parametrisieren Abfragen standardmäßig. Dadurch wird SQL-Injection ohne jeglichen Aufwand Ihrerseits verhindert.

Sie müssen jedoch wissen, wie Ihr spezifisches ORM funktioniert. Zum Beispiel kann Hibernate, ein beliebtes ORM in der Java-Welt, bei falscher Verwendung dennoch anfällig für SQL-Injection sein.

Die Parametrisierung von Abfragen ist die erste und beste Verteidigung, aber es gibt noch andere. Stored Procedures unterstützen ebenfalls SQL-Parameter und können verwendet werden, um SQL-Injection zu verhindern. Denken Sie daran, dass die gespeicherten Prozeduren ebenfalls korrekt aufgebaut sein müssen, damit dies funktioniert.

// This should REALLY be validated too
String custname = request.getParameter("customerName");
// perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";

PreparedStatement pstmt = connection.preparedStatement( query );
pstmt.setString(1, custname);
ResultSet results = pstmt.executeQuery( );

Validieren und bereinigen Sie immer Ihre Eingaben. Da einige Zeichen, wie z. B. "OR 1=1", von einem legitimen Benutzer Ihrer Anwendung nicht eingegeben werden, ist es nicht notwendig, sie zuzulassen. Sie können dem Benutzer eine Fehlermeldung anzeigen oder sie aus der Eingabe entfernen, bevor sie verarbeitet werden.

Verlassen Sie sich also nicht allein auf die Validierung und Desinfizierung, um sich zu schützen. Clevere Menschen haben Wege gefunden, sie zu umgehen. Das sind gute Defense in Depth (DiD)-Strategien, aber die Parametrisierung ist der todsichere Weg, um alle Basen abzudecken.

Eine weitere gute DiD-Strategie ist die Verwendung von "Least Privilege" innerhalb der Datenbank und Whitelisting von Eingaben. Das Erzwingen von "Least Privilege" bedeutet, dass Ihre Anwendung keine unbegrenzte Macht innerhalb der Datenbank hat. Sollte ein Angreifer Zugriff erhalten, ist der Schaden, den er anrichten kann, begrenzt.

OWASP hat ein großartiges SQL Injection Cheat Sheet zur Verfügung, das zeigt, wie man mit dieser Schwachstelle in verschiedenen Sprachen und Plattformen umgeht... aber wenn Sie noch einen draufsetzen wollen, können Sie auf unserer Plattform gleich eine SQL Injection Challenge in Ihrer bevorzugten Sprache spielen; hier sind einige der beliebtesten, um den Anfang zu machen:

SQL-Einschleusung in C#

SQL-Einschleusung in Node.js

SQL-Einschleusung in Python Django

SQL-Einschleusung in Java Spring

Die Reise beginnt

Sie haben große Fortschritte gemacht, um SQL-Injection zu verstehen und die Schritte, die nötig sind, um sie zu beheben. Großartig!

Wir haben besprochen, wie SQL-Injektion auftritt; typischerweise verwendet ein Angreifer Eingaben, um Ihre Datenbankabfragen für seine eigenen schändlichen Zwecke zu steuern.

Wir haben auch den Schaden gesehen, der durch die Ausnutzung von SQL-Injection-Schwachstellen entsteht: Konten können kompromittiert werden und Millionen von Dollar verloren gehen... ein Alptraum, und ein teurer noch dazu.

Wir haben gesehen, wie man SQL-Injection verhindern kann:

  • Abfragen parametrieren
  • Verwenden von objektrelationalen Mappern und gespeicherten Prozeduren
  • Validierung und Whitelisting von Benutzereingaben

Jetzt liegt es an Ihnen. Übung ist der beste Weg, um weiter zu lernen und seine Fähigkeiten zu verbessern, also schauen Sie sich doch mal unsere Lernressourcen zur SQL-Injektion und probieren Sie dann unsere kostenlose Demo der Plattform? Sie werden auf dem besten Weg sein, ein Secure Code Warrior zu werden.

Ressource anzeigen
Ressource anzeigen

Autor

Jaap Karan Singh

Sie wollen mehr?

Tauchen Sie ein in unsere neuesten Erkenntnisse über sichere Kodierung im Blog.

Unsere umfangreiche Ressourcenbibliothek zielt darauf ab, die menschliche Herangehensweise an eine sichere Weiterbildung im Bereich der Programmierung zu stärken.

Blog ansehen
Sie wollen mehr?

Holen Sie sich die neuesten Forschungsergebnisse zur entwicklergesteuerten Sicherheit

Unsere umfangreiche Ressourcenbibliothek ist voll von hilfreichen Ressourcen, von Whitepapers bis hin zu Webinaren, die Ihnen den Einstieg in die entwicklungsorientierte sichere Programmierung erleichtern. Erforschen Sie sie jetzt.

Ressourcendrehscheibe

Coders Conquer Security: Teilen & Lernen - SQL-Injektion

Veröffentlicht am 06. Dez. 2018
Von Jaap Karan Singh

Vereinfacht ausgedrückt ist SQL (oder Structured Query Language) die Sprache, die für die Kommunikation mit relationalen Datenbanken verwendet wird; es ist die Abfragesprache, die von Entwicklern, Datenbankadministratoren und Anwendungen verwendet wird, um die riesigen Datenmengen zu verwalten , die jeden Tag erzeugt werden.

Unsere Daten werden schnell zu einem der wertvollsten Güter der Welt... und wenn etwas wertvoll ist, wollen Bösewichte es zu ihrem Vorteil in die Finger bekommen.

Angreifer nutzen SQL-Injection - eine der ältesten(seit 1998!) und lästigsten Datenschwachstellen, die es gibt - um sensible Informationen zu stehlen und zu verändern, die in Millionen von Datenbanken auf der ganzen Welt vorhanden sind. Es ist heimtückisch, und Entwickler müssen SQL-Injection verstehen (und wissen, wie man sich dagegen verteidigt), wenn wir unsere Daten sicher halten wollen.

Zu diesem Zweck werden wir drei Hauptaspekte der SQL-Injektion besprechen:

  • Wie es funktioniert
  • Warum es so gefährlich ist
  • Wie man sich dagegen verteidigt

SQL-Injektion verstehen

SQL-Injection kann mit einem Wort verstanden werden: Kontext.

Innerhalb einer Anwendung existieren zwei Kontexte: einer für Daten, der andere für Code. Der Code-Kontext sagt dem Computer, was er ausführen soll und trennt ihn von den zu verarbeitenden Daten.

SQL-Injection tritt auf, wenn ein Angreifer Daten eingibt, die vom SQL-Interpreter fälschlicherweise als Code behandelt werden.

Ein Beispiel ist ein Eingabefeld auf einer Website, in das ein Angreifer ''' OR 1=1" eingibt und das an das Ende einer SQL-Abfrage angehängt wird. Wenn diese Abfrage ausgeführt wird, gibt sie für jede Zeile in der Datenbank "true" zurück. Das heißt, es werden alle Datensätze aus der abgefragten Tabelle zurückgegeben.

Die Auswirkungen einer SQL-Injection können katastrophal sein. Wenn dies auf einer Anmeldeseite geschieht, könnte sie alle Benutzerdatensätze zurückgeben, möglicherweise einschließlich Benutzernamen und Kennwörtern. Wenn eine einfache Abfrage zum Herausnehmen von Daten erfolgreich ist, dann würden auch Abfragen zum Ändern von Daten erfolgreich sein.

Lassen Sie uns einen Blick auf verwundbaren Code werfen, damit Sie sehen können, wie eine SQL-Injection-Schwachstelle in Fleisch und Blut aussieht.

Sehen Sie sich diesen Code an:

String query = "SELECT account balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
   Statement statement = connection.createStatement( ... );
   ResultSet results = statement.executeQuery( query );
}

Der Code hier fügt die Parameterinformationen vom Client einfach an das Ende der SQL-Abfrage an, ohne sie zu validieren. Wenn dies geschieht, kann ein Angreifer Code in ein Eingabefeld oder URL-Parameter eingeben und dieser wird ausgeführt.

Der springende Punkt ist nicht, dass Angreifer nur ''' OR 1=1" zu jeder SELECT-Abfrage hinzufügen können, sondern dass ein Angreifer jede Art von SQL-Abfrage (INSERT, UPDATE, DELETE, DROP usw.) manipulieren und mit allem erweitern kann, was die Datenbank unterstützt. Es gibt großartige Ressourcen und Tools im öffentlichen Bereich, die zeigen, was möglich ist.

Wir werden bald lernen, wie man dieses Problem beheben kann. Zuerst wollen wir verstehen, wie viel Schaden angerichtet werden kann.

Warum SQL-Injection so gefährlich ist

Hier sind nur drei Beispiele für Sicherheitsverletzungen, die durch SQL-Injection verursacht wurden:

  • Die Website des Illinois Board of Election wurde aufgrund von SQL-Injection-Schwachstellen angegriffen. Die Angreifer stahlen die persönlichen Daten von 200.000 US-Bürgern. Die Art der gefundenen Schwachstelle bedeutete, dass die Angreifer die Daten auch hätten ändern können, was sie jedoch nicht taten.
  • Hetzner, ein südafrikanisches Website-Hosting-Unternehmen, wurde in Höhe von 40.000 Kundendatensätzen angegriffen. Eine SQL-Injection-Schwachstelle führte zum möglichen Diebstahl jedes Kundendatensatzes in ihrer Datenbank.
  • Ein katholischer Finanzdienstleister in Minnesota, USA, wurde mittels SQL-Injection angegriffen. Kontodaten, einschließlich Kontonummern, von fast 130.000 Kunden wurden gestohlen.

Sensible Daten können verwendet werden, um Konten zu übernehmen, Passwörter zurückzusetzen, Geld zu stehlen oder Betrug zu begehen.

Selbst Informationen, die nicht als sensibel oder persönlich identifizierbar gelten, können für andere Angriffe verwendet werden. Adressdaten oder die letzten vier Ziffern Ihrer staatlichen Identifikationsnummer können verwendet werden, um sich gegenüber Unternehmen als Sie auszugeben oder Ihr Passwort zurückzusetzen.

Wenn ein Angriff erfolgreich ist, können Kunden das Vertrauen in das Unternehmen verlieren. Die Behebung von Schäden an Systemen oder behördlichen Geldstrafen kann Millionen von Dollar kosten.

Aber so muss es für Sie nicht enden.

SQL-Injektion besiegen

SQL-Injection kann vereitelt werden, indem Sie Teile Ihrer Anwendung eindeutig kennzeichnen, so dass der Computer weiß, ob ein bestimmter Teil Daten oder auszuführender Code ist. Dies kann durch parametrisierte Abfragen geschehen.

Wenn SQL-Abfragen Parameter verwenden, verwendet der SQL-Interpreter den Parameter nur als Daten. Er führt ihn nicht als Code aus.

Zum Beispiel wird ein Angriff wie ''' OR 1=1" nicht funktionieren. Die Datenbank wird nach der Zeichenfolge "OR 1=1" suchen und sie nicht in der Datenbank finden. Sie wird einfach mit den Schultern zucken und sagen: "Tut mir leid, ich kann das nicht für Sie finden."

Ein Beispiel für eine parametrisierte Abfrage in Java sieht so aus:

Die meisten Entwicklungsframeworks bieten eingebaute Schutzmechanismen gegen SQL-Injection.

Objektrelationale Mapper (ORMs), wie z. B. Entity Framework in der .NET-Familie, parametrisieren Abfragen standardmäßig. Dadurch wird SQL-Injection ohne jeglichen Aufwand Ihrerseits verhindert.

Sie müssen jedoch wissen, wie Ihr spezifisches ORM funktioniert. Zum Beispiel kann Hibernate, ein beliebtes ORM in der Java-Welt, bei falscher Verwendung dennoch anfällig für SQL-Injection sein.

Die Parametrisierung von Abfragen ist die erste und beste Verteidigung, aber es gibt noch andere. Stored Procedures unterstützen ebenfalls SQL-Parameter und können verwendet werden, um SQL-Injection zu verhindern. Denken Sie daran, dass die gespeicherten Prozeduren ebenfalls korrekt aufgebaut sein müssen, damit dies funktioniert.

// This should REALLY be validated too
String custname = request.getParameter("customerName");
// perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";

PreparedStatement pstmt = connection.preparedStatement( query );
pstmt.setString(1, custname);
ResultSet results = pstmt.executeQuery( );

Validieren und bereinigen Sie immer Ihre Eingaben. Da einige Zeichen, wie z. B. "OR 1=1", von einem legitimen Benutzer Ihrer Anwendung nicht eingegeben werden, ist es nicht notwendig, sie zuzulassen. Sie können dem Benutzer eine Fehlermeldung anzeigen oder sie aus der Eingabe entfernen, bevor sie verarbeitet werden.

Verlassen Sie sich also nicht allein auf die Validierung und Desinfizierung, um sich zu schützen. Clevere Menschen haben Wege gefunden, sie zu umgehen. Das sind gute Defense in Depth (DiD)-Strategien, aber die Parametrisierung ist der todsichere Weg, um alle Basen abzudecken.

Eine weitere gute DiD-Strategie ist die Verwendung von "Least Privilege" innerhalb der Datenbank und Whitelisting von Eingaben. Das Erzwingen von "Least Privilege" bedeutet, dass Ihre Anwendung keine unbegrenzte Macht innerhalb der Datenbank hat. Sollte ein Angreifer Zugriff erhalten, ist der Schaden, den er anrichten kann, begrenzt.

OWASP hat ein großartiges SQL Injection Cheat Sheet zur Verfügung, das zeigt, wie man mit dieser Schwachstelle in verschiedenen Sprachen und Plattformen umgeht... aber wenn Sie noch einen draufsetzen wollen, können Sie auf unserer Plattform gleich eine SQL Injection Challenge in Ihrer bevorzugten Sprache spielen; hier sind einige der beliebtesten, um den Anfang zu machen:

SQL-Einschleusung in C#

SQL-Einschleusung in Node.js

SQL-Einschleusung in Python Django

SQL-Einschleusung in Java Spring

Die Reise beginnt

Sie haben große Fortschritte gemacht, um SQL-Injection zu verstehen und die Schritte, die nötig sind, um sie zu beheben. Großartig!

Wir haben besprochen, wie SQL-Injektion auftritt; typischerweise verwendet ein Angreifer Eingaben, um Ihre Datenbankabfragen für seine eigenen schändlichen Zwecke zu steuern.

Wir haben auch den Schaden gesehen, der durch die Ausnutzung von SQL-Injection-Schwachstellen entsteht: Konten können kompromittiert werden und Millionen von Dollar verloren gehen... ein Alptraum, und ein teurer noch dazu.

Wir haben gesehen, wie man SQL-Injection verhindern kann:

  • Abfragen parametrieren
  • Verwenden von objektrelationalen Mappern und gespeicherten Prozeduren
  • Validierung und Whitelisting von Benutzereingaben

Jetzt liegt es an Ihnen. Übung ist der beste Weg, um weiter zu lernen und seine Fähigkeiten zu verbessern, also schauen Sie sich doch mal unsere Lernressourcen zur SQL-Injektion und probieren Sie dann unsere kostenlose Demo der Plattform? Sie werden auf dem besten Weg sein, ein Secure Code Warrior zu werden.

Wir bitten Sie um Ihre Erlaubnis, Ihnen Informationen über unsere Produkte und/oder verwandte Themen der sicheren Codierung zuzusenden. Wir werden Ihre persönlichen Daten immer mit äußerster Sorgfalt behandeln und sie niemals zu Marketingzwecken an andere Unternehmen verkaufen.

Senden
Um das Formular abzuschicken, aktivieren Sie bitte "Analytics"-Cookies. Sie können die Cookies wieder deaktivieren, sobald Sie fertig sind.