Sicherheit/Directory Traversal

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Unter Directory Traversal oder auch Path Traversal versteht man eine Sicherheitslücke, bei der durch fehlende Validierung von Benutzereingaben auf beliebige Dateien und Verzeichnisse zugegriffen werden kann, die dafür eigentlich nicht vorgesehen waren. Diese kann so ausgenutzt werden, dass sensible Daten wie Passwörter preisgegeben werden.

Beispiel

Normalerweise sollte von außen nicht auf Dateien eines Webservers außerhalb des Web-Verzeichnisses oder dessen Unterverzeichnisse zugegriffen werden können. Bei einem Directory-Traversal-Angriff versucht ein Angreifer nun mittels manipulierter Pfadangaben auf Dateien außerhalb dieser Verzeichnisse zuzugreifen.[1]

Beispiel
<?php
$template = 'red.php';
if (isset($_GET['template'])) {
   $template = $_GET['template'];
}
include ("/home/users/phpguru/templates/" . $template);
?>
Obiger Code bindet ohne weitere Überprüfungen eine Datei ein, deren Name als URL-Parameter übergeben wird. Dies resultiert normalerweise in URLs wie der folgenden: https://example.org/vulnerable.php?template=page.php

Wenn nun folgender HTTP-Request gesendet würde …

Beispiel
GET /vulnerable.php?template=../../../../../../../../../etc/passwd HTTP/1.1

… würde damit folgendes Ergebnis erzielt:

Beispiel
HTTP/1.1 200 OK
Content-Type: text/html
Server: Apache

root:fi3sED95ibqR6:0:1:System Operator:/:/bin/ksh 
daemon:*:1:1::/tmp: 
phpguru:f8fk3j1OIf31.:182:100:Developer:/home/users/phpguru/:/bin/csh
Das angreifbare Skript wurde folglich beispielhaft dazu gebracht, die /etc/passwd des Systems auszuliefern.

Empfohlene Methoden

Um Directory Traversal Angriffe zu verhindern, sollten Sie …

  • URI Requests so verarbeiten, dass sie nicht direkt in Datei-Requests resultieren
Mit Listen arbeiten
<?php
// inkludierbare Dateien
$includes = array(
  'login' => 'template-login.html',
  'mail' => 'template-mail.html'
);

// gültige Datei angefordert?
if (array_key_exists('file', $_GET)
  && array_key_exists($_GET['file'], $includes)
) {
  include('path/to/files/'.$includes[$_GET['file']]);
}
Die zum Inkludieren möglichen Dateien werden in einem assoziativen Array definiert. Die include-Anweisung ergeht nur dann, wenn eine passende Ressource vom Server angefordert wurde, also wenn der URL-Parameter file existiert, und wenn er einen Wert enthält, zu dem das Array $includes einen gleichlautenden Schlüssel hat.
  • Wenn ein URI Request auf eine Datei oder ein Verzeichnis erfolgen soll, muss der normalisierte Pfad ermittelt (unter PHP mittels realpath() zu erreichen) und anschließend darauf überprüft werden, ob der mit einem oder mehreren erlaubten Pfaden beginnt:
Benutzung von realpath()
if (strpos (realpath($_GET['file']), '/absolute/allowed/path/') === 0) {
  include ($_GET['file']);
} else {
  // Fehlerbehandlung, z. B. abbrechen und Statuscode „403 Forbidden“ senden
}


Beachten Sie: Das Verwenden einer hartkodierten Dateiendung als Suffix-Ergänzung des Pfads ist wirkungslos:
Beispiel
<?php
include($_GET['file'] . '.html');
Durch die Verwendung des Nullzeichens (NULL, signalisiert das Ende des strings) kann alles nach dem $_GET umgangen werden, indem beispielsweise geheim.php\0 gesendet wird – alles nach dem Nullzeichen (dargestellt durch \0) wird ignoriert.

Quellen

  1. SELFHTML-Forum: Traversal Lücke vom 05.04.2016

Weblinks