Модераторы: Aliance, skyboy, MoLeX, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Безопасность в PHP, Статья 
:(
    Опции темы
CyClon
Дата 4.12.2005, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Респект, теперь есть о чем подумать... Давайте еще... Сам может что надумаю или найду - выложу...


--------------------
user posted image
PM   Вверх
CyClon
Дата 10.12.2005, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Цитата
Приемы защиты веб-приложений на PHP

Единственная цель этой статьи - показать некоторые часто используемые приемы защиты веб-приложений - типа WWW-чатов, гостевых книг, веб-форумов и других приложений подобного рода... 
Илья Басалаев
woweb.ru
10-05-2004
печать



Первой заповедью веб-программиста, желающего написать более-менее защищенное веб-приложение, должно стать "Никогда не верь данным, присылаемым тебе пользователем".

Пользователи - это по определению такие злобные хакеры, которые только и ищут момента, как бы напихать в формы ввода всякую дрянь типа PHP, JavaScript, SSI, вызовов своих жутко хакерских скриптов и тому подобных ужасных вещей. Поэтому первое, что необходимо сделать - это жесточайшим образом отфильтровать все данные, присланные пользователем.

Допустим, у нас в гостевой книге существует 3 формы ввода: имя пользователя, его e-mail и само по себе тело сообщения. Прежде всего, ограничим количество данных, передаваемых из форм ввода чем-нибудь вроде:

<input type=text name=username maxlength=20>

На роль настоящей защиты, конечно, это претендовать не может - единственное назначение этого элемента - ограничить пользователя от случайного ввода имени длиннее 20-ти символов. А для того, чтобы у пользователя не возникло искушения скачать документ с формами ввода и подправить параметр maxlength - установим где-нибудь в самом начале скрипта, обрабатывающего данные, проверку переменной окружения web-сервера HTTP-REFERER:

<?
$referer=getenv("HTTP_REFERER");
if (!ereg("^http://www.myserver.com")) {
echo "hacker? he-he... ";
exit;
}
?>

Теперь, если данные переданы не из форм документа, находящегося на сервере www.myserver.com, “кул хацкеру” будет выдано деморализующее сообщение. На самом деле, и это тоже не может служить 100%-ой гарантией того, что данные ДЕЙСТВИТЕЛЬНО переданы из нашего документа. В конце концов, переменная HTTP_REFERER формируется браузером, и никто не может помешать хакеру подправить код браузера, или просто зайти телнетом на 80-ый порт и сформировать свой запрос. Так что подобная защита поможет только от Ну Совсем Необразованных Хакеров.

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

Следующим этапом станет пресловутая жесткая фильтрация переданных данных. Прежде всего, не будем доверять переменной maxlength в формах ввода - и ручками порежем строку:

$username=substr($username,0,20);

Не дадим пользователю использовать пустое поле имени - просто так, чтобы не давать писать анонимные сообщения:

if (empty($username)) {
echo "invalid username";
exit;
}

Запретим пользователю использовать в своем имени любые символы, кроме букв русского и латинского алфавита, знака "_" (подчеркивание), пробела и цифр:

if (preg_match("/[^(w)|(x7F-xFF)|(s)]/",$username)) {
echo "invalid username";
exit;
}

Я предпочитаю везде, где нужно что-нибудь более сложное, чем проверить наличие шаблона в строке или поменять один шаблона на другой, использовать Перл-совместимые регулярные выражения (Perl-compatible Regular Expressions). То же самое можно делать и используя стандартные PHP-шные ereg() и eregi(). Я не буду приводить здесь эти примеры - все достаточно подробно описано в мануале.

Для поля ввода адреса e-mail добавим в список разрешенных символов знаки "@" и "." (иначе пользователь не сможет корректно ввести адрес). Зато уберем русские буквы и пробел:

if (preg_match("/[^(w)|(@)|(.)]/",$usermail)) {
echo "invalid mail";
exit;
}

Поле ввода текста мы не будем подвергать таким жестким репрессиям - перебирать все знаки препинания, которые можно использовать, попросту лень; поэтому ограничимся использованием функций nl2br() и htmlspecialchars() - это не даст врагу понатыкать в текст сообщения html-тегов.

Некоторые разработчики, наверное, скажут: "а мы все-таки очень хотим, чтобы пользователи _могли_ вставлять теги". Если сильно неймется - можно сделать некие тегозаменители, типа "текст, окруженный звездочками, будет высвечен bold"ом.". Но никогда не следует разрешать пользователям использование тегов, подразумевающих подключение внешних ресурсов - от тривиального <img> до супернавороченного <bgsound>.

Как-то раз меня попросили потестировать html-чат. Первым же замеченным мной багом было именно разрешение вставки картинок. Стоило учесть еще пару особенностей строения чата – и через несколько минут у меня был файл, в котором аккуратно были перечислены IP-адреса, имена и пароли всех присутствовавших в этот момент в чате пользователей. Как? Да очень просто - чату был послан тег <img src=http://myserver.com/myscript.pl>, в результате чего браузеры всех пользователей, присутствовавших в тот момент на чате, вызвали скрипт myscript.pl с хоста myserver.com. (а людей, сидевших под lynx"ом, там не было :-) ). Скрипт же, перед тем как выдать location на картинку, свалил мне в лог-файл половину переменных окружения - в частности QUERY_STRING, REMOTE_ADDR и других. Для каждого пользователя; с вышеупомянутым результатом…

Посему мое мнение - да, разрешить вставку html-тегов в чатах, форумах и гостевых книгах - это красиво, но игра не стоит свеч - вряд ли пользователи пойдут к вам в форум или чат, зная, что их IP может стать известным первому встречному хакеру. Да и не только IP - возможности javascript я перечислять не буду :-)

Для примитивной гостевой книги - перечисленных средств хватит, чтобы сделать ее более-менее сложной для взлома. Однако, для удобства книги обычно содержат некоторые возможности для модерирования - как минимум, возможность удаления сообщений. Разрешенную, естественно, узкому (или не очень) кругу лиц. Посмотрим, что можно сделать здесь.
Допустим, вся система модерирования книги также состоит из двух частей - страницы со списком сообщений, где можно отмечать подлежащие удалению сообщения, и непосредственно скрипта, удаляющего сообщения. Назовем их, соответственно, admin1.php и admin2.php.

Простейший и надежнейший способ аутентификации пользователя - размещение скриптов в директории, защищенной файлом .htaccess. Для преодоления такой защиты нужно уже не приложение ломать, а web-сервер. Что несколько сложнее и уж, во всяком случае, не укладывается в рамки этой статьи. Однако, такой способ не всегда пригоден к употреблению - иногда нужно все-таки проводить авторизацию средствами самого приложения.

Первый, самый простой способ - авторизация средствами HTTP, через код 401. При виде такого кода возврата, любой нормальный браузер высветит окошко авторизации и попросит ввести логин и пароль. А в дальнейшем браузер при получении кода 401 будет пытаться подсунуть web-серверу текущие для данного realm"а логин и пароль, и только в случае неудачи - потребует повторной авторизации. Пример кода для вывода требования на такую авторизацию есть во всех хрестоматиях и мануалах:

if (!isset($PHP_AUTH_USER)) {
Header("WWW-Authenticate: Basic realm="My Realm"");
Header("HTTP/1.0 401 Unauthorized");
exit;
}

Разместим этот кусочек кода в начале скрипта admin1.php. После его выполнения, у нас будут две установленные переменные: $PHP_AUTH_USER и $PHP_AUTH_PW, в которых, соответственно, будут лежать имя и пароль, введенные пользователем. Их можно, к примеру, проверить по SQL-базе:

*** Внимание!!!***

В приведенном ниже фрагменте кода сознательно допущена серьезная ошибка в безопасности. Попытайтесь найти ее самостоятельно.

$sql_statement="select password from people where name="$PHP_AUTH_USER"";
$result = mysql($dbname, $sql_statement);
$rpassword = mysql_result($result,0,"password");
$sql_statement = "select password("$PHP_AUTH_PW")";
$result = mysql($dbname, $sql_statement);
$password = mysql_result($result,0);
if ($password != $rpassword) {
Header("HTTP/1.0 401 Auth Required");
Header("WWW-authenticate: basic realm="My Realm"");
exit;
}

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

Итак, раскрываю секрет: допустим, хакер вводит заведомо несуществующее имя пользователя и пустой пароль. При этом в результате выборки из базы переменная $rpassword принимает пустое значение. А алгоритм шифрования паролей при помощи функции СУБД MySQL Password() – так же, впрочем, как и стандартный алгоритм Unix - при попытке шифрования пустого пароля возвращает пустое значение. В итоге - $password == $rpassword, условие выполняется, и взломщик получает доступ к защищенной части приложения. Лечится это либо запрещением пустых паролей, либо, на мой взгляд, более правильным путем - вставкой следующего фрагмента кода:

if (mysql_numrows($result) != 1) {
Header("HTTP/1.0 401 Auth Required");
Header("WWW-authenticate: basic realm="My Realm"");
exit;
}

То есть - проверкой наличия одного и только одного пользователя в базе. Ни больше, ни меньше.

Точно такую же проверку на авторизацию стоит встроить и в скрипт admin2.php. По идее, если пользователь хороший человек - он приходит к admin2.php через admin1.php, а значит, уже является авторизованным и никаких повторных вопросов ему не будет - браузер втихомолку передаст пароль. Если же нет - ну, тогда и поругаться не грех. Скажем, вывести ту же фразу "hacker? he-he...".

К сожалению, не всегда удается воспользоваться алгоритмом авторизации через код 401, и приходится выполнять ее только средствами приложения. В общем случае модель такой авторизации будет следующей:
· Пользователь один раз авторизуется при помощи веб-формы и скрипта, который проверяет правильность имени и пароля.
· Остальные скрипты защищенной части приложения каким-нибудь образом проверяют факт авторизованности пользователя.

Такая модель называется сессионной - после прохождения авторизации открывается так называемая "сессия", в течение которой пользователь имеет доступ к защищенной части системы. Сессия закрылась - доступ закрывается. На этом принципе, в частности, строится большинство www-чатов: пользователь может получить доступ к чату только после того, как пройдет процедуру входа. Основная сложность данной схемы заключается в том, что все скрипты защищенной части приложения каким-то образом должны знать о том, что пользователь, посылающий данные, успешно авторизовался.

Рассмотрим несколько вариантов, как это можно сделать:

1. После авторизации все скрипты защищенной части вызываются с неким флажком вида adminmode=1. (Не надо смеяться - я сам такое видел).
Ясно, что любой, кому известен флажок adminmode, может сам сформировать URL и зайти в режиме администрирования. Кроме того - нет возможности отличить одного пользователя от другого.

2. Скрипт авторизации может каким-нибудь образом передать имя пользователя другим скриптам. Распространено во многих www-чатах - для того, чтобы отличить, где чье сообщение идет, рядом с формой типа text для ввода сообщения, пристраивается форма типа hidden, где указывается имя пользователя. Тоже ненадежно, потому что хакер может скачать документ с формой к себе на диск и поменять значение формы hidden. Некоторую пользу здесь может принести вышеупомянутая проверка HTTP_REFERER - но, как я уже говорил, никаких гарантий она не дает.

3. Определение пользователя по IP-адресу. В этом случае, после прохождения авторизации, где-нибудь в локальной базе данных (sql, dbm, да хоть в txt-файле) сохраняется текущий IP пользователя, а все скрипты защищенной части смотрят в переменную REMOTE_ADDR и проверяют, есть ли такой адрес в базе. Если есть - значит, авторизация была, если нет - "hacker? he-he..." :-)

Это более надежный способ - не пройти авторизацию и получить доступ удастся лишь в том случае, если с того же IP сидит другой пользователь, успешно авторизовавшийся. Однако, учитывая распространенность прокси-серверов и IP-Masquerad"инга - это вполне реально.

4. Единственным известным мне простым и достаточно надежным способом верификации личности пользователя является авторизация при помощи random uid. Рассмотрим ее более подробно:

После авторизации пользователя скрипт, проведший авторизацию, генерирует достаточно длинное случайное число:

mt_srand((double)microtime()*1000000);
$uid=mt_rand(1,1000000);

Это число он:
а) заносит в локальный список авторизовавшихся пользователей;
б) выдает пользователю.

Пользователь при каждом запросе, помимо другой информации (сообщение в чате, или список сообщений в гостевой книге), отправляет серверу свой uid. При этом в документе с формами ввода будет присутствовать, наряду с другими формами, тег вида:

<input type=hidden name=uid value=1234567890>

Форма uid невидима для пользователя, но она передается скрипту защищенной части приложения. Тот сличает переданный ему uid с uid"ом, хранящимся в локальной базе и либо выполняет свою функцию, либо...

Единственное, что необходимо сделать при такой организации - периодически чистить локальный список uid"ов и/или сделать для пользователя кнопку "выход", при нажатии на которую локальный uid пользователя сотрется из базы на сервере - сессия закрыта.

Некоторые программисты используют в качестве uid не "одноразовое" динамически генерирующееся число, а пароль пользователя. Это допустимо, но это является "дурным тоном", поскольку пароль пользователя обычно не меняется от сессии к сессии, а значит - хакер сможет сам открывать сессии. Та же самая модель может быть использована везде, где требуется идентификация пользователя - в чатах, веб-конференциях, электронных магазинах.

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

При ведении лог-файлов - необходимо помнить, что доступ к ним должен быть только у вас. Лучше всего, если они будут расположены за пределами дерева каталогов, доступного через WWW. Если нет такой возможности - создайте отдельный каталог для лог-файлов и закройте туда доступ при помощи .htaccess (Deny from all).

Я буду очень признателен, если кто-нибудь из программистов поделится своими - не описанными здесь -методами обеспечения безопасности при разработке приложений для Web.
P.S. Выражаю глубокую благодарность Козину Максиму ([email protected]) за рецензирование данной статьи и ряд весьма ценных дополнений.



--------------------
user posted image
PM   Вверх
CyClon
Дата 10.12.2005, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Вот тут распечатал парочку статей включая эту.. Только дочитал.. И скажу вам - отличная статья! Читать всем без исключения.


--------------------
user posted image
PM   Вверх
Ciber SLasH
Дата 14.12.2005, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: нет
Всего: 67



Цитата(CyClon @ 10.12.2005, 21:00)
Вот тут распечатал парочку статей включая эту..

Источник не подскажешь ?
PM   Вверх
CyClon
Дата 14.12.2005, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Спросил бы раньше, подсказал быsmile))
Добавлено @ 20:46
Хех ребята учитись юзать поиск.
http://yandex.ru
Запрос:

IP-адреса потенциального злоумышленника - то в

вывалило кучу сайтоффsmile

http://www.winsov.ru/php003.php
http://www2.marketer.ru/articles/index.pr820.html
http://nbsp.ru/articles/2005/11/10/priemy_...okonchanie.html
http://renewing.ru/modules.php?name=Pages&pa=showpage&pid=91

Думаю что то на всех есть полезное. Пойду серфить.
Добавлено @ 20:47
Источник: http://detail.phpclub.net/


--------------------
user posted image
PM   Вверх
Alx
Дата 8.1.2006, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ajaxy
****


Профиль
Группа: Комодератор
Сообщений: 2903
Регистрация: 26.11.2003
Где: Cutopia

Репутация: нет
Всего: 78



1. рекомендуется использовать функцию mysql_real_escape_string() вместо mysql_escape_string(), т.к. последняя теряет смысл при Unicode-кодировке.

2. с include (а вернее рекомендую использовать require) я поступаю так:
Код

<?
$act = $_GET['act'];
require "/sources/{$act}.php";
?>


3. ещё раз четко про SQL, чтобы исключить возможность упущения чего-либо:

1) всегда использовать кавычки вокруг переменной вставляемой в запрос:
Код

SELECT * FROM _tbl WHERE _cell = '{$cell}';

2) всегда использовать функцию mysql_real_escape_string() хотя бы для проставления бэкслэшей ( \ ) перед кавычками дабы не получилось так ( $cell = "' and _pass > '0" ):
Код

SELECT * FROM _tbl WHERE _cell = '' and _pass > '0';

а получилось так:
Код

SELECT * FROM _tbl WHERE _cell = '\' and _pass > \'0';

3) всегда хранить данные, введённые пользователем, которые рано или поздно будут выведены в браузер только после пропуска через функцию htmlspecialchars()
4) если мы ждем от юзера число, достаточно строку пропустить через intval():
Код

$userid = $_GET['userid'];
$userid = intval($userid);
mysql_query("SELECT * FROM _tbl WHERE _userid = '{}');

таким образом, какую бы противную строчку мы не получили от хацкера, от неё останутся только циферки или 0.

вот это надо обязательно запомнить!


--------------------
PM MAIL WWW ICQ   Вверх
Mal Hack
Дата 8.1.2006, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 1
Всего: 261



Цитата(Alx @ 8.1.2006, 16:37 Найти цитируемый пост)

2. с include (а вернее рекомендую использовать require) я поступаю так:

Сам факт использования той или иной функции на безопасности в данном случае не сказывается.
Цитата(Alx @ 8.1.2006, 16:37 Найти цитируемый пост)

4) если мы ждем от юзера число, достаточно строку пропустить через intval():

А я бы вот использовал проверку, а не приведение типов. ctype_*();
Цитата(Alx @ 8.1.2006, 16:37 Найти цитируемый пост)

3. ещё раз четко про SQL, чтобы исключить возможность упущения чего-либо:

http://vingrad.ru/PHP-ART-002847
PM ICQ   Вверх
Mh139
Дата 30.1.2006, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 29.1.2006

Репутация: нет
Всего: нет



Цитата

Ошибка №1: include-баг


А по-моему не стоит заморачиваться с basename'ами и regexp'ами.

Самый на мой взгляд удобный способ - ассоциативный массив типа

Код

$page_array["news"] = "news.php";
$page_array["guestbook"] = "guestbook.php"
/* и т. д. */


Ну и естественно в include() нужно передавать $page_array[$page]. Если переданный ключ в массиве отсутствует, то и подключать нечего.
PM MAIL   Вверх
CyClon
Дата 7.2.2006, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Mh139, разумно.

Или юзать:

switch ($_GET['page']) {
case forum:
include("forum.php");
default:
include("news.php");
}



--------------------
user posted image
PM   Вверх
IZ@TOP
Дата 14.2.2006, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: 1
Всего: 73



CyClon, или хранить все данные в базе. А вообще с появлением РНР 5, стало возможным ограничивать доступ к переменным и методам классов, что на мой взгляд крайне удобно и плюс к безопасности.


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
CyClon
Дата 19.2.2006, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



IZ@TOP, PHP5 ни разу не юзалsmile)) Все PHP4...


--------------------
user posted image
PM   Вверх
IZ@TOP
Дата 20.2.2006, 07:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: 1
Всего: 73



CyClon, четверка уже морально устарела как и третья версия в свое время.


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
Janus
Дата 21.2.2006, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 186
Регистрация: 26.9.2005

Репутация: нет
Всего: 1



Четверка все еще на большинстве хостингов стоит.
--------------------
Проект "Репликатор" 
PM MAIL   Вверх
CTAPbIuMABP
Дата 22.2.2006, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 92
Регистрация: 17.2.2006
Где: Киев

Репутация: нет
Всего: 1



IMHO

Код

<?
$referer=getenv("HTTP_REFERER");
if (!ereg("^http://www.myserver.com")) {
echo "hacker? he-he... ";
exit;
}
?>


на этот случай есть программа InetCrack

Код

if ($_GET['file'] == "../date/passwd.dat") {
echo "Вы ввели запрещеный адрес файла!";
return 0;
}


тоже бред на проверку

Код

if ($_GET['file'] == "%2E%2E%2Fdate/passwd.dat") {
echo "Вы ввели запрещеный адрес файла!";
return 0;
}


А вообще чтобы узнать побольше советую очень практичный пример! скачайте XSpider даже демка подойдет, напишите чтото вроде

Код

$_SERVER[HTTP_REFERER] -> в БД или в dat file
echo "<a href=\"file.php?var=1\">\file.php</a>";


и посмотрите лог файл или БД там будет много интересного

Это сообщение отредактировал(а) CTAPbIuMABP - 22.2.2006, 12:55
PM WWW ICQ Skype   Вверх
OlegNT
Дата 19.4.2006, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 21.3.2006
Где: Нижний Тагил

Репутация: нет
Всего: нет



C include поступаю так:

Код

include (!empty ($_GET['page']) && substr_count ($_GET['page'], '/') == 0 && substr_count ($_GET['page'], '\\') == 0 && file_exists ("pages/".$_GET['page'].".php") ? $_GET['page'] : "home").".php";


Кстати, ".php" в GET-запросе можно избавиться, если набрать:

index.php?page=file.txt%00  

Это сообщение отредактировал(а) OlegNT - 19.4.2006, 20:09
PM MAIL WWW Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Избранное | Следующая тема »


 




[ Время генерации скрипта: 0.1814 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.