Показать полную графическую версию : Переход по страницам на PHP
Привет, недавно начал изучать PHP, и вот пишу сайт.
Имеется главная страница index.php. На ней есть таблица, слева линк $PHP_SELF?action=states, а справа прописано include($inc);
В index.php лежит скрипт типа:
if ($action == "states"){
$inc="states.php";
}
При нажатии все нормально загружается.
На states.php у мен лежит линк такого соджержания $PHP_SELF?action=states&st=01
Вопрос:
Как сделать чтобы при нажатии на этот линк страница открывалась здесь же.
Я пытался сам написать, и вот что вышло:
index.php
if ($action == "states") {
$inc="states.php"
if ($st == $st and $st != "") {
$inc="states/$st.htm";
}
}
Все бы ничего, но если ввести неправильно сформированный запрос, то можно читать любые файлы на сервере :) Вариант с else {$inc="error.htm";} не прокатывает, так как при заходе на states.php вылезает error.htm
Vlad Drakula
01-10-2005, 14:00
fossil
я думаю что настоящая проблемма заключается в том что вы не знаете как это все можно организовать с помощью другово метода?
Vlad Drakula
Именно так. Ну или возможно как-то переделать этот. Хотя я думал над ним долго....
Vlad Drakula
01-10-2005, 15:48
fossil
если вы опишите свою задачу более подробдо, то я скорее всего смогу предложить вам более простой вариант решения.
Первая страница (index.php) является как бы шаблоном. Остальные страницы в меню инклюдиться таким образом include("$inc"); Меню имеет вид $PHP_SELF?action=
В зависимости от линка присваиваются параметры :) Тут же эти линки обрабатываются и инклюдится нужная страница. Например
if ($action == "states"){
$inc="states.php";
}
С этим впринципе проблем не возникает.
На странице states.php лежат линки с параметрами $PHP_SELF?action=states&st= в переменную st присваивается номер статьи. Все статьи лежат в каталоге states в htm. Така как у меня states.php инклудится, то все линки на states.php следовательно должны обрабатываться в index.php и инклудиться.
Например у меня в states.php лежит линк $PHP_SELF?action=states&st=01
Следовательно я дописал в index.php следующие строки:
if ($action == "states") {
$inc="states.php"
if ($st == $st and $st != "") {
$inc="states/$st.htm";
}
}
Получается что когда я жму на линк в инклуженном states.php инклудится статья /states/$st.htm (где $st номер статьи).
Вот впринципе и все. Если например сделать запрос http://mysite.ru/index.php?action=states&st=../../../../../../../../../../../../../../etc/passwd%00 нам выведется его содержимое :)
Надо же сделать если ввести что либо другое, то вместо /states/$st.htm инклудилась error.htm, или же как-то сделать подругому запрос.
vadimiron
01-10-2005, 17:53
fossil
Такая система, которую вы создаёте, обычно называется модульной, и states здесь выступает модулем
Есть пару вопросов-предложений:
Во-первых, почему вы пишете
if ($action == "states"){
$inc="states.php";
}
Наверняка у вас будет не только один модуль, а со времен добавяться ещё, тогда может лучше писать так:
if (!empty($action))
{
$inc=$action.".php";
}
Можно также проверять, существует ли вообще такой модуль, если нет, то выводим ошибку "такого модуля нет"
if (!empty($action))
{
if(file_exists($action.".php")) $inc=$action.".php";
else echo "Ошибка: Такой страницы не существует";
}
Обработка переменной $st должна вообще происходить не в index.php, а в том модуле, к которуму она логически принадлежит, то есть в вашем случае в states. Система здесь действует также: проверяем не пуста ли переменная, если нет, то смотрит, существует ли соответствующий данной переменной файл (то есть статья), если существует, то подключаем, если нет, то выводим надпись с ошибкой.
Ещё замечание к модульной системы, если нету переменной action или эта переменная указывает на не существующий модуль, можно подключать стандартный модуль main (или типа того), который будет являться первой страницей сайта
elfoflorien
01-10-2005, 23:34
fossil
еще не плохо бы проверять переменную $st на наличие ../, ./, /root, /etc, и т. д., иначе, конечно получается очень нехорошая штука:
Если например сделать запрос http://mysite.ru/index.php?action=s..../etc/passwd%00 нам выведется его содержимое
Vlad Drakula
02-10-2005, 10:54
elfoflorien
Если например сделать запрос http://mysite.ru/index.php?action=s..../etc/passwd%00 нам выведется его содержимое
а это значит скорее всего у вас не правильные настройки, раз операционка дала прочитать из пхп этот файл!
elfoflorien
04-10-2005, 14:33
Vlad Drakula
на счет настроек не знаю (где это настраивается в Linux?), но такое у меня получалось и под Linux, и под Windows
vadimiron
04-10-2005, 16:19
elfoflorien
В любом случае достаточно проверять, существует ли такой такой файл, на которой указывает переменная $action. Мы же знаем в какой папке лежат все подобные файлы, вот там и смотрим.
elfoflorien
04-10-2005, 21:59
vadimiron
http://mysite/index.php?action=../../../../../../../etc/passwd
на Unix такой файл существует, поэтому ваша проверка ничего не даст - браузеру будет передан ../../../../../../../etc/passwd, т.е. /etc/passwd
или я чего-то не понял?
vadimiron
04-10-2005, 22:37
elfoflorien
Насчёт такого примера вы правы, но неужели этот файл и вправду вам выдаётся??
В любом случае есть золотое правило: Не доверяем данным, полученным от юзеров-то есть бережённого бог бережёт.
Довольно-таки простой выход, это никогда не передавать имена файлов с расширением, то пишем include($action.html)
Я сделал так, и вродебы все работает:
if ($action == "states") {
$inc="states.php";
if ($st == $st and !empty($st)) {
if (file_exists("states/$st.php")) {
$inc="states/$st.php";
} else {$inc="error.htm";}
}
} else {$inc="error.htm"}
Хотя нет, извеняюсь, баг остается прежним :)
if ($action == "states") {
$inc="states.php";
if ($st == $st and !empty($st)) {
if (file_exists("states/$st.php") and substr($st, 0, 2) != ".." and substr($st, 0, 1) != "/") {
$inc="states/$st.php";
} else {$inc="error.htm";}
}
}
Вот рабочий вариант, правда можно читать все файлы которые в каталоге лежат.
elfoflorien
05-10-2005, 15:43
fossil, vadimiron
как насчет использования метода POST вместо GET? тогда ведь пользователь не сможет так просто подделать имя файла $action; есть, конечно, возможность посмотреть HTML код и послать заголовки и POST, и GET, но все равно пользователь просто так ничего не сделает и не узнает имя переменной, в которой находится путь; потом еще один выход - шифровать содержимое $action, чтобы злоумышленник просто не знал, что туда написать. Можно воспользоваться стандартным алгоритмом PHP, а можно написать свой.
elfoflorien
Если можешь, пожалуйста про шифрование поподробнее.
Можно просто проверять, чтобы нельзя использовать специальные символы, правда я незнаю как. Кто знает напишите плз :)
2All
есть такая замечательная функция basename (http://ru.php.net/manual/en/function.basename.php). Обрезает путь, возвращая собственно имя файла. После чего приставляем свой настоящий путь до файла и плюем на всех кулхцкеров :). (В случаях, когда нет ветвления по каталогам, или его можно легко предопределить, скажем по тому же имени файла, очень даже помагает).
В случае чего можно использовать также dirname (http://ru.php.net/manual/en/function.dirname.php), парсить результат и посылать всех, кто пытается выйти за пределы предопределенного дерева каталогов.
Насчет $_GET и $_POST - elfoflorien абсолютно прав, - только через предопределенные переменные и желательно через $_POST
elfoflorien
fossil
Шифрование - я бы не стала играть в эти игры :), потому, что следующей после этого проблемой встанет проблема индексирования нашего сайта поисковыми системами
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.