flawopen.com/path-traversal/Php

● CWE-918 · Alta
Investigación · 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.

💡 Explicación en Lenguaje Sencillo (ELI5)

Imagina un escáner de llaves de hotel programado para abrir únicamente habitaciones del segundo piso. Si un huésped escribe '../../master-safe' en el teclado de la puerta, la cerradura vulnerable sube por el pasillo y abre la caja fuerte principal del gerente.

Conceptos Clave y Términos

Web Application Security
Componente de arquitectura central afectado por CWE-918.
CWE-918
Clasificación estándar Common Weakness Enumeration (CWE) para path-traversal-php.
Defense-in-Depth
Verificación de ingeniería multicapa y aislamiento de límites en tiempo de ejecución.

Flujo de Ataque Paso a Paso

Step 1

Entrada de Ruta de Archivo del Cliente

Un endpoint acepta un nombre de archivo o identificador de recurso provisto por el usuario vía parámetro HTTP.

Step 2

Inyección de Secuencias de Recorrido

El atacante inyecta secuencias relativas como '../', '..%2f' o rutas absolutas en el nombre del archivo.

Step 3

Evasión del Límite de Directorio

El backend concatena el archivo al directorio base sin resolver rutas canónicas ni validar límites seguros.

Step 4

Lectura o Sobrescritura Arbitraria de Archivos

El servidor lee y transmite archivos confidenciales del sistema (/etc/passwd, claves de entorno) al atacante.

Código Fuente: Vulnerable vs. Seguro

✕ IMPLEMENTACIÓN VULNERABLE
<?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);
?>
✓ PARCHE SEGURO Y ROBUSTO
<?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);
?>

Lista de Verificación de Seguridad para Ingeniería

References