Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
modul:m183:learningunits:lu10:03 [2025/09/19 08:09] – angelegt vdemir | modul:m183:learningunits:lu10:03 [2025/09/19 10:37] (aktuell) – vdemir | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
====== LU10c - SQLi Gegenmassnahmen ====== | ====== LU10c - SQLi Gegenmassnahmen ====== | ||
+ | |||
+ | Glücklicherweise gibt gegen alle SQLi-Varianten entsprechende Gegenmassnahmen. Die hier vorliegende Liste ist daher nur ein Ausschnitt mit den prominentesten. | ||
+ | |||
+ | ===== Escaping ===== | ||
+ | |||
+ | Beim // | ||
+ | |||
+ | {{: | ||
+ | |||
+ | Das Hauptproblem bei SQLI besteht darin, dass Werte ungeprüft in die Datenbank weitergegeben werden, wobei Platzhalter mit vom User zur Laufzeit eingegebenen Werten angereichert werden. Enthält eine solcher zur Laufzeit generierte SQL-Anweisung Injektion, wird diese ungeprüft und ungepuffert an die DB weitergeleitet. | ||
+ | |||
+ | ===== Parametrisierte Werteübergabe ===== | ||
+ | Die // | ||
+ | |||
+ | **Beispiel mit JavaScript/ | ||
+ | |||
+ | // 1. Schritt: Zusammenbau des SQL-Statements mit Platzhaltern | ||
+ | const sql1 = ` | ||
+ | UPDATE Production.ProductInventory | ||
+ | SET Quantity = @qty | ||
+ | WHERE ProductID = @productId | ||
+ | `; | ||
+ | |||
+ | // 2. Schritt: Parametrisieren der Übergabewerte | ||
+ | const qty = 10; | ||
+ | const productId = 709; | ||
+ | |||
+ | // 3. Schritt: Zusammenbauen und Ausführen mit Laufzeitwerten | ||
+ | const sql = require(' | ||
+ | async function updateInventory() { | ||
+ | try { | ||
+ | // Verbindung herstellen (Beispielconfig anpassen!) | ||
+ | const pool = await sql.connect({ | ||
+ | user: ' | ||
+ | password: ' | ||
+ | server: ' | ||
+ | database: ' | ||
+ | }); | ||
+ | // | ||
+ | const request = pool.request(); | ||
+ | request.input(' | ||
+ | request.input(' | ||
+ | // | ||
+ | const result = await request.query(sql1); | ||
+ | console.log(' | ||
+ | } catch (err) { | ||
+ | console.error(' | ||
+ | } | ||
+ | } | ||
+ | updateInventory(); | ||
+ | |||
+ | ===== Input Validation ===== | ||
+ | **Input Validation** bedeutet, dass alle Eingaben aus unsicheren Quellen (User, Formulare, API-Aufrufe, | ||
+ | |||
+ | **Oder kurz:** <color # | ||
+ | | ||
+ | ===== Prepared Statement ===== | ||
+ | Ein //Prepared Statement// trennt klar Code (das SQL) von Daten (Benutzereingaben). Dadurch kann ein Angreifer die Struktur der Abfrage nicht durch manipulierte Eingaben verändern — und genau das ist der Kern jeder SQL-Injection. | ||
+ | |||
+ | **Wie funktionieren sie? | ||
+ | |||
+ | - Die Anwendung schickt ein SQL-Template an die Datenbank, in dem Platzhalter statt konkreter Werte stehen. | ||
+ | * Beispiel (pseudo): SELECT * FROM users WHERE id = ? | ||
+ | - Die Datenbank parst und compiliert dieses Template, legt einen Ausfuehrungsplan an. | ||
+ | - Zur Laufzeit werden die Platzhalter separat mit Werten gefuellt — diese Werte werden nie als Teil des SQL-Codes interpretiert, | ||
+ | |||
+ | Ergebnis: Eingaben wie 1; DROP TABLE users; koennen nicht als zusätzlicher SQL-Code ausgefuehrt werden — sie landen als sicherer Datenwert in der Abfrage. | ||
+ | |||
+ | **Warum das gegen SQLi hilft** | ||
+ | |||
+ | * **Trennung von Code und Daten:** Eingaben koennen die SQL-Syntax nicht mehr verändern. | ||
+ | * **Schutz gegen die meisten Angriffsvarianten: | ||
+ | * Performance-Bonus: | ||
+ | |||
+ | **Beispiel JavaScript** | ||
+ | Die Werte in [...] sind rein Daten — kein Code. | ||
+ | |||
+ | // Platzhalter $1, $2 — Parameter separat uebergeben | ||
+ | const sql = ' | ||
+ | await client.query(sql, | ||
+ | |||
+ | ===== Stored Procedure ===== | ||
+ | Kurzfassung zuerst: Stored Procedures (SPs) verlagern SQL-Logik in die Datenbank. Richtig verwendet trennen sie Code (die prozedurale Logik in der DB) von Daten (die Parameter), reduzieren Angriffsflächen und erleichtern Zugriffssteuerung. Keine Zauberformel — sie helfen, sind aber kein Freifahrtschein. | ||
+ | |||
+ | {{: | ||
+ | |||
+ | **Wie stored procedures grundsätzlich schützen** | ||
+ | * Die SQL-Struktur liegt in der Datenbank und nicht in applikationsseitig zusammengesetzten Strings. | ||
+ | * Parameter werden (wenn sie als Parameter benutzt werden) von der DB engine als Daten behandelt — nicht als Teil des SQL-Codes. | ||
+ | * DB-Accounts können nur EXECUTE-Rechte auf die SP erhalten, nicht direkte SELECT/ | ||
+ | * SPs erlauben zentralisierte Validierung/ | ||
+ | |||
+ | **Kurz:** SP machen es einem Angreifer schwerer, per manipulierten Input die Abfrage-Struktur zu verändern — sofern diese nicht durch unsauberen Code zunichte gemacht wurde. | ||
+ | |||
+ | |||
+ | |||
---- | ---- | ||
[[https:// | [[https:// |