flawopen.com/path-traversal/Php

● CWE-918 · Высокий
Исследования · 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.

💡 Простыми словами (ELI5)

Представьте электронный замок в отеле, запрограммированный открывать только номера на втором этаже. Если гость вводит на панели '../../master-safe', уязвимый замок выходит в коридор и открывает главный сейф управляющего.

Ключевые понятия и термины

Web Application Security
Технический термин (Web Application Security): Core architecture component affected by CWE-918.
CWE-918
Технический термин (CWE-918): Standard Common Weakness Enumeration classification for path-traversal-php.
Defense-in-Depth
Технический термин (Defense-in-Depth): Multi-layered engineering verification and runtime boundary isolation.

Пошаговый сценарий атаки

Step 1

Передача пути к файлу клиентом

Конечная точка принимает имя файла или путь к документу через параметр HTTP-запроса.

Step 2

Внедрение последовательностей обхода каталогов

Злоумышленник передает последовательности '../', '..%2f' или абсолютные пути для выхода из базового каталога.

Step 3

Преодоление границ файловой системы

Бэкенд конкатенирует путь без канонизации и проверки того, что результирующий путь находится внутри базовой папки.

Step 4

Несанкционированное чтение системных файлов

Сервер считывает и передает клиенту конфиденциальные файлы операционной системы (например, /etc/passwd).

Исходный код: Уязвимый vs Защищённый вариант

✕ УЯЗВИМАЯ РЕАЛИЗАЦИЯ
<?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);
?>
✓ БЕЗОПАСНЫЙ ИСПРАВЛЕННЫЙ ВАРИАНТ
<?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);
?>

Чек-лист по защите системы для инженеров

References