Cybersicherheit

SQL-Injection – Demo-Angriffs- und Abwehrmethoden für Entwickler

SQL-Injection – Demo-Angriffs- und Abwehrmethoden für Entwickler

Haben Sie schon einmal die Geschichte gehört, dass eine große Website gehackt wurde, weil sie eine Codezeile „vergessen“ hatte, sie zu überprüfen? In der Welt der Cybersicherheit gibt es eine Angriffsart, die mehr als zwei Jahrzehnte alt ist, aber immer noch auf der OWASP-Top-10-Liste für 2025 steht – SQL-Injection. Nicht weil die Technologie fortgeschritten ist, sondern weil Entwickler oft die Grundlagen vergessen. In diesem Artikel wird SQL-Injection aus der Sicht eines Entwicklers erläutert: Was es ist, wie es auftritt und vor allem: wie man es verhindert.

SQL-Injection: Die offene Seitentür

Stellen Sie sich vor, Sie haben ein Haus mit fest verschlossener Haustür – Firewall eingeschaltet, HTTPS installiert, Authentifizierung läuft. Aber es stellte sich heraus, dass es hinten ein Fenster gab, das unverschlossen war. Das ist ungefähr die SQL-Injection-Analogie. Dieser Angriff durchdringt weder Firewalls noch umgeht er die Verschlüsselung. Es kommt durch die Eingaben, die Sie vom Benutzer erhalten – Eingaben, die Sie validieren sollten, aber nicht.

SQL-Injection funktioniert durch das Einfügen von bösartigem SQL-Code in Eingaben, die nur aus reinem Text bestehen sollten. Wenn Ihre Anwendung Benutzereingaben ohne Sanierung direkt in eine Datenbankabfrage eingibt, kann ein Angreifer die Abfrage „kapern“. Das Ergebnis? Dies kann in Form von Datendiebstahl, Datenlöschung oder sogar vollständiger Kontrolle über Ihre Serverdatenbank geschehen.

Wie SQL-Injection-Angriffe ablaufen

Sehen wir uns ein einfaches Beispiel an. Sie haben beispielsweise ein einfaches Anmeldeformular:

<?php
$username = $_POST['username'];
$password = $_POST['password'];

$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = mysqli_query($conn, $query);
?>

Der obige Code sieht für viele unerfahrene Entwickler „normal“ aus. Beachten Sie jedoch, dass die Variablen $username und $password ohne jegliche Bereinigung direkt in die Abfrage eingefügt werden. Das ist ein Rezept für eine Katastrophe.

Stellen Sie sich nun vor, dass der Angreifer admin' -- in das Feld „Benutzername“ eingibt. Die resultierende Abfrage lautet:

SELECT * FROM users WHERE username='admin' --' AND password=''

Das ---Flag in SQL ist ein Kommentar. Daher wird der Passwortteil überprüft und die Abfrage prüft nur, ob der Benutzername admin existiert. Ohne tatsächliche Authentifizierung meldet sich der Angreifer beim Admin-Konto an. Dies wird als Authentifizierungsumgehung bezeichnet – eine der klassischsten Formen der SQL-Injection

Arten der SQL-Injection

SQL-Injection ist nicht immer so einfach wie im obigen Beispiel. Hier sind einige Variationen, die Sie erkennen müssen:

In-Band-SQL-Injection ist der häufigste Typ, bei dem der Angreifer die Abfrageergebnisse direkt in der Anwendungsantwort sieht. Beispiele hierfür sind Fehlermeldungen, die die Datenbankstruktur offenbaren, oder Seiten, die aufgrund böswilliger Eingaben ihr Verhalten ändern. Dazu gehören UNION-basiert (Kombination der Ergebnisse einer böswilligen Abfrage mit der ursprünglichen Abfrage) und Fehlerbasiert (Verwendung von Fehlermeldungen zum Extrahieren von Informationen).

Blind SQL Injection tritt auf, wenn die Anwendung Fehler nicht anzeigt oder Ergebnisse nicht direkt abfragt. Der Angreifer muss einen Blick auf die Antwort auf die gestellte boolesche Frage werfen. Beispielsweise durch Senden von ' OR 1=1 -- und Beobachten des Antwortunterschieds zwischen wahr und falsch. Der Prozess ist langsamer, aber genauso gefährlich.

Out-of-Band-SQL-Injection nutzt Datenbankfunktionen wie LOAD_FILE() oder UTL_HTTP.REQUEST, um Daten aus der Datenbank an den Server des Angreifers zu senden. Dieser Typ ist seltener, da er bestimmte Datenbankfunktionen erfordert, aber schwer zu erkennen ist.

Praktische Demo: SQL-Injection in PHP

Lassen Sie uns eine einfache Demo ausprobieren. Erstellen Sie eine PHP-Datei mit einer durch Injektion anfälligen Abfrage:

<?php
$conn = new mysqli('localhost', 'root', 'password', 'testdb');

if (isset($_GET['id'])) {
    // VULNERABLE — jangan tiru ini!
    $id = $_GET['id'];
    $query = "SELECT name, email FROM users WHERE id = $id";
    $result = $conn->query($query);

    while ($row = $result->fetch_assoc()) {
        echo "Name: " . $row['name'] . "<br>";
        echo "Email: " . $row['email'] . "<br>";
    }
}
?>

Wenn die normale URL example.com/user.php?id=1 lautet, kann der Angreifer Folgendes versuchen:

# Menampilkan semua data
example.com/user.php?id=1 UNION SELECT username, password FROM users--

# Menyuntikkan data palsu (INSERT)
example.com/user.php?id=1; INSERT INTO users(name,email) VALUES('hacker','[email protected]')--

# Menghapus tabel
example.com/user.php?id=1; DROP TABLE users--

Stellen Sie sich vor, dass dies auf einer Website passiert, auf der Kreditkartendaten, Krankengeschichte oder nationale Identität gespeichert sind. Die Auswirkungen können enorm sein.

So verhindern Sie SQL-Injection

Die gute Nachricht ist, dass SQL-Injection ein Angriff ist, der sehr leicht zu verhindern ist, solange Sie wissen, wie. Die folgenden Methoden haben sich als wirksam erwiesen:

1. Vorbereitete Anweisungen (parametrisierte Abfragen)

Dies ist die effektivste und am meisten empfohlene Methode. Vorbereitete Anweisungen trennen die SQL-Abfrage von den Daten, sodass Benutzereingaben niemals als SQL-Code interpretiert werden.

<?php
// SAFE — gunakan prepared statements
$stmt = $conn->prepare("SELECT name, email FROM users WHERE id = ?");
$stmt->bind_param("i", $_GET['id']);
$stmt->execute();
$result = $stmt->get_result();

while ($row = $result->fetch_assoc()) {
    echo "Name: " . $row['name'] . "<br>";
    echo "Email: " . $row['email'] . "<br>";
}
?>

Beachten Sie das Fragezeichen ? in der Abfrage – es handelt sich um einen Platzhalter, der von bind_param() ausgefüllt wird. Die Datenbank behandelt den Wert einfach als Daten und nicht als Teil der Abfragestruktur. SQL-Injection-Angriffe sind nutzlos.

2. Eingabevalidierung

Zusätzlich zu vorbereiteten Anweisungen müssen Sie auch Benutzereingaben validieren. Wenn das Feld eine Zahl sein muss, stellen Sie sicher, dass es eine Zahl ist. Wenn Sie eine E-Mail senden müssen, überprüfen Sie das E-Mail-Format. Vertrauen Sie niemals Eingaben so wie sie sind.

<?php
// Validasi: pastikan ID hanya angka
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id === false) {
    die("Invalid ID");
}

// Sekarang aman untuk dimasukkan ke query
$stmt = $conn->prepare("SELECT name, email FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
?>

3. Gespeicherte Prozeduren

Gespeicherte Prozeduren sind SQL-Blöcke, die in der Datenbank gespeichert und von der Anwendung ausgeführt werden. Mit gespeicherten Prozeduren müssen komplexe Abfragen nicht direkt in den Anwendungscode geschrieben werden, und Sie können die von Datenbankbenutzern benötigten Daten begrenzen.

4. Whitelist-Ansatz

Wenn die Eingabe nur eine bestimmte Anzahl von Werten umfassen kann (z. B. Rollen: Administrator, Redakteur, Betrachter), verwenden Sie eine Whitelist. Vergleichen Sie die Eingabe mit einer Liste zulässiger Werte, nicht mit einer Liste verbotener Werte.

<?php
$allowed_roles = ['admin', 'editor', 'viewer'];
$role = $_POST['role'];

if (!in_array($role, $allowed_roles)) {
    die("Role tidak valid");
}
?>

5. Prinzip der geringsten Privilegien

Verwenden Sie einen Datenbankbenutzer mit möglichst wenigen Zugriffsrechten. Wenn die Anwendung nur Daten lesen muss, verwenden Sie keinen Benutzer mit den Berechtigungen DROP oder GRANT. Selbst wenn eine Injektion erfolgt, können die Auswirkungen begrenzt werden.

SQL-Injection-Erkennungstools

Sie können dies nicht nur auf der Codeseite verhindern, sondern auch Tools verwenden, um SQL-Injection-Schwachstellen in Ihrer Anwendung zu erkennen:

sqlmap ist ein automatisches Tool, das SQL-Injection erkennen und ausnutzen kann. Sehr nützlich zum Testen Ihrer eigenen Anwendung. Führen Sie einen Scan lokaler Anwendungen durch, bevor Sie sie in der Produktion bereitstellen.

Burp Suite (kostenlose Community Edition) kann zum Abfangen und Ändern von HTTP-Anfragen verwendet werden, sodass Sie Eingaben manuell testen können.

Nikto ist ein Webserver-Scanner, der verschiedene Arten von Schwachstellen erkennen kann, einschließlich SQL-Injection auf Konfigurationsebene.

Denken Sie daran: Verwenden Sie dieses Tool nur zum Testen Ihrer eigenen Anwendung. Die Verwendung dieses Tools in den Anwendungen anderer Personen ohne Erlaubnis ist illegal.

Schlussfolgerung

SQL-Injection mag wie ein veraltetes „klassisches“ Thema klingen, aber die Realität ist, dass dieser Angriff auch im Jahr 2025 immer noch sehr relevant ist. Es gibt viele Fälle von Datenlecks, die durch etwas so Einfaches wie „Vergessen, vorbereitete Anweisungen zu verwenden“ verursacht werden.

Als Entwickler sind Sie dafür verantwortlich, Benutzerdaten zu schützen. Stellen Sie von nun an sicher, dass jede von Ihnen geschriebene Abfrage vorbereitete Anweisungen verwendet, dass jede Eingabe, die Sie erhalten, validiert wurde und dass jedem Datenbankbenutzer die minimal möglichen Zugriffsrechte erteilt wurden.

Sind Sie in Ihrem Projekt jemals auf eine SQL-Injection-Sicherheitslücke gestoßen? Oder haben Sie vielleicht noch weitere Tipps zur Prävention? Sagen Sie es uns in der Kommentarspalte – wer weiß, Ihre Erfahrung könnte anderen Entwicklern helfen.