Zwei Seiten derselben Medaille
Injection ist nicht auf Datenbanken beschränkt. Überall dort, wo Eingaben eines Nutzers direkt in Befehle oder Abfragen einfließen, kann es gefährlich werden. Zwei besonders relevante Varianten sind Command Injection (Angriffe auf Betriebssystembefehle) und NoSQL Injection (Angriffe auf moderne Datenbanken wie MongoDB). Beide zeigen: Injection ist ein grundsätzliches Designproblem – wenn Daten und Befehle nicht sauber getrennt sind, kann der Nutzer Kontrolle übernehmen.
Command Injection – Wenn Nutzer die Shell kapern
Was ist Command Injection?
Command Injection tritt auf, wenn eine Anwendung Nutzereingaben direkt in Systembefehle integriert. Statt nur das zu tun, was der Entwickler vorgesehen hat, führt die Anwendung plötzlich zusätzliche Befehle aus, die der Angreifer einschleust.
Das ist besonders gefährlich, weil Angreifer dadurch direkten Zugriff auf das Betriebssystem bekommen – im schlimmsten Fall können sie Dateien löschen, neue Benutzer anlegen oder das komplette System übernehmen.
Beispiel: Ping-Funktion in einer Web-App
Stell dir eine einfache Admin-Funktion vor, bei der man prüfen kann, ob ein Host erreichbar ist:
<?php
$ip = $_GET['ip'];
system("ping -c 4 " . $ip);
?>
Die Idee: Der Nutzer gibt eine IP-Adresse ein, die Anwendung hängt diese an den Befehl ping
an, und das Ergebnis wird angezeigt.
Klingt harmlos – ist es aber nicht.
Ein Angreifer gibt ein:
8.8.8.8; rm -rf /var/www/html
Der Befehl, den die Shell dann ausführt, lautet:
ping -c 4 8.8.8.8; rm -rf /var/www/html
Das erste Kommando führt den Ping aus – das zweite löscht die komplette Web-App.
Weitere Beispiele für Command Injection
- Log-Funktion:
os.system("echo " + userInput + " >> logfile.txt")
- Archivierung:
tar -czf backup.tar.gz "uploads/$filename"
Manipulierter Dateiname könnte zusätzliche Optionen einschleusen. - Externe Tools:
Wenn eine App z. B.ffmpeg
,imagemagick
oder andere Kommandozeilen-Programme aufruft, sind sie oft anfällig.
Angriffsvarianten
- Befehlstrennung:
;
,&&
,||
→ mehrere Befehle nacheinander. - Subshells:
$(...)
,`...`
→ Befehle in Befehlen. - Pipes:
|
→ Ausgaben umleiten und neue Kommandos starten.
Beispiel:
127.0.0.1 && cat /etc/passwd
Das erste Kommando pingt localhost, das zweite gibt die Passwort-Datei aus.
Schutzmaßnahmen gegen Command Injection
- Keine String-Konkatenation: Eingaben dürfen nie direkt in Shell-Befehle eingefügt werden.
- Sichere APIs verwenden: In Python z. B.
subprocess.run(["ping", "-c", "4", ip])
stattos.system("ping -c 4 " + ip)
. - Whitelist-Validierung: Nur erlaubte Eingaben zulassen (z. B. IPv4-Adressen per Regex).
- Sandboxing: Prozesse in eingeschränkten Umgebungen ausführen.
- Principle of Least Privilege: Der Prozess darf nicht als root laufen.
NoSQL Injection – Angriffe auf moderne Datenbanken
Hintergrund
NoSQL-Datenbanken wie MongoDB, CouchDB oder Elasticsearch sind sehr beliebt in modernen Web-Apps, vor allem im Zusammenhang mit Node.js und Microservices. Sie speichern Daten oft in JSON-Dokumenten und nutzen flexible Query-Sprachen.
Das Problem: Entwickler unterschätzen oft die Risiken – und implementieren die gleichen Fehler wie früher bei SQL.
Beispiel: Unsichere Login-Abfrage in MongoDB
Eine Node.js-App prüft Logins so:
db.users.find({
username: req.body.username,
password: req.body.password
});
Das sieht sicher aus, ist es aber nicht.
Ein Angreifer könnte Folgendes senden:
{
"username": {"$ne": null},
"password": {"$ne": null}
}
Die Abfrage lautet dann: „Finde alle Nutzer, bei denen Username und Passwort nicht null sind.“ Ergebnis: Es werden Nutzer zurückgegeben – der Login ist umgangen.
Typische Angriffe bei NoSQL
- Login-Bypass: Wie oben beschrieben – Bedingungen wie
$ne
oder$gt
sorgen dafür, dass Abfragen immer „wahr“ sind. - Data Extraction: Durch Kombination von Queries lassen sich Inhalte der Datenbank rekonstruieren.
- Denial of Service: Mit
$where
-Abfragen, die JavaScript enthalten, kann man rechenintensive Befehle einschleusen.
Beispiel:
{
"username": "alice",
"password": { "$gt": "" }
}
→ $gt
(größer als) mit leerem String matcht fast alles.
Blind NoSQL Injection
Wie bei SQL gibt es auch hier „Blind“-Varianten, wenn keine Fehlermeldungen angezeigt werden. Angreifer bauen dann Abfragen, die je nach Bedingung unterschiedliche Antwortzeiten erzeugen.
Beispiel:
{
"username": "alice",
"password": { "$where": "sleep(5000)" }
}
Wenn die Antwort verzögert kommt, weiß der Angreifer: Der Payload wurde interpretiert.
Schutzmaßnahmen gegen NoSQL Injection
- Parameterisierung: Auch bei NoSQL gibt es Libraries, die sichere Queries ermöglichen.
- Strikte Schema-Validierung: Eingaben gegen ein festes JSON-Schema prüfen (z. B. mit
joi
oderajv
in Node.js). - Whitelist für Operatoren: Nur erlaubte Query-Operatoren zulassen, keine dynamische Weiterleitung aller Felder.
- Konfigurationssicherheit: Admin-Interfaces von MongoDB & Co. niemals öffentlich erreichbar machen.
- Least Privilege: Applikationsnutzer darf nur minimale Rechte haben, keine Admin- oder Root-Rechte.
Gemeinsamkeiten und Unterschiede
Aspekt | Command Injection | NoSQL Injection |
---|---|---|
Zielsystem | Betriebssystem (Shell) | Datenbank (MongoDB, CouchDB, etc.) |
Angriffsvektor | Shell-Befehle einschleusen | JSON/Abfrage-Operatoren manipulieren |
Folgen | RCE, Systemübernahme | Login-Bypass, Datenklau, DoS |
Schutz | APIs statt Shell, Whitelists | Schema-Validierung, parametrisierte Queries |
Beide Varianten zeigen: Injection ist kein Relikt aus SQL-Zeiten, sondern betrifft auch moderne Technologien.
Was du mitnehmen solltest
- Command Injection erlaubt es, Shell-Befehle auszuführen – mit potenziell katastrophalen Folgen.
- NoSQL Injection ist ein moderneres Pendant, das oft unterschätzt wird – vor allem in Node.js-Stacks.
- Beide entstehen, weil Eingaben ungefiltert als Befehle behandelt werden.
- Schutz: Parametrisierung, Whitelists, sichere APIs, minimale Rechte.
Im nächsten Teil der Serie beschäftigen wir uns mit zwei weniger bekannten, aber sehr gefährlichen Varianten: Template Injection und LDAP Injection.
Schreibe einen Kommentar