Directory-Traversal
Directory Traversal – Grundlagen
- Kontext
- Software verwendet externe Daten, um einen Pfadnamen zu erzeugen
- Dateizugriffe sollen eigentlich nur unterhalb eines bestimmten Verzeichnisses erfolgen
- Schwachstelle
- Eingabedaten werden nicht richtig überprüft
- Angreifer kann spezielle Zeichenfolgen übergeben
- Angriff
- Angreifer übergibt manipulierte Daten
- Server greift auf Dateien außerhalb des erwünschten Verzeichnisses zu
- Ergebnis
- Unerlaubter Zugriff auf Dateien: ausführen, verändern, löschen, lesen
- Typische Szenarien
- URL-Parameter einer Web-Applikation
- Kommandozeilen-Parameter
Beispiel für Directory Traversal
Web-Server liefert Rechnungsdokumente aushttp://x/showbill?file=bill-1234_2010-06-01.pdf
Dateien liegen unter/srv/www/billapp/...
Angreifer versucht nun die folgenden URLs
http://x/showbill?file=../../../etc/passwdhttp://x/showbill?file=..%2F..%2F..%2Fetc/passwdhttp://x/showbill?file=..%252F..%252F..%252Fetc/passwdhttp://x/showbill?file=..%252F..%252F..%252Fetc/passwd%00.html
Beispiel: Directory Traversal
String filename = request.getParameter("file");
InputStream in = new FileInputStream(filename);
String ct = URLConnection.guessContentTypeFromStream(in);
response.setContentType(ct);
OutputStream out = response.getOutputStream();
byte[] buffer = new byte[1024];
int length;
// Datei ausgeben
while ((length = in.read(buffer)) >= 0) {
out.write(buffer, 0, length);
}
in.close();
Directory Traversal: Gegenmaßnahmen
- Keine Dateizugriffe basierend auf Benutzereingaben machen
- Dateinamen auf dem Server bestimmen und in Liste laden
- Liste zum Browser schicken und Eintrag auswählen lassen
- Index des Listeneintrags verwenden, um die Datei zu öffnen
- Wenn sich Zugriffe nicht vermeiden lassen
- Liste der erlaubten Verzeichnisse anlegen (Whitelist)
- Nur erwünschte Zeichen akzeptieren
- Pfadnamen normalisieren, z. B. mit
File.getCanonicalPath()in Java - Überprüfen, ob das Ergebnis mit der Whitelist übereinstimmt
Beispiel: Normalisierung von Pfaden
File root = new File("c:/img");
File f = new File(root, filename);
String canonicalPath = f.getCanonicalPath();
String rootPath = root.getCanonicalPath() + File.separatorChar;
if(!canonicalPath.startsWith(rootPath)) {
throw new IllegalArgumentException();
}
InputStream in = new FileInputStream(f);