Безопасность и включает в себя на основе данных URL - PullRequest
0 голосов
/ 29 января 2010

Представляет ли следующее заявление о включении угрозу безопасности?

include "pages/".$_GET["page"].".php";

Если да:
- почему?
- что было бы безопаснее?

Ответы [ 5 ]

3 голосов
/ 29 января 2010

Да. Для начала, вы никогда не должны использовать переменные GET напрямую без какой-либо проверки: ever .

Кроме того, вы не должны разрешать включать произвольную спецификацию пути.

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

Примером последнего будет что-то вроде этого:

$allowed_pages = array(
  "page1" => "pages/page1.php",
  "page2" => "pages/page2.php",
  "foobar" => "pages/page7.php",
  "stuff" => "pages/blarg.php"
);

$page = $_GET['page'];
if(array_key_exists($allowed_pages, $page)) {
  include($allowed_pages[$page]);
}

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

1 голос
/ 29 января 2010

включает "pages /".$_ GET [" page "].". Php ";

Тот факт, что вы жестко запрограммировали префикс, предотвращает такие атаки, как:

? Page = http% 3A% 2F% 2Fwww.blackhat.com% 2Fbad.code% 3F

Но так как $ _GET ['page'] может включать в себя '..', тогда кто-то может заставитьвключение любого файла с расширением php из вашей системы.Вы уверены, что это никогда не приведет к компромиссу безопасности?

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

C.

1 голос
/ 29 января 2010

Помимо белого списка, вы можете сделать что-то вроде этого

$include = $_GET['page'];

if ( ! preg_match('/^[a-z-_]+$/i', $include)) {
    throw new Exception('Access denied');
}
1 голос
/ 29 января 2010

По сути, вы даете им возможность выполнять ЛЮБОЙ фрагмент PHP, который существует в вашей системе. Это довольно большое неизвестное.

По сути, это рискованно, потому что даже если нет «опасного» кода, на который можно было бы указать сейчас, это может произойти в будущем.

1 голос
/ 29 января 2010

Это риск, потому что в $_GET["page"] может быть путь, который вы не исключаете - в примере ../../settings.php на что-то другое.

Это должно быть сделано как:

$allowedPages = array('news', 'contact', ...);
if ( in_array($_GET["page"], $allowedPages) ) {
    include "pages/".$_GET["page"].".php";
} else {
    throw new Exception('Page is not valid !');
}

Хорошо также проверить, существует ли файл.

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