La bibliothèque VirtualPath
normalise les chemins et empêche les attaques par traversée de répertoires sans interroger un système de fichiers.
Il est recommandé d'utiliser le gestionnaire de dépendances Composer pour installer rayne/virtual-path
.
composer require rayne/virtual-path
La classe VirtualPath
normalise les entrées en virtual path absolus sans interroger aucun système de fichiers. Il détecte et signale également les attaques par traversée de répertoires.
La classe JailedPath
utilise VirtualPath
pour créer des chemins sécurisés pouvant être utilisés pour travailler avec des fichiers réels. La normalisation se fait par rapport à une jail
appelée chemin qui est utilisée comme racine virtuelle pour tout chemin saisi par l'utilisateur. Comme JailedPath
n'interroge pas le système de fichiers, il est adapté pour travailler avec des chemins locaux, distants ou fictifs.
Veuillez lire la section Détails de mise en œuvre pour plus de détails.
TL;DR Utilisez la classe JailedPath
en cas de doute.
JailedPath
Dans cet exemple, les visiteurs du site Web sont autorisés à télécharger n'importe quel fichier du répertoire local /test
en spécifiant le chemin relatif comme paramètre GET
. Pour empêcher les utilisateurs de quitter le répertoire avec des attaques par traversée de répertoire, JailedPath
est utilisé avec /test
comme répertoire racine virtuel.
<?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 ());
}
Le tableau suivant montre comment les chemins définis par l'utilisateur sont normalisés et comment ils sont interprétés par rapport à la racine virtuelle.
Entrée de l'utilisateur | hasJailbreakAttempt() | getAbsolutePath() | getRelativePath() |
---|---|---|---|
Chaîne vide | false | /test | Chaîne vide |
. | false | /test | Chaîne vide |
a.png/../b.png | false | /test/b.png | b.png |
/a/./b | false | /test/a/b | a/b |
.. | true | /test | Chaîne vide |
../example | true | /test/example | example |
../etc/passwd | true | /test/etc/passwd | etc/passwd |
Tableau | true | /test | Chaîne vide |
VirtualPath
Si un préfixe fixe ou l'enrobage de JailedPath
n'est pas requis, alors VirtualPath
est suffisant car il s'agit de la classe utilisée pour normaliser les chemins. VirtualPath
normalise l'entrée et fournit un chemin fiable (normalisé, avec un /
) et un chemin non fiable (une représentation sous forme de chaîne de l'entrée utilisateur probablement malveillante).
L'exemple précédent peut être facilement recréé avec VirtualPath
lorsque l'instance de VirtualPath
(qui est (string)
castable) est ajoutée au répertoire racine virtuel.
<?php
use Rayne VirtualPath VirtualPath ;
$ path = new VirtualPath ( $ _GET [ ' path ' ] ?? '' );
$ absolutePath = ' /test ' . $ path ;
Selon le scénario d'utilisation, il est parfois utile de travailler avec le chemin de confiance normalisé même si l'entrée d'origine n'est pas digne de confiance, par exemple lors de la prise en charge explicite des chemins relatifs et en donnant à l'utilisateur le bénéfice du doute lorsqu'il tente accidentellement d'accéder à des fichiers en dehors du virtual path .
Remarque : VirtualPath
renvoie le chemin normalisé précédé d'un /
. Lorsque vous travaillez avec des fichiers, il est recommandé d'ajouter un chemin approuvé comme préfixe (voir l'exemple de code dans la section actuelle), sinon les fichiers relatifs à la racine du système de fichiers seraient référencés. Pour ne pas oublier d'ajouter le préfixe, utilisez plutôt la classe JailedPath
lorsque vous travaillez avec de vrais fichiers.
Saisir | isTrusted() | getTrustedPath() | getUntrustedPath() |
---|---|---|---|
Tableau | false | / | Chaîne vide |
Chaîne vide | true | / | Chaîne vide |
../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 |
L’utilisation d’un chemin normalisé virtuel pur présente différents avantages :
La normalisation du chemin se fait sans interroger un système de fichiers
Il est impossible de forger des attaques temporelles pour des fichiers en dehors de la portée du virtual path
Aucune comparaison complexe n'est requise pour limiter les traversées de répertoires à un répertoire spécifique et à ses enfants
Seulement .
, ..
, (normalisé en
/
) et /
sont interprétés pour la normalisation du chemin
Pas d'inattendu ni de fuite d'informations ~
extensions comme on le voit dans d'autres bibliothèques
L'implémentation de VirtualPath
n'interprète, ne modifie ni ne supprime les caractères de contrôle et Unicode :
Les chemins de répertoire et de fichier peuvent contenir des caractères de contrôle sur certains systèmes
La suppression des caractères de contrôle est hors de portée de la bibliothèque
Cloner le référentiel
git clone https://github.com/rayne/virtual-path.git
Installer les dépendances de développement
composer install --dev
Exécutez les tests
composer test