Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке обхід шляху (path traversal) і як захистити завантаження файлів за назвою?

Обхід шляху - назва файлу від користувача містить ../ і виводить за межі дозволеного каталогу:

// вразливо
Route::get('/download', function (Request $request) {
    return response()->download(storage_path('app/invoices/' . $request->query('file')));
});
// file=../../.env  →  storage/app/invoices/../../.env  →  .env застосунку

Так читають .env (ключі, паролі бази), конфігурацію, вихідний код, системні файли. У поєднанні із записом файлів (розпакування архівів, збереження за назвою від користувача) - перезапис коду й виконання команд.

Варіанти атаки, які наївна перевірка пропускає:

  • закодовані послідовності: %2e%2e%2f, подвійне кодування %252e;
  • зворотні слеші на Windows: ..\..\;
  • абсолютні шляхи: /etc/passwd;
  • Zip Slip: архів з файлом ../../public/shell.php - під час розпакування він опиниться поза цільовим каталогом.

Захист:

1. Не приймати шлях від користувача взагалі. Найкраще - ідентифікатор запису в базі, а шлях до файлу береться з бази:

Route::get('/invoices/{invoice}/download', function (Invoice $invoice) {
    Gate::authorize('view', $invoice);
    return Storage::disk('invoices')->download($invoice->path);
});

Заодно це вирішує й авторизацію: користувач отримує лише свій файл.

2. Якщо назва з запиту неминуча - лише ім'я файлу без каталогів і білий список символів:

$name = basename($request->query('file'));
abort_unless(preg_match('/^[a-z0-9_-]+\.pdf$/i', $name), 404);

3. Перевірка канонічного шляху:

$base = realpath(storage_path('app/invoices'));
$path = realpath($base . DIRECTORY_SEPARATOR . $name);
abort_unless($path !== false && str_starts_with($path, $base . DIRECTORY_SEPARATOR), 404);

4. Розпакування архівів - перевіряти кожен шлях усередині до запису.

Laravel Storage нормалізує шляхи й не дає вийти за корінь диска через ../ (Flysystem кидає виняток для шляхів за межами кореня). Але це не замінює перевірку прав: файл іншого користувача всередині того самого диска - вже не path traversal, а помилка авторизації.

Докладніше в документації: OWASP: Path Traversal

1

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання