2009-02-05 6 views
1

Что было бы самым безопасным способом включить страницы с $ _GET без разрешенных страниц в блоке/использовании коммутатора и т. Д. У меня много страниц, поэтому нет благодарности.Dynamic Include

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

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

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

Спасибо.

+0

Мне любопытно: можете ли вы добавить дополнительную справочную информацию? Зачем вам это делать? Почему вы не можете организовать свою веб-страницу на основе разных областей/функций и т. Д.? – cbrulak

+0

Приобретено, потому что большинство ответов, похоже, не понимают, насколько опасен весь этот подход, что вызывает беспокойство. –

ответ

-6

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

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

И добавляет не будет защищать вас от SQL-инъекций.

+0

Он не вводит имя страницы в SQL-запрос, и не отправляет его в HTML; он включает файл, основанный на пользовательском вводе, который требует различной обработки и логики для защиты от атак на пути. – Rob

+0

Я знаю, но по-прежнему очень часто используется addlashes для предотвращения инъекций SQL. –

+0

Но не для включения файлов. –

0

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

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

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

На веб-сайте PHP есть more discussion of these issues.

1

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

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

3

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

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

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

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

+0

И, конечно же, «получение файла [собственного] нападающего в файловой системе» - это то, что преподают сценаристы. file_exists() действительно не покупает OP ничего здесь, кроме иллюзии безопасности. –

+0

Проблема в том, что ваш подход (Paul Dixon's) также страдает от недостатка, который вы определили в подходе OP, за исключением того, что в вашем случае контекст выполнения является браузером конечного пользователя. Похоже, что нижеуказанный ответ об уберу ниже о XSS не был полностью исключен из стадиона ... –

+0

это правда, но, по крайней мере, это ограничивает возможность атаки одному каталогу, а не одному из нападавших. –

0

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

0

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

3

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

+0

+1 за предоставление родовой версии моего ответа, который почему-то получил downvoted. ;-) (file_exists() == TRUE) означает * nothing *. Если вы не уверены, что ваша файловая система не поддается компромиссу. –

0

Не делайте этого. Вы никогда не будете ожидать всех возможных атак, и вас будут взломать.

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

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

+0

Эй, по крайней мере, объясните, почему вы остановились! –

0

Самый безопасный метод включает в себя очистку запроса немного.

  1. Strip любой ../
  2. Газа из ^\/

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