flawopen.com/path-traversal/Php

● CWE-918 · Haute
Recherche · FlawOpen

Path Traversal in PHP

How include and file_get_contents suffer from path traversal, and how to verify boundaries using realpath and str_starts_with.

💡 Explication en Langage Simple (ELI5)

Imaginez un lecteur de carte d'hôtel programmé pour n'ouvrir que les chambres du 2e étage. Si un client tape '../../master-safe' sur le digicode, la serrure vulnérable remonte le couloir et déverrouille le coffre-fort principal du gérant.

Concepts Clés et Termes

Web Application Security
Composant d'architecture clé affecté par CWE-918.
CWE-918
Classification standard Common Weakness Enumeration (CWE) pour path-traversal-php.
Defense-in-Depth
Vérification d'ingénierie multicouche et isolation des limites à l'exécution.

Déroulement de l'Attaque Étape par Étape

Step 1

Saisie de Chemin de Fichier par le Client

Un point de terminaison accepte un nom de fichier ou un identifiant de ressource via un paramètre HTTP.

Step 2

Injection de Séquence de Traversée de Répertoire

L'attaquant injecte des séquences relatives comme '../', '..%2f' ou des chemins absolus non autorisés.

Step 3

Contournement de la Limite du Système de Fichiers

Le backend concatène naïvement le fichier sans vérifier le chemin canonique ni restreindre le répertoire racine.

Step 4

Divulgation ou Écriture Arbitraire de Fichiers

Le runtime ouvre et renvoie des fichiers système critiques (/etc/passwd, secrets d'API) à l'attaquant.

Code Source : Vulnérable vs Sécurisé

✕ IMPLÉMENTATION VULNÉRABLE
<?php
// VULNERABLE: Direct concatenation in file read
$base_dir = '/var/www/uploads';
$file = $_GET['file'];

// Attacker input: ../../../../etc/passwd
$path = $base_dir . '/' . $file;

// Dumps arbitrary server file to user
readfile($path);
?>
✓ PATCH SÉCURISÉ ET ROBUSTE
<?php
// HARDENED: Canonicalize with realpath and enforce directory prefix check
$base_dir = realpath('/var/www/uploads');
$file = $_GET['file'] ?? '';

if (!is_string($file) || empty($file)) {
    http_response_code(400);
    exit('Invalid file parameter');
}

// 1. Resolve canonical path
$real_target = realpath($base_dir . DIRECTORY_SEPARATOR . $file);

// 2. Strict boundary check (ensure prefix matches base_dir + separator)
$expected_prefix = $base_dir . DIRECTORY_SEPARATOR;
if ($real_target === false || !str_starts_with($real_target, $expected_prefix)) {
    http_response_code(403);
    exit('Forbidden: Path Traversal detected');
}

if (!is_file($real_target)) {
    http_response_code(404);
    exit('File not found');
}

readfile($real_target);
?>

Liste de Contrôle de Sécurité pour l'Ingénierie

References