Динамическое включение - PullRequest
1 голос
/ 05 февраля 2009

Какой самый безопасный способ включить страницы с $ _GET, не помещая разрешенные страницы в переключатель массива / использования и т. Д. У меня много страниц, так что нет, спасибо.

$content = addslashes($_GET['content']);

if (file_exists(PAGE_PATH."$content.html")) { 
include(PAGE_PATH."$content.html");
}

Насколько это безопасно?

Спасибо.

Ответы [ 9 ]

3 голосов
/ 05 февраля 2009

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

if (preg_match('/^[a-z0-9]+$/', $_GET['page']))
{
    $file=PAGE_PATH.$_GET['page'].".html";
    if (file_exists($file))
    {
         readfile($file);
    }
}

Я использовал readfile , как будто файлы .html просто статические, нет необходимости использовать include.

Возможный недостаток вашего подхода заключается в том, что вы можете спроектировать путь к любому HTML-файлу в системе и выполнить его как PHP. Если вы можете найти какой-нибудь способ получить собственный HTML-файл для файловой системы, вы можете выполнить его через свой скрипт.

3 голосов
/ 05 февраля 2009

Это очень плохая практика. Вы должны настроить контроллер для обработки отправки в код, который должен быть выполнен или извлечен, вместо того, чтобы пытаться напрямую включить его из переменной, предоставленной пользователем. Вы никогда не должны доверять пользовательскому вводу при включении файлов. Вам нечего помешать им включить то, что вы не хотите включать.

1 голос
/ 05 февраля 2009

Сопоставьте его с регулярным выражением, которое принимает только "a-zA-Z -".

edit: я не думаю, что блокировка определенных шаблонов - это хорошая идея. Я бы предпочел сделать, как я уже сказал, регулярное выражение, которое принимает только те символы, которые, как мы знаем, не вызовут эксплойтов.

0 голосов
/ 05 февраля 2009

Самый безопасный метод - немного очистить запрос.

  1. Вычеркнуть любую ../
  2. Полоска ^\/

Оттуда убедитесь, что вы проверили, существует ли запрашиваемый файл и может ли он быть прочитан. Тогда просто include это.

0 голосов
/ 05 февраля 2009

Не. Вы никогда не предвидите все возможные атаки, и вас взломают.

Если вы хотите, чтобы в вашем коде не было массивов и т.п., используйте базу данных с двумя столбцами, ID и путь. Запросить страницу по числовому идентификатору. Игнорируйте все запросы на идентификаторы, которые не являются чисто числовыми и не входят в диапазон допустимых идентификаторов. Если вы беспокоитесь о SEO, вы можете добавить произвольные имена страниц после числового идентификатора в своих ссылках, как это делает Stack Overflow.

База данных не должна быть сверхмощной. Например, вы можете использовать SQLite .

0 голосов
/ 05 февраля 2009

Вы можете сначала отсканировать каталог, содержащий все шаблоны HTML, и кэшировать все имена шаблонов в массиве, по которому можно проверить параметр GET. Но даже если вы кешируете этот массив, он все равно создает некоторые накладные расходы.

0 голосов
/ 05 февраля 2009

Это выглядит в целом безопасно, так как вы проверяете, что страница действительно существует, перед ее отображением. Однако вы можете создать черный список страниц, которые пользователи не смогут просматривать с действительными учетными данными $ _SESSION. Это можно сделать либо с помощью массива / переключателя, либо вы можете просто иметь все специальные страницы в определенном каталоге и проверить это.

0 голосов
/ 05 февраля 2009

Предполагая, что "разрешенный" набор страниц существует в PAGE_PATH, тогда я мог бы предложить что-то вроде следующего:

  • Название страницы обрезки
  • Отклонить имена страниц, начинающиеся с косой черты (это может быть попытка указать абсолютный путь)
  • Отклонить имена страниц, которые содержат .. (может быть попытка обхода пути)
  • Явно префикс PAGE_PATH и включает (надеюсь) безопасный путь

Если все имена ваших страниц соответствуют некоторым согласованным правилам, например, буквенно-цифровые символы, тогда вы можете теоретически использовать регулярное выражение для проверки, отвергая «плохие» имена страниц.

На сайте PHP есть еще подробнейшее обсуждение этих вопросов .

0 голосов
/ 05 февраля 2009

Вы должны использовать хотя бы что-то подобное для предотвращения атак XSS.

$content = htmlentities($_GET['page'], ENT_QUOTES, 'UTF-8');

И аддлэш не защитит вас от SQL-инъекций.

...