Динамическая безопасность включения - PullRequest
3 голосов
/ 08 февраля 2009

Есть ли способ безопасно включить страницы, не помещая их все в массив?

if (preg_match('/^[a-z0-9]+/', $_GET['page'])) {

$page = $_GET['page'].".php";
$tpl = $_GET['page'].".html";
if (file_exists($page)) include($page);
if (file_exists($tpl)) include($tpl);

}

Что мне добавить, чтобы сделать это довольно безопасно?

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

Спасибо.

Ответы [ 4 ]

6 голосов
/ 08 февраля 2009

Слабым местом вашей текущей реализации является то, что…

  1. регулярное выражение просто проверяет начало строки, так что «images/../../secret» пройдет, а
  2. без дальнейшей проверки, «index» также будет допустимым значением и вызовет рекурсию.

Чтобы сделать вашу реализацию безопасной, рекомендуется помещать все, что предполагается включить, в отдельный каталог (например, «includes» и «templates»). Исходя из этого, вы просто должны убедиться, что нет выхода из этого каталога.

if (preg_match('/^[a-z0-9]+$/', $_GET['page'])) {
    $page = realpath('includes/'.$_GET['page'].'.php');
    $tpl = realpath('templates/'.$_GET['page'].'.html');
    if ($page && $tpl) {
        include $page;
        include $tpl;
    } else {
        // log error!
    }
} else {
    // log error!
}

Примечание: realpath возвращает абсолютный путь к указанному относительному пути, если файл существует, и false в противном случае. Так что file_exists не нужно.

4 голосов
/ 08 февраля 2009

Несмотря на то, что вы заявили о том, что не хотите хранить список доступных страниц в массиве, это, вероятно, будет лучшим решением без использования базы данных.

$availFiles = array('index.php', 'forum.php');
if(in_array($_GET['page'].".php", $availFiles))
 {
   //Good
 }
else
 {
   //Not Good
 }

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

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

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

Если вы не хотите, чтобы ваш сайт был взломан, вы не позволяете своим пользователям контролировать поток приложения, назначая включение.

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

Я согласен с Unkwntech. Это такой небезопасный способ включения файлов на ваш сайт, я бы хотел, чтобы программисты PHP покончили с этим вообще. Несмотря на это, массив со всеми возможными совпадениями, безусловно, безопаснее. Тем не менее, вы обнаружите, что шаблон MVC работает лучше и безопаснее. Я бы скачал воспламенитель кода и взял бы учебник или два, вам понравится по той же причине, по которой вы хотите использовать динамические включения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...