IT-Sicherheit

SQL Injection – Die häufigste Web-Schwachstelle erklärt

Kevin KrögerIT-Sicherheit

SQL Injection ist die wahrscheinlich häufigste und gefährlichste Web-Schwachstelle. Auf fast jeder Liste von Top Hacking-Techniken steht sie ganz oben. Und das Beste: Sie ist extrem einfach zu preventen.

Wie funktioniert SQL Injection?

Stell dir vor, du hast eine einfache Login-Form. Der Code sieht so aus: ```python username = request.form.get("username") password = request.form.get("password") query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'" result = execute_query(query) ``` Alles normal, oder? Der Benutzer gibt seinen Username und Passwort ein, die werden in die SQL-Query eingefügt, und die Datenbank gibt zurück ob es einen Match gibt. Aber: Was ist wenn der Benutzer statt eines normalen Usernames etwas böses eingibt? ``` username: admin' -- password: whatever ``` Die generierte Query wird: ```sql SELECT * FROM users WHERE username = 'admin' --' AND password = 'whatever' ``` Beachte das `--`. In SQL ist das ein Kommentar. Alles danach wird ignoriert. Also wird die Query zu: ```sql SELECT * FROM users WHERE username = 'admin' ``` Und boom: Der Attacker loggt sich als Admin ein, ohne das Passwort zu wissen. Das ist SQL Injection in seiner einfachsten Form.

Komplexere Attacks

SQL Injection kann viel schlimmer sein. Ein Attacker kann: - Alle Daten aus der Datenbank auslesen - Daten löschen (DROP TABLE users) - Daten ändern (UPDATE users SET admin = 1) - In manche Fällen: Kommandos auf dem Server ausführen Beispiel: ``` username: ' OR '1'='1' -- password: whatever ``` Die Query wird: ```sql SELECT * FROM users WHERE username = '' OR '1'='1' --' AND password = 'whatever' ``` Und `'1'='1'` ist immer true. Also gibt die Query alle User zurück.

Warum ist das so verbreitet?

Weil Entwickler diesen mistake machen: ```python # FALSCH – Vulnerable: query = f"SELECT * FROM users WHERE email = '{email}'" ``` Das ist so einfach – und es funktioniert für normale Inputs. Ein Entwickler sieht keinen Grund, es zu ändern. Aber ein Hacker findet die Lücke sofort.

Wie man sich schützt: Prepared Statements

Die Lösung ist einfach: Prepared Statements. ```python # RICHTIG – Safe: cursor.execute("SELECT * FROM users WHERE email = ?", (email,)) ``` Der Unterschied: Die Query und die Daten sind separiert. Die SQL-Query ist fix. Die Daten werden als Daten behandelt, nicht als Code. SQL kann nicht injiziert werden. Das ist die gesamte Sicherheit – ein einfacher Syntax-Change.

In verschiedenen Sprachen

Python: ```python cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,)) ``` PHP: ```php $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$user_id]); ``` JavaScript/Node: ```javascript connection.query('SELECT * FROM users WHERE id = ?', [userId], callback); ``` Java: ```java PreparedStatement stmt = connection.prepareStatement("SELECT * FROM users WHERE id = ?"); stmt.setInt(1, userId); ``` Alle modernen Frameworks haben Prepared Statements. Kein Grund, sie nicht zu nutzen.

ORMs helfen auch

Wenn du ein ORM nutzt (Django ORM, Hibernate, Sequelize, etc.), bist du meist automatisch geschützt: ```python # Django ORM – Safe by default: User.objects.filter(email=email) ``` Das generiert intern Prepared Statements. Aber: ORMs können auch vulnerable sein, wenn du raw queries schreibst. Also sei vorsichtig.

Häufiger Fehler: "Filter" statt "Prepared Statements"

Einige Entwickler denken, sie können sich schützen durch Input-Filtering: ```python # FALSCH – Unsicher: email = email.replace("'", "") # Remove quotes query = f"SELECT * FROM users WHERE email = '{email}'" ``` Das ist nicht sicher. Ein Attacker kann Wege finden, um die Filter zu bypass. Prepared Statements ist der einzige sichere Weg.

Fazit

SQL Injection ist easy zu preventern – nutze Prepared Statements. Das ist es. Es ist ein One-Line-Fix und es eliminiert die gesamte SQL Injection-Klasse von Vulnerabilities.

Häufige Fragen