SQL Injection: Angriffe, Schutzmaßnahmen & Prevention
Dieser Beitrag ist eine Begriffserklärung zu SQL Injection Angriffen – inklusive Schutzmaßnahmen und Best Practices.
In a Nutshell
SQL Injection ist eine Schwachstelle in Webanwendungen, bei der Angreifer manipulierte SQL-Befehle in Eingabefelder einschleusen, um unberechtigten Zugriff auf Datenbanken zu erhalten oder Daten zu verändern.
Kompakte Fachbeschreibung
SQL Injection ist eine der gefährlichsten und häufigsten Sicherheitslücken in Webanwendungen. Angreifer exploitieren unsichere Verarbeitung von Benutzereingaben, um eigene SQL-Befehle auszuführen.
Angriffsvektoren:
- Login-Formulare: Umgehung von Authentifizierung
- Suchfelder: Extraktion von Daten aus anderen Tabellen
- URL-Parameter: Manipulation von Datenbankabfragen
- API-Endpunkte: Direkte SQL-Kommandoausführung
Gefahren:
- Datenklau: Extraktion sensibler Informationen
- Datenmanipulation: Ändern oder Löschen von Daten
- Systemübernahme: Ausführung von Systembefehlen
- Denial of Service: Zerstören von Datenbankstrukturen
Prüfungsrelevante Stichpunkte
- Ziel: Zugriff auf, Veränderung oder Zerstörung von Datenbanken
- Ursache: Unsichere Übergabe von Nutzereingaben an Datenbank
- Typische Schwachstellen: Login-Formulare, Suchfelder, URL-Parameter
- Schutzmaßnahmen: Prepared Statements, Input-Validierung, ORM-Frameworks
- Beispiel-Angriff:
admin' OR '1'='1umgeht Passwortprüfung - OWASP A03: Injection ist Top 3 Sicherheitsrisiko
- Rechteprinzip: Kein Root-Zugriff für Web-Nutzer
- IHK-relevant: Wichtig für Softwarearchitektur und -entwicklung
Kernkomponenten
- Vulnerable Queries: Direkte String-Verkettung von SQL
- Prepared Statements: Parameterisierte Abfragen
- Input Validation: Whitelisting und Escaping
- ORM Frameworks: Hibernate, Entity Framework
- Least Privilege: Minimale Datenbankrechte
- Error Handling: Keine Datenbankfehler暴露
- Security Testing: Automatisierte Scanner
- Code Reviews: Manuelle Überprüfung
Praxisbeispiele
Verwundbarer Code
// SEHR GEFÄHRLICH - SQL Injection möglich
public User login(String username, String password) {
String query = "SELECT * FROM users WHERE username = '" +
username + "' AND password = '" + password + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
if (rs.next()) {
return new User(rs.getString("username"), rs.getString("role"));
}
return null;
}
// Angriff: username = "admin' OR '1'='1" -- "
// Ergebnis: SELECT * FROM users WHERE username = 'admin' OR '1'='1' -- ' AND password = ''
// Alle Benutzer werden zurückgegeben!
Sichere Alternative mit Prepared Statements
// SICHER - SQL Injection verhindert
public User login(String username, String password) {
String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement stmt = connection.prepareStatement(query);
stmt.setString(1, username);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
return new User(rs.getString("username"), rs.getString("role"));
}
return null;
}
Weitere Angriffsbeispiele
-- Union-Based Injection
' UNION SELECT username, password FROM admins --
-- Blind Injection
' AND (SELECT COUNT(*) FROM users WHERE username='admin' AND password LIKE 'a%') > 0 --
-- Time-Based Injection
' AND (SELECT SLEEP(5)) --
-- StoredProcedure Injection
'; DROP TABLE users; --
Schutzmaßnahmen
1. Prepared Statements (Parameterized Queries)
// Java
String sql = "SELECT * FROM products WHERE name = ? AND price < ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, productName);
stmt.setDouble(2, maxPrice);
// PHP mit PDO
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
// Python
cursor.execute("SELECT * FROM users WHERE id = %s", [user_id])
2. Input Validation & Escaping
// Whitelist-Validierung
public boolean isValidUsername(String username) {
return username.matches("^[a-zA-Z0-9_]{3,20}$");
}
// HTML-Escaping für Ausgaben
String safeOutput = StringEscapeUtils.escapeHtml4(userInput);
3. ORM Frameworks
// JPA/Hibernate
@Entity
@Table(name="users")
public class User {
@Id
private String username;
private String password;
// Automatische SQL-Erstellung, sicher vor Injection
}
public User findByUsername(String username) {
return entityManager.createQuery(
"SELECT u FROM User u WHERE u.username = :username", User.class)
.setParameter("username", username)
.getSingleResult();
}
4. Least Privilege Principle
-- Web-Anwendung bekommt nur notwendige Rechte
GRANT SELECT, INSERT, UPDATE ON app_db.users TO 'webapp'@'localhost';
-- KEINE DROP, DELETE, ALTER Rechte!
Vorteile und Nachteile von Schutzmaßnahmen
Vorteile
- Sicherheit: Verhindert Datenbankkompromittierung
- Compliance: Erfüllt Sicherheitsstandards (GDPR, ISO 27001)
- Vertrauen: Schützt Benutzerdaten und Unternehmensruf
- Kosteneffizienz: Verhindert teure Sicherheitsvorfälle
Nachteile
- Performance: Prepared Statements können langsamer sein
- Komplexität: Erfordert zusätzlichen Programmieraufwand
- Lernkurve: Entwickler müssen sicheres Programmieren lernen
- Testing: Zusätzliche Sicherheitstests erforderlich
Häufige Prüfungsfragen
-
Was ist SQL Injection und wie funktioniert sie? Einschleusen von SQL-Code über Benutzereingaben durch unsichere String-Verkettung.
-
Wie verhindert man SQL Injection am effektivsten? Durch Verwendung von Prepared Statements/Parameterized Queries.
-
Warum ist Input Validation allein nicht ausreichend? Validierung kann umgangen werden, Prepared Statements sind sicherer.
-
Welche Rolle spielt das Least Privilege Principle? Web-Anwendungen sollten nur minimale Datenbankrechte haben, um Schaden zu begrenzen.
Wichtigste Quellen
- https://owasp.org/www-community/attacks/SQL_Injection
- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
- https://portswigger.net/web-security/sql-injection