Vulnérabilités web Quand le restaurant laisse entrer n’importe qui

Path Traversal et Access Control, deux failles expliquées sans jargon, depuis l'architecture que tu connais déjà.

Dans l’article précédent, on a vu comment fonctionne un serveur web : Apache reçoit les requêtes, PHP prépare les pages, MariaDB stocke les données. On a aussi vu qu’il existe deux zones sur le disque — une zone publique que le serveur peut servir, et une zone privée qui ne devrait jamais être accessible depuis internet.

Aujourd’hui on va voir ce qui se passe quand cette frontière est mal gardée, ou carrément ignorée.

Partie 1 Path Traversal — le cuisinier qui sort de sa cuisine

L'image mentale

On reprends la métaphore du restaurant. Le cuisinier (PHP) a accès à toute la cuisine — les ingrédients du service, mais aussi les réserves personnelles du chef, les documents administratifs dans le bureau, les clés du sous-sol. Normalement il ne va chercher que ce qu’on lui demande pour les plats du menu.

Le Path Traversal, c’est quand un client mal intentionné lui glisse une commande bizarre : “Apporte-moi non pas le plat du jour, mais ce qu’il y a dans le tiroir du bureau au fond du couloir.” Et le cuisinier, sans réfléchir, s’exécute.

Comment ça se passe concrètement

Sur un site vulnérable, une URL qui affiche une photo ressemble à ça :

https://exemple.com/photo?fichier=photo_profil.jpg

Le serveur prend le nom du fichier que tu lui donnes et va le chercher dans son dossier photos. Le problème : il ne vérifie pas que tu restes bien dans ce dossier. Tu peux lui indiquer un chemin qui remonte dans l’arborescence du système avec la séquence ../ deux points et un slash, qui signifie “remonte d’un niveau”.

https://exemple.com/photo?fichier=../../../etc/passwd

Trois ../ et tu es sorti du dossier photos, remonté à la racine du système, et tu pointes vers /etc/passwd — le fichier qui liste tous les comptes utilisateurs du serveur Linux. Le cuisinier l’ouvre et te le sert comme si c’était une simple image.

Le cuisinier a les droits de lire les fichiers système. Si personne ne filtre ce qu’il reçoit, il obéit et il peut te donner des mots de passe, des clés de configuration, ou n’importe quel fichier sensible sur la machine.

Les fichiers que ça permet d'atteindre
  • /etc/passwd — la liste de tous les comptes du serveur Linux
  • /etc/shadow — les mots de passe chiffrés associés
  • config.php ou .env — souvent les identifiants de la base de données
  • Les logs, les clés SSH, les fichiers de configuration d’Apache lui-même
Et si le site essaie de se protéger ?

Certains développeurs ajoutent des filtres pour bloquer les séquences ../. Mais ces filtres sont souvent contournables, parce qu’il existe plusieurs façons d’écrire la même chose et le filtre ne les connaît pas toutes.

Encodage URL

Le filtre cherche ../ en clair. Si tu l’écris en code URL, il ne le voit pas, mais le système de fichiers, lui, le comprend quand même.

../ devient %2e%2e%2f

Double encodage

Le serveur décode une première fois et voit %2e%2e%2f le filtre passe. Le système de fichiers décode une deuxième fois et obtient ../.

../ devient %252e%252e%252f

Filtre qui supprime une seule fois

Le filtre retire ../ mais une seule passe. En cachant un ../ à l’intérieur d’un autre, après suppression il en reste un intact.

….// → après filtre → ../

Null byte

Le serveur vérifie que le fichier finit par .jpg. Le %00 tronque la chaîne  le système s’arrête là et ignore le reste.

../../../etc/passwd%00.jpg

La logique commune à tous ces bypasses : le filtre et le système de fichiers n’interprètent pas la même chose. Tu exploites cet écart.

La protection

Ne jamais construire un chemin de fichier depuis une entrée utilisateur sans vérifier que le chemin résolu reste bien dans le dossier autorisé. En PHP, realpath() résout le chemin réel tu vérifies ensuite qu’il commence bien par ta zone publique. Si ce n’est pas le cas, tu bloques.

Partie 2 Access Control — le videur qui ne vérifie pas les badges

L'image mentale

Retour au restaurant. Cette fois il y a une salle VIP à l’arrière réservée aux abonnés premium. À l’entrée, il y a un videur. Mais ce soir, le videur laisse passer tout le monde sans vérifier les badges. Il voit quelqu’un arriver, ouvre la porte, et voilà.

C’est exactement ça le Broken Access Control : le serveur sait qu’il existe des zones réservées, mais il oublie  ou néglige de vérifier si tu as vraiment le droit d’y entrer.

Les trois niveaux du contrôle d'accès

Avant d’entrer dans les attaques, une chose importante à comprendre : il y a trois questions distinctes qu’un système doit se poser à chaque requête.

Question 1

Qui es-tu ?

C’est l’authentification — vérifier ton identité via un mot de passe, un token, etc.

Question 2

C'est encore toi ?

C’est la gestion de session — s’assurer que c’est bien toi sur les requêtes suivantes.

Question 3

Tu as le droit ?

 C’est le contrôle d’accès — vérifier que ton rôle t’autorise à faire cette action précise.

Le Broken Access Control, c’est quand la question 3 est mal posée  ou pas posée du tout.

Scénario 1 — accès vertical : devenir admin sans l'être

Tu es un utilisateur normal. Tu découvres qu’en tapant /admin dans la barre d’adresse, la page d’administration s’affiche. Apache la transmet à PHP, PHP va chercher les données dans la base — et personne n’a vérifié ton rôle. Le videur était absent.

Ce qu’on cherche
  • Des URLs admin devinables : /admin, /dashboard, /console
  • Le fichier /robots.txt — les développeurs y listent parfois les pages à ne pas indexer, dont certaines sensibles
  • Le code source JavaScript de la page — il peut contenir des URLs cachées que le serveur pense secrètes
  • Des paramètres dans l’URL ou les cookies : ?role=admin, ?admin=true

Un paramètre comme role=user dans un cookie ne protège rien si le serveur lui fait confiance sans vérification côté backend. Tu changes user en admin dans les outils développeur, et le tour est joué.

Scénario 2 — accès horizontal : voir les données des autres

Tu es connecté avec ton compte. Tu remarques que l’URL de ton profil ressemble à ça :

https://exemple.com/moncompte?id=142

Tu changes 142 par 143. Si le serveur te renvoie le profil de quelqu’un d’autre  sans erreur, sans blocage  c’est une faille IDOR (Insecure Direct Object Reference). Traduction : une référence directe à un objet sans contrôle d’accès.

C’est comme un vestiaire avec des casiers numérotés. Tu as le casier 142. Tu essaies la clé sur le 143  et ça ouvre. Personne n’a vérifié que cette clé t’appartenait vraiment.

Scénario 3 — horizontal vers vertical : escalade en deux étapes

La combinaison la plus redoutable. Tu commences par une IDOR simple :

Étape 1

Tu testes ?id=1 souvent le compte admin, créé en premier.

Étape 2

La page affiche le profil admin avec son email, ou pire, la possibilité de changer son mot de passe.

Étape 3

Tu changes le mot de passe. Tu te connectes avec. Tu es admin.

Tu as commencé par accéder aux données d’un autre utilisateur (horizontal), et tu as fini par prendre le contrôle d’un compte supérieur (vertical). C’est pour ça qu’on parle d’escalade de privilèges.

La protection

La règle est simple : toujours vérifier côté serveur que l’utilisateur connecté a le droit d’accéder à la ressource qu’il demande. Jamais côté client  le JavaScript peut être modifié. Par défaut, tout accès est refusé sauf ce qui est explicitement autorisé. Et un ID d’objet dans une URL ne doit jamais suffire à prouver qu’on a le droit d’y accéder.

Ce qu'il faut retenir

Path Traversal — le cuisinier sort de sa cuisine. Il lit des fichiers qu’il ne devrait pas toucher parce que personne ne valide le chemin qu’on lui donne. La frontière zone publique / zone privée est traversée.

Broken Access Control — le videur est absent. Le serveur répond à des requêtes sans vérifier si l’utilisateur a le droit de les faire. Changer un paramètre dans l’URL suffit parfois à devenir admin.

Les deux failles partagent la même origine : faire confiance à ce qui vient du client. Tout ce qu’un navigateur envoie peut être modifié. La sécurité se construit côté serveur, pas côté navigateur..

 

DamSecFlow

Don’t Toast your Host