Часто нам може знадобитися прикріпити файл до сторінки, який ми зберігаємо на диску десь в іншому місці. Якщо ми вводимо його точну назву безпосередньо у функцію прикріплення, то турбуватися нема про що.
include 'menu.html';
Попередній запис абсолютно безпечний, оскільки ми завжди монтуємо один і той же файл. Помилка безпеки в цьому випадку виникнути не може. Єдина проблема, яка може виникнути - це відсутність файлу menu.html, що викличе попереджувальне повідомлення (яке, ймовірно, все одно не з'явиться), але така ситуація є рідкісною, оскільки ми зазвичай прикріплюємо файл, існування якого практично не викликає сумнівів.
Але що робити, якщо, наприклад, ми хочемо прикріпити статті до простого контент-сайту, як цей? На цьому сайті у мене є фізична папка, де зберігаються статті у форматі HTML і я прикріплюю їх безпосередньо до вихідного коду.
Однак, просто підключитися недостатньо! Початківець може так назвати окремі статті:
include 'статті/' . $_GET['Стаття'] . '.html';
Але це вкрай небезпечно. Зловмисник може передати посилання на інший каталог, використовуючи в назві статті
../
або щось подібне, а іноді вдається позбутися закінчення, передавши в кінці нульовий байт. Ви повинні як мінімум використовувати функціюbasename()
, а краще дозволити тільки значення білого списку.
Часто ми не заперечуємо проти завантаження некоректного (неочікуваного) файлу - користувач сам винен, що запросив сторінку, яка йому насправді не потрібна, але бувають ситуації, коли це має значення. Зокрема:
Якщо у нас немає можливості перевіряти вхідні дані якимось безпечним способом (наприклад, з білого списку), то все одно не варто покладатися на чесність користувача і захищати скрипти хоча б на рівні 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:
Články píše Jan Barášek © 2009-2024 | Kontakt | Mapa webu
Status | Aktualizováno: ... | uk