PHP Manual
/
Безпека

Включити безпеку в PHP і прикріплення файлів

22. 08. 2019

Obsah článku

Часто нам може знадобитися прикріпити файл до сторінки, який ми зберігаємо на диску десь в іншому місці. Якщо ми вводимо його точну назву безпосередньо у функцію прикріплення, то турбуватися нема про що.

Безпечне прикріплення файлу

include 'menu.html';

Попередній запис абсолютно безпечний, оскільки ми завжди монтуємо один і той же файл. Помилка безпеки в цьому випадку виникнути не може. Єдина проблема, яка може виникнути - це відсутність файлу menu.html, що викличе попереджувальне повідомлення (яке, ймовірно, все одно не з'явиться), але така ситуація є рідкісною, оскільки ми зазвичай прикріплюємо файл, існування якого практично не викликає сумнівів.

Прикріплення файлу за зразком

Але що робити, якщо, наприклад, ми хочемо прикріпити статті до простого контент-сайту, як цей? На цьому сайті у мене є фізична папка, де зберігаються статті у форматі HTML і я прикріплюю їх безпосередньо до вихідного коду.

Однак, просто підключитися недостатньо! Початківець може так назвати окремі статті:

include 'статті/' . $_GET['Стаття'] . '.html';

Але це вкрай небезпечно. Зловмисник може передати посилання на інший каталог, використовуючи в назві статті ../ або щось подібне, а іноді вдається позбутися закінчення, передавши в кінці нульовий байт. Ви повинні як мінімум використовувати функцію basename(), а краще дозволити тільки значення білого списку.

Чому б не завантажувати нерелевантні файли?

Часто ми не заперечуємо проти завантаження некоректного (неочікуваного) файлу - користувач сам винен, що запросив сторінку, яка йому насправді не потрібна, але бувають ситуації, коли це має значення. Зокрема:

  • Користувач завантажує файл, до якого немає публічного доступу, а доступ до нього має лише сервер.
  • Завантаження іншого PHP-скрипта може викликати неочікувану дію або повідомлення про помилку, що може дати підказку про те, як працює сайт, і сприяти подальшим атакам.
  • Завантаження іншого файлу може призвести не тільки до його додавання в документ, але й до його запуску.

Білий список та перевірка вхідних даних

Якщо у нас немає можливості перевіряти вхідні дані якимось безпечним способом (наприклад, з білого списку), то все одно не варто покладатися на чесність користувача і захищати скрипти хоча б на рівні PHP.

Перше, що важливо - це помістити всі завантажені файли в одну папку (каталог) і відключити деякі небезпечні символи, особливо скісну риску і крапку. Це унеможливить доступ до інших папок, які містять потенційно вразливі файли. Відключення небезпечних символів також може бути здійснено простим видаленням їх з вхідного рядка.

$load = '../індекс'; // цей вхід може бути потенційно небезпечним
$load = strtr($load, './', ''); // видаляє з рядка всі крапки та скісні риски
include $load .'.html';

Запускаєш файли?

Важливо відзначити, що конструкція include виконує файли при підключенні так само, як якщо б вони були PHP-кодом, тому варто передбачити таку можливість.

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

$load = '../індекс'; // цей вхід може бути потенційно небезпечним
$load = strtr($load, './', ''); // видаляє з рядка всі крапки та скісні риски
$file = file_get_contents($load . '.html'); // завантаження вмісту в змінну
echo $file; // вивести вміст файлу

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

Розпізнавання потрібного файлу зі скрипта

Однозначного керівництва для цього немає, кожен має робити це самостійно відповідно до потреб сценарію. Наприклад, я розпізнаю статтю з інших файлів по тому, що в них є заголовок розміром H1. Тому якщо хтось завантажує файл, де немає заголовка, я нічого не відображаю і сторінка закінчується повідомленням про помилку. Завжди важливо знайти якусь унікальну особливість, яка є тільки у потрібних вам файлів, і якої немає в інших, і відштовхуватися від неї.

Висновок

Хоча перевірка та завантаження файлів є відносно простим процесом, велика кількість початківців все ще припускаються помилок - і будуть припускатися їх і надалі. Найголовніше - правильно зрозуміти сенс того, що ми завантажуємо, і як відрізнити потрібний нам контент від решти. І найголовніше - працювати з контентом як з рядком і ніколи не завантажувати його безпосередньо на сторінку.

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
Status:
All systems normal.
2024