Эта тема на forum.dklab.ru


Юрик: Эмуляция register_globals=Off
Тема, как отключить magic_quotes, уже была: http://forum.dklab.ru/php/advises/UndoMagic_quotes.html

Теперь предлагаю обсудить, как средствами, доступными из самого скрипта, отрубить действие register_globals=On

Первое, что пришло на ум:
foreach ($GLOBALS as $k=>$v)
if (@$_REQUEST[$k]) unset($GLOBALS[$k]);

Ваши предложения? :-)
Валенок:
а зачем?) в хорошем скрипте все переменные инициализируются, а те которые могут быть всунуты - просто не используются (или инициализируются %) )
Юрик:
а зачем?) в хорошем скрипте все переменные инициализируются, а те которые могут быть всунуты - просто не используются (или инициализируются %) )
верно, но всё-таки. Ошибки иногда допускают даже хорошие программисты, а register_globals=On - потенциальная дыра
Валенок:
тогда лучше всем переменным ансет сделать, кроме тех, что на $_ начинаются) (в самом начале)
Юрик:
Пока что код, предложенный выше, обламывается:( Т.к. можно затереть любой массив: index.php?=_GET=hack

тогда лучше всем переменным ансет сделать, кроме тех, что на $_ начинаются) (в самом начале)
Может быть. Сейчас посмотрю, не заденет ли это чего-нибудь нужного
Anonymous:
а можно весь скрипт засунуть в функцию:
function do() {
/* тут что-то делаем или инклудим другой скрипт */
}; do();

:)
Юрик:
Валенок,
Мне кажется, Вы правы ))
Пока рабочий вариант такой:
foreach ($GLOBALS as $k=>$v)
{
if ($k=='GLOBALS' || $k=='k' || $k=='v') continue;
if (strpos($k, '_')!==0) unset($GLOBALS[$k]);
}

Пара моментов:
1. Переменные от клиента, которые начинаются с '_', всё равно будут глобальными. Но это уже не так старшно.
2. Заодно подтираются "антикварные" массивы типа $HTTP_POST_VARS, $HTTP_ENV_VARS, а также глобализированные значения из $_ENV и $_SERVER.

Конечно, можно было бы вырубать всё, кроме $_POST, $_GET, $_COOKIE, $_SERVER, $_ENV, $_FILES, $_REQUEST, $GLOBALS. Но это не тянет на решение задачи в общем виде, т.к. в более новых версиях PHP могут добавиться новые массивы (надеюсь, что они будут начинаться с '_', иначе предложенное решение работать не будет)

Гость,
да, это вариант, но придётся переписывать головной код - просто в файл настройки добавить не получится
Г.О.:

foreach ($GLOBALS as $k=>$v)
if (@$_REQUEST[$k]) unset($GLOBALS[$k]);

Фантастика.
Если уж очень хочется:

foreach ($_REQUEST as $k => $v) {
unSet($GLOBALS[$k]);
}

Юрик:
Г.О.
оба варианта уже отпадают по соображениям безопасности :(
Удивительно, но только что нашёл решение в мануале
http://ru2.php.net/manual/en/faq.misc.php#faq.misc.registerglobals
Валенок:
Юрик
лучше переволноваться, чем недоволноваться. придумают новый суперглобал и всё править придется ))
Юрик:
согласен )) Текущий вариант:
function undo_register_globals()
{
if (!ini_get('register_globals')) return;
foreach ($GLOBALS as $k=>$v)
if (strpos($k, '_')!==0 && $k!='GLOBALS') unset($GLOBALS[$k]);
}
Юрий Насретдинов:
Юрик
Хотите более надёжный (и более быстрый, особенно ввиду того, что Вы перебираете целый $GLOBALS ;) ) способ решить Вашу проблему?


php_flag register_globals Off

Валенок:
Юpий Насрeтдинов
ну, это решение на случай, если ваше предложение невозможно:)

а глобалс в начале Пути (скрипта) не такой уж и большой.
Юрик:
Юpий Насрeтдинов
Естественно, если будет такая возможность, поставлю Off. В $GLOBALS в начале работы порядка нескольких десятков значений (перебирается не рекурсивно, поэтому быстро)
Юрий Насретдинов:
У хостера (FreeBSD, PHP 4.4.0) 73 глобальных переменных, под Денвером (Windows, PHP 5.1.6) 90 глобальных переменных. Думается, что если перебирать $_REQUEST, будет на порядок (это типа 10 раз) быстрее.
Юрик:
Думаю, лучше абстрагироваться от данных, к-е вводит пользователь, это более безопасный подход
Юрий Насретдинов:
Думаю, лучше абстрагироваться от данных, к-е вводит пользователь, это более безопасный подход
Я свою точку зрения могу обосновать - лучше перебирать $_REQUEST, потому что быстрее и потому что единственный потенциальный источник угрозы безопасности - именно пользовательские данные, ибо остальные переменные ставятся самим сервером и навредить никак не могут.
Валенок:
есть еще пользовательская переменная $QUERY_STRING
это я к
остальные переменные ставятся самим сервером и навредить никак не могут.
Юрик:

Я свою точку зрения могу обосновать - лучше перебирать $_REQUEST, потому что быстрее и потому что единственный потенциальный источник угрозы безопасности - именно пользовательские данные, ибо остальные переменные ставятся самим сервером и навредить никак не могут.
а как быть, если index.php?_ENV=hack
?
или Вы имеете ввиду затирать всё из $_REQUEST, кроме переменных, начинающихся с '_'?
Г.О.:
а как быть, если index.php?_ENV=hack
http://ru2.php.net/manual/ru/ini.core.php#ini.variables-order
Юрик:
а как быть, если index.php?_ENV=hack
http://ru2.php.net/manual/ru/ini.core.php#ini.variables-order
Гляньте первый код в ветке, всё перезатирается, если неправильно перебирать массив
Юрий Насретдинов:
index.php?_ENV=hack
Ну да, об этом я не подумал...
или Вы имеете ввиду затирать всё из $_REQUEST, кроме переменных, начинающихся с '_'?
Да, пожалуй в таком случае это будет самый правильный способ.
Anonymous:
да, это вариант, но придётся переписывать головной код - просто в файл настройки добавить не получится ой, да ладно :) выносим головной скрипт в index.inc, а заместо index.php пихаем мой код, в котором просто инклудим index.inc
дело пяти минут, зато гарантированная безопасность :)

Эта тема на forum.dklab.ru