Die VirtualPath
Bibliothek normalisiert Pfade und verhindert Directory-Traversal-Angriffe, ohne ein Dateisystem abzufragen.
Es wird empfohlen, den Abhängigkeitsmanager Composer zu verwenden, um rayne/virtual-path
zu installieren.
composer require rayne/virtual-path
Die VirtualPath
-Klasse normalisiert Eingaben in absolute virtual path , ohne ein Dateisystem abzufragen. Es erkennt und markiert auch Directory-Traversal-Angriffe.
Die JailedPath
-Klasse nutzt VirtualPath
, um sichere Pfade zu erstellen, die für die Arbeit mit echten Dateien verwendet werden können. Die Normalisierung erfolgt relativ zu einem jail
namens „Pfad“, das als virtuelles Stammverzeichnis für jeden vom Benutzer eingegebenen Pfad verwendet wird. Da JailedPath
das Dateisystem nicht abfragt, eignet es sich für die Arbeit mit lokalen, Remote- oder fiktiven Pfaden.
Weitere Einzelheiten finden Sie im Abschnitt „Implementierungsdetails“.
TL;DR Verwenden Sie im Zweifelsfall die Klasse JailedPath
.
JailedPath
In diesem Beispiel dürfen Website-Besucher jede Datei aus dem lokalen Verzeichnis /test
herunterladen, indem sie den relativen Pfad als GET
Parameter angeben. Um zu verhindern, dass Benutzer das Verzeichnis bei Directory-Traversal-Angriffen verlassen, wird JailedPath
mit /test
als virtuellem Stammverzeichnis verwendet.
<?php
use Rayne VirtualPath JailedPath ;
$ jailedPath = new JailedPath ( ' /test ' , $ _GET [ ' path ' ] ?? '' );
if ( $ jailedPath -> hasJailbreakAttempt ()) {
// Log jailbreak attempt, ban user, …
return ;
}
if ( is_file ( $ jailedPath -> getAbsolutePath ())) {
@ readfile ( $ jailedPath -> getAbsolutePath ());
}
Die folgende Tabelle zeigt, wie benutzerdefinierte Pfade normalisiert und relativ zum virtuellen Stamm interpretiert werden.
Benutzereingabe | hasJailbreakAttempt() | getAbsolutePath() | getRelativePath() |
---|---|---|---|
Leere Zeichenfolge | false | /test | Leere Zeichenfolge |
. | false | /test | Leere Zeichenfolge |
a.png/../b.png | false | /test/b.png | b.png |
/a/./b | false | /test/a/b | a/b |
.. | true | /test | Leere Zeichenfolge |
../example | true | /test/example | example |
../etc/passwd | true | /test/etc/passwd | etc/passwd |
Array | true | /test | Leere Zeichenfolge |
VirtualPath
Wenn kein festes Präfix oder der Zuckerüberzug von JailedPath
erforderlich ist, reicht VirtualPath
aus, da es sich um die Klasse handelt, die zum Normalisieren von Pfaden verwendet wird. VirtualPath
normalisiert die Eingabe und stellt einen vertrauenswürdigen (normalisiert, mit einem führenden /
) und einen nicht vertrauenswürdigen (eine Zeichenfolgendarstellung der wahrscheinlich böswilligen Benutzereingabe) Pfad bereit.
Das vorherige Beispiel kann einfach mit VirtualPath
neu erstellt werden, wenn die Instanz von VirtualPath
(die (string)
umwandelbar ist) an das virtuelle Stammverzeichnis angehängt wird.
<?php
use Rayne VirtualPath VirtualPath ;
$ path = new VirtualPath ( $ _GET [ ' path ' ] ?? '' );
$ absolutePath = ' /test ' . $ path ;
Abhängig vom Nutzungsszenario ist es manchmal nützlich, mit dem normalisierten vertrauenswürdigen Pfad zu arbeiten, auch wenn die ursprüngliche Eingabe nicht vertrauenswürdig ist, z. B. wenn explizit relative Pfade unterstützt werden und dem Benutzer im Zweifelsfall ein Vorteil gegeben wird, wenn er versehentlich versucht, auf Dateien außerhalb des virtual path zuzugreifen.
Hinweis : VirtualPath
gibt den normalisierten Pfad mit einem führenden /
zurück. Beim Arbeiten mit Dateien wird empfohlen, einen vertrauenswürdigen Pfad als Präfix hinzuzufügen (siehe Codebeispiel im aktuellen Abschnitt), da sonst auf Dateien verwiesen wird, die sich auf das Stammverzeichnis des Dateisystems beziehen. Um nicht zu vergessen, das Präfix hinzuzufügen, verwenden Sie stattdessen die Klasse JailedPath
wenn Sie mit echten Dateien arbeiten.
Eingang | isTrusted() | getTrustedPath() | getUntrustedPath() |
---|---|---|---|
Array | false | / | Leere Zeichenfolge |
Leere Zeichenfolge | true | / | Leere Zeichenfolge |
../articles | false | /articles | ../articles |
tags/../../articles | false | /articles | tags/../../articles |
tags/../articles | true | /articles | tags/../articles |
../etc/passwd | false | /etc/passwd | ../etc/passwd |
/etc/passwd | true | /etc/passwd | /etc/passwd |
etc/passwd | true | /etc/passwd | etc/passwd |
Die Verwendung eines rein virtuellen normalisierten Pfads hat verschiedene Vorteile:
Die Pfadnormalisierung erfolgt ohne Abfrage eines Dateisystems
Es ist unmöglich, Timing-Angriffe für Dateien außerhalb des virtual path zu fälschen
Es sind keine komplexen Vergleiche erforderlich, um Verzeichnisdurchläufe auf ein bestimmtes Verzeichnis und seine untergeordneten Verzeichnisse zu beschränken
Nur .
, ..
, (normalisiert auf
/
) und /
werden zur Pfadnormalisierung interpretiert
Keine unerwarteten und informationsleckenden ~
Erweiterungen wie in anderen Bibliotheken
Die Implementierung von VirtualPath
interpretiert, ändert oder entfernt keine Steuerzeichen und Unicode:
Auf einigen Systemen dürfen Verzeichnis- und Dateipfade Steuerzeichen enthalten
Das Entfernen von Steuerzeichen liegt außerhalb des Bereichs der Bibliothek
Klonen Sie das Repository
git clone https://github.com/rayne/virtual-path.git
Installieren Sie die Entwicklungsabhängigkeiten
composer install --dev
Führen Sie die Tests durch
composer test