Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Вебмастеру (http://forum.oszone.net/forumdisplay.php?f=22)
-   -   Переход по страницам на PHP (http://forum.oszone.net/showthread.php?t=54607)

fossil 01-10-2005 13:36 360653

Переход по страницам на 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 360657

fossil
я думаю что настоящая проблемма заключается в том что вы не знаете как это все можно организовать с помощью другово метода?

fossil 01-10-2005 15:04 360665

Vlad Drakula
Именно так. Ну или возможно как-то переделать этот. Хотя я думал над ним долго....

Vlad Drakula 01-10-2005 15:48 360673

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

fossil 01-10-2005 16:14 360683

Первая страница (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=st.../etc/passwd%00 нам выведется его содержимое :)

Надо же сделать если ввести что либо другое, то вместо /states/$st.htm инклудилась error.htm, или же как-то сделать подругому запрос.

vadimiron 01-10-2005 17:53 360692

fossil
Такая система, которую вы создаёте, обычно называется модульной, и states здесь выступает модулем
Есть пару вопросов-предложений:
Во-первых, почему вы пишете
PHP код:

if ($action == "states"){
$inc="states.php";


Наверняка у вас будет не только один модуль, а со времен добавяться ещё, тогда может лучше писать так:
PHP код:

if (!empty($action))
{
$inc=$action.".php";


Можно также проверять, существует ли вообще такой модуль, если нет, то выводим ошибку "такого модуля нет"
PHP код:

if (!empty($action))
{
    if(
file_exists($action.".php"))  $inc=$action.".php";
    else echo 
"Ошибка: Такой страницы не существует";


Обработка переменной $st должна вообще происходить не в index.php, а в том модуле, к которуму она логически принадлежит, то есть в вашем случае в states. Система здесь действует также: проверяем не пуста ли переменная, если нет, то смотрит, существует ли соответствующий данной переменной файл (то есть статья), если существует, то подключаем, если нет, то выводим надпись с ошибкой.

Ещё замечание к модульной системы, если нету переменной action или эта переменная указывает на не существующий модуль, можно подключать стандартный модуль main (или типа того), который будет являться первой страницей сайта

fossil 01-10-2005 19:37 360701

Спасибо большое!

elfoflorien 01-10-2005 23:34 360746

fossil
еще не плохо бы проверять переменную $st на наличие ../, ./, /root, /etc, и т. д., иначе, конечно получается очень нехорошая штука:
Цитата:

Если например сделать запрос http://mysite.ru/index.php?action=s..../etc/passwd%00 нам выведется его содержимое

Vlad Drakula 02-10-2005 10:54 360805

elfoflorien
Цитата:

Если например сделать запрос http://mysite.ru/index.php?action=s..../etc/passwd%00 нам выведется его содержимое
а это значит скорее всего у вас не правильные настройки, раз операционка дала прочитать из пхп этот файл!

elfoflorien 04-10-2005 14:33 361379

Vlad Drakula
на счет настроек не знаю (где это настраивается в Linux?), но такое у меня получалось и под Linux, и под Windows

vadimiron 04-10-2005 16:19 361408

elfoflorien
В любом случае достаточно проверять, существует ли такой такой файл, на которой указывает переменная $action. Мы же знаем в какой папке лежат все подобные файлы, вот там и смотрим.

elfoflorien 04-10-2005 21:59 361511

vadimiron
Код:

http://mysite/index.php?action=../../../../../../../etc/passwd
на Unix такой файл существует, поэтому ваша проверка ничего не даст - браузеру будет передан ../../../../../../../etc/passwd, т.е. /etc/passwd
или я чего-то не понял?

vadimiron 04-10-2005 22:37 361518

elfoflorien
Насчёт такого примера вы правы, но неужели этот файл и вправду вам выдаётся??

В любом случае есть золотое правило: Не доверяем данным, полученным от юзеров-то есть бережённого бог бережёт.
Довольно-таки простой выход, это никогда не передавать имена файлов с расширением, то пишем include($action.html)

fossil 05-10-2005 13:56 361675

Я сделал так, и вродебы все работает:
PHP код:

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"


fossil 05-10-2005 14:26 361687

Хотя нет, извеняюсь, баг остается прежним :)

fossil 05-10-2005 14:43 361694

PHP код:

if ($action == "states") {
$inc="states.php";
    if (
$st == $st and !empty($st)) {
    if (
file_exists("states/$st.php") and substr($st02) != ".." and substr($st01) != "/") {
    
$inc="states/$st.php";
    } else {
$inc="error.htm";}
    }


Вот рабочий вариант, правда можно читать все файлы которые в каталоге лежат.

elfoflorien 05-10-2005 15:43 361709

fossil, vadimiron
как насчет использования метода POST вместо GET? тогда ведь пользователь не сможет так просто подделать имя файла $action; есть, конечно, возможность посмотреть HTML код и послать заголовки и POST, и GET, но все равно пользователь просто так ничего не сделает и не узнает имя переменной, в которой находится путь; потом еще один выход - шифровать содержимое $action, чтобы злоумышленник просто не знал, что туда написать. Можно воспользоваться стандартным алгоритмом PHP, а можно написать свой.

fossil 05-10-2005 17:42 361743

elfoflorien
Если можешь, пожалуйста про шифрование поподробнее.

Можно просто проверять, чтобы нельзя использовать специальные символы, правда я незнаю как. Кто знает напишите плз :)

mar 05-10-2005 18:04 361757

2All
есть такая замечательная функция basename. Обрезает путь, возвращая собственно имя файла. После чего приставляем свой настоящий путь до файла и плюем на всех кулхцкеров :). (В случаях, когда нет ветвления по каталогам, или его можно легко предопределить, скажем по тому же имени файла, очень даже помагает).
В случае чего можно использовать также dirname, парсить результат и посылать всех, кто пытается выйти за пределы предопределенного дерева каталогов.

Насчет $_GET и $_POST - elfoflorien абсолютно прав, - только через предопределенные переменные и желательно через $_POST

elfoflorien
fossil
Шифрование - я бы не стала играть в эти игры :), потому, что следующей после этого проблемой встанет проблема индексирования нашего сайта поисковыми системами


Время: 19:59.

Время: 19:59.
© OSzone.net 2001-