Vous subissez une attaque ? Faire appel à notre réponse aux incidents

Développement sécurisé

Path traversal : utilisez des ID, vérifiez le chemin résolu

Repérez les lectures, téléchargements et includes acceptant ../ et corrigez-les avec des ID et un contrôle du chemin canonique, pas des blocklists.

Aussi en :EnglishTürkçeDeutschEspañolItalianoPolskiNederlandsEesti

Illustration : Path traversal : utilisez des ID, vérifiez le chemin résolu

Le path traversal existe partout où votre code utilise une entrée externe pour construire un chemin d'accès sans empêcher que ce chemin se résolve en dehors du répertoire prévu. CWE-22 est l'entrée qui le décrit. Recensez chacun de ces endroits, cessez de laisser les utilisateurs fournir des noms de fichiers et, pour les entrées qui subsistent, vérifiez le chemin résolu.

Ce que gagne un attaquant

La lecture n'est qu'un début. Selon ce que le code fait du chemin, un attaquant peut lire des fichiers inattendus et exposer des données sensibles, créer ou écraser des programmes et des bibliothèques pour exécuter du code, ou corrompre des fichiers jusqu'à ce que le produit cesse de fonctionner ou que les utilisateurs soient verrouillés. OWASP cite le code source de l'application et les fichiers de configuration parmi les fichiers accessibles.

Les fichiers protégés par un mécanisme de sécurité sont les pires cibles. Lire un fichier de mots de passe permet de mener des attaques par force brute sur les comptes, et y ajouter un nouveau compte peut contourner l'authentification.

La portée dépend de la plateforme. Sous Windows, un attaquant ne peut se déplacer qu'au sein de la partition qui contient la racine web, sous Linux sur l'ensemble du disque. Les contrôles d'accès du système d'exploitation continuent de s'appliquer en plus.

Repérer les endroits qui construisent des chemins

Partez du sink, pas de l'URL. Listez chaque appel qui ouvre, lit, sert, inclut ou écrit un fichier, puis remontez chaque argument de chemin jusqu'à son origine. Tout ce qui touche à la requête va sur la liste, y compris les appels cachés derrière vos propres fonctions d'encapsulation et les helpers de framework : vérifiez donc aussi leurs appelants.

L'entrée est plus large que la query string. Les exemples d'OWASP comprennent get-files.jsp?file=report.pdf, get-page.php?home=aaa.html et some-page.asp?page=index.html, mais aussi un cookie. Cet extrait est adapté de l'exemple d'OWASP (à l'origine de Wikipedia) :

$template = 'blue.php';
if ( isset( $_COOKIE['TEMPLATE'] ) )
    $template = $_COOKIE['TEMPLATE'];
include ( "/home/users/phpguru/templates/" . $template );

Un cookie TEMPLATE=../../../../../../../../../etc/passwd fait remonter include() jusqu'au répertoire racine et renvoie le fichier de mots de passe. Les paramètres nommés file, page, template ou f sont les suspects habituels, mais les noms ne sont pas un critère fiable. Suivez les données.

Vérifiez trois formes :

  • Traversée relative : les séquences ../ qui sortent du répertoire prévu.
  • Chemins absolus : ?f=/etc/passwd ou ?f=/var/www/html/get.php, qui fonctionnent quand l'entrée est utilisée comme chemin complet.
  • Inclusions distantes : ?page=http://other-site/... lorsque le mécanisme d'inclusion accepte des URL.

Les messages d'erreur verbeux aident l'attaquant, car ils révèlent de vrais chemins sur lesquels s'appuyer. Vérifiez ce que renvoie votre application lorsqu'un fichier est absent.

Pourquoi les blocklists échouent

Supprimer ../ ne fonctionne pas, car la même traversée s'écrit de nombreuses façons :

  • %2e%2e%2f, ..%2f et %2e%2e/ signifient tous ../.
  • ..%5c et %2e%2e%5c signifient ..\, ce qui compte sous Windows, où les deux séparateurs fonctionnent.
  • %252e%252e%255c est la forme doublement encodée de ..\. Les conteneurs web effectuent un seul niveau de décodage, de sorte qu'elle arrive encore encodée. Si votre code ou une bibliothèque la décode une seconde fois, elle devient une traversée après l'exécution du contrôle.
  • ..%c0%af et ..%c1%9c sont d'autres encodages de ../ et ..\.
  • Un octet nul, comme dans ?file=secret.doc%00.pdf, peut faire voir .pdf à une application Java alors que le système d'exploitation voit .doc. Les attaquants s'en servent pour contourner la validation.

Le filtrage se retourne aussi contre lui-même. Si l'on retire ../ de façon séquentielle dans .../...//, les caractères restants reforment ../. Filtrer uniquement / est inutile si le système de fichiers accepte \.

Première correction : cesser d'accepter des chemins

Le meilleur contrôle consiste à retirer l'entrée utilisateur du chemin. Utilisez des index plutôt que des fragments de noms de fichiers. L'exemple d'OWASP est un fichier de langue : l'utilisateur envoie 5 et le serveur fait correspondre cette valeur à la langue, au lieu de faire confiance à un nom renvoyé.

Pour les téléchargements, stockez les fichiers sous un ID et servez-les par ID, de sorte que l'utilisateur ne fournisse jamais ni nom ni extension. L'exemple du template devient :

$templates = [1 => 'blue.php', 2 => 'red.php'];
$id = (int) ($_COOKIE['TEMPLATE'] ?? 1);
$template = $templates[$id] ?? 'blue.php';
include '/home/users/phpguru/templates/' . $template;

Si vous devez absolument accepter un nom, validez-le par rapport à des valeurs connues et rejetez le reste. Utilisez une allowlist stricte de caractères, au plus un . dans le nom de fichier, aucun séparateur de répertoire, et une liste d'extensions autorisées. Rejetez les entrées invalides plutôt que d'essayer de les assainir.

Seconde correction : canonicaliser, puis vérifier

Lorsque l'entrée doit atteindre une API de fichiers, décodez-la une seule fois, puis résolvez-la avec une fonction de canonicalisation native avant de la valider :

LangageFonction
Crealpath()
JavagetCanonicalPath()
ASP.NETGetFullPath()
Perlrealpath() ou abs_path()
PHPrealpath()

Ces fonctions suppriment les séquences .. et les liens symboliques. Après la résolution, vérifiez que le résultat se trouve toujours dans votre répertoire de base et refusez la requête dans le cas contraire. Un exemple en PHP, avec $name ayant déjà passé l'allowlist :

$base = realpath('/home/users/phpguru/templates');
$full = realpath($base . '/' . $name);
if ($full === false || strpos($full, $base . DIRECTORY_SEPARATOR) !== 0) {
    http_response_code(404);
    exit;
}

Conservez tous les contrôles côté serveur. La validation côté client se contourne trivialement.

Limiter les dégâts

Gardez les fichiers de configuration sensibles en dehors de la racine web. Sous Windows avec IIS, placez la racine web ailleurs que sur le disque système, afin que la traversée ne puisse pas atteindre les répertoires système. Les jails chrootées et les politiques d'accès au code restreignent les emplacements où des fichiers peuvent être lus ou écrits, et elles limitent les dégâts lorsqu'un contrôle a été oublié.

Pour les tests, rejouez les encodages ci-dessus sur chaque paramètre identifié, ainsi qu'un chemin absolu et une URL distante. Un test d'intrusion le fera de manière systématique.

Par où commencer

  1. Listez chaque appel de manipulation de fichiers dans votre code, ajoutez les fonctions d'encapsulation et les helpers de framework qui les entourent, et remontez chaque argument de chemin jusqu'à sa source, y compris les cookies et les en-têtes.
  2. Remplacez les noms de fichiers fournis par l'utilisateur par des ID associés à des fichiers sur le serveur, en commençant par les téléchargements et la sélection de templates ou de langues.
  3. Pour tout cas restant, décodez une seule fois, canonicalisez avec la fonction de la plateforme et rejetez tout ce qui se résout en dehors du répertoire de base.
  4. Supprimez le code de blocklist qui retire ../ ou /, et remplacez-le par une allowlist de caractères, d'extensions et, si possible, de valeurs.
  5. Déplacez la configuration sensible hors de la racine web et cessez de renvoyer des messages d'erreur qui révèlent des chemins de fichiers.
  6. Testez chaque paramètre avec les variantes encodées, doublement encodées, absolues et distantes, et conservez ces cas comme tests de non-régression.

Comment nous pouvons vous aider

Développement sécurisé

Nous intégrons la sécurité aux logiciels dès le premier commit, et nous développons nos propres outils de sécurité.

Nous contacter
Équipe AngelForce

Rédigé par l’équipe AngelForce : des consultants en sécurité certifiés CEH, LPT Master et CISA qui testent, surveillent et protègent les systèmes d’organisations dans toute l’Europe.

Rédigé avec l’aide de l’IA à partir des sources publiques indiquées sur cette page, puis relu par l’équipe AngelForce avant publication.

Sources

  1. community.owasp.org/attacks/Path_Traversal
  2. cwe.mitre.org/data/definitions/22.html

Articles : Développement sécurisé

Dites-nous ce que vous devez protéger

Décrivez votre environnement et vos objectifs. Nous vous répondrons par e-mail.

Nous contacter
info@angelforce.eu +372 5705 2044

AngelForce OÜ · Tallinn, Estonie