register_globals=On Предупреждение (Rating: -2)
Вы, возможно, слышали, что использование её может привести к небезопасной работе вашей программы (скрипта). Но давайте разберемся, как эту опцию могут использовать в противоправных целях и как от этого защититься.
Что представляет собой register_globals?
Это опция в php.ini, которая указывает на необходимость регистрации переменных, полученных методом POST или GET в глобальный массив $GLOBALS.
Для ясности приведу пример при register_globals=On.
Есть файл "index.php" с содержимым:
Получим:
Но давайте вдумаемся, зачем нам "загрязнять" массив $GLOBALS? Для этого у нас есть специальные массивы, хранящие данные, переданные методами GET (массив $_GET) и POST (массив $_POST).
Тот же самый пример, но при register_globals=Off:
- глобальная переменная
- ссылка в глобальном массиве $GLOBALS
123 - $_GET['asd']
Т.о. не была создана локальная переменная и для манипулирования с <$asd> мы должны использовать массив $_GET.
Возможно, уже сейчас вы изменили свое мнение о register_globals.
Вероятно, вам придется, что-то переписать в своих программах, но оно того стоит.А теперь я расскажу вам, как взломщик может воспользоваться этой опцией в своих целях, т.е. при register_globals=On.
Начну от простого к сложному.
Часто мы видим предупреждения:
Notice: Undefined variable: asd(название переменной) in ****
Что это значит? Это значит, что переменная $asd не была определена явно.
Например, некоторые люди балуются подобным:
Предположим мы пишем систему аутентификации пользователя:
Этого бы не случилось, если бы мы написали так:
Продолжим далее:
Теперь использование функции IsSet() становиться небезопасно, т.к. любой может подменить переменную на угодную ему.
Приведу пример с sql-инъекцией:
"index.php?where=id=0 + UNION + ALL + SELECT + login, + password, + null + FROM + admin + where + login='admin'",
получим sql-инъекцию:
SELECT id, title, description FROM table WHERE id=0
UNION ALL SELECT login, password, null FROM admin where login='admin'
И взломщик получает ваши явки и пароли
Как вы видите, все примеры имеют дыры в защите, которые можно эксплуатировать через включенный register_globals.
Справиться с подобным можно, если всегда определять переменную вне зависимости от условий. Или же использовать инкапсуляцию переменных в функциях, т.е. когда вы определяете функцию, то переменные внутри нее будут закрыты извне, например:
Теперь, если мы напишем в адресной строке: "index.php?where=123"
Даст: "$where не существует"
Но это при условии, что вы не устанавливаете переменную $where как глобальную, т.е. "global $where"
Я могу придумать еще очень много примеров, но думаю, что приведенных мною вам будет достаточно для понимания.
Хочу сказать, что все эти проблемы канут в лета, когда вы установите опцию register_globals=Off и попробуете заново все приведенные выше примеры.
Это можно сделать как в php.ini, но большинство хостинг провайдеров вам это не позволят, потому придется воспользоваться файлом .htaccess
Создаем файл с названием: .htaccess
Запишем в него:
php_flag register_globals off
И все, теперь некоторые вопросы безопасности решены
Немного о причине написания мной этой статьи:
Лично я никогда не использовал register_globals = on, т.к. мне казалось это нелогичным. Также я знал, что это еще один "+" к защите. Но в полной мере я не осознавал, насколько это может быть опасно. Случилось это когда я решил написать GSMgen - Google SiteMap generator, который должен был работать безопасно и при включенном register_globals. Когда же я начал его тестировать, у меня был шок: так как мне нравится использовать функцию IsSet(), я нашел в ней непосредственную уязвимость, и в процессе мне пришлось от этого отказаться Что поделаешь...
Я очень надеюсь, что эта статья изменит ваше мнение относительно register_globals. Думаю, что со временем все хостинг провайдеры будут ставить register_globals = off по умолчанию. Но пока этого нет, вы знаете как с этим бороться;-)
Added: ZipeR
12.05.2011 / 14:46Что представляет собой register_globals?
Это опция в php.ini, которая указывает на необходимость регистрации переменных, полученных методом POST или GET в глобальный массив $GLOBALS.
Для ясности приведу пример при register_globals=On.
Есть файл "index.php" с содержимым:
<? echo $asd.' - локальная переменная<br>'; echo $GLOBALS['asd'].' - ссылка в глобальном массиве $GLOBALS<br>'; echo $_GET['asd'].' - $_GET["asd"]'; ?>В адресной строке напишем: index.php?asd=123
Получим:
123 - локальная переменная 123 - ссылка в глобальном массиве $GLOBALS 123 - $_GET['asd']Как мы видим, создались 2 переменные: одна локальная (+ ссылка в $GLOBALS), другая в массиве $_GET. Многие не используют массив $_GET вообще, они продолжают обрабатывать переменную $asd после получения ее извне.
Но давайте вдумаемся, зачем нам "загрязнять" массив $GLOBALS? Для этого у нас есть специальные массивы, хранящие данные, переданные методами GET (массив $_GET) и POST (массив $_POST).
Тот же самый пример, но при register_globals=Off:
- глобальная переменная
- ссылка в глобальном массиве $GLOBALS
123 - $_GET['asd']
Т.о. не была создана локальная переменная и для манипулирования с <$asd> мы должны использовать массив $_GET.
Возможно, уже сейчас вы изменили свое мнение о register_globals.
Вероятно, вам придется, что-то переписать в своих программах, но оно того стоит.А теперь я расскажу вам, как взломщик может воспользоваться этой опцией в своих целях, т.е. при register_globals=On.
Начну от простого к сложному.
Часто мы видим предупреждения:
Notice: Undefined variable: asd(название переменной) in ****
Что это значит? Это значит, что переменная $asd не была определена явно.
Например, некоторые люди балуются подобным:
<? for($i= 0;$i<10;$i++) { @$asd.=$i; } echo $asd ?>Т.е. не определив переменную, сразу начинают ее использовать. Приведенный код по идее не страшен, но задумайтесь, а вдруг эта самая переменная $asd, в последствии записывается в файл? Например, напишем следующее в строке адреса: "index.php?asd=LUSER+" и получим: "LUSER 0123456789". Ну разве приятно будет увидеть такое? Не думаю.
Предположим мы пишем систему аутентификации пользователя:
<? if($_POST['login']=='login'&&$_POST['pass']=='pass') { $valid_user=TRUE; // Юзер корректный } if($valid_user) { echo 'Здравствуйте, пользователь'; } else echo 'В доступе отказано' ?>Привел я заведомо дырявую систему, стоит нам только написать в адресной строке "index.php?valid_user=1" и мы получим надпись "Здравствуйте, пользователь"
Этого бы не случилось, если бы мы написали так:
<? if($_POST['login']=='login'&&$_POST['pass']=='pass') { $valid_user=TRUE; // Юзер корректный } else $valid_user=FALSE; if($valid_user) { echo 'Здравствуйте, пользователь'; } else echo 'В доступе отказано' ?>Т.е. сами определили переменную $valid_user, как FALSE в случае неудачи.
Продолжим далее:
Теперь использование функции IsSet() становиться небезопасно, т.к. любой может подменить переменную на угодную ему.
Приведу пример с sql-инъекцией:
<? if(@$some_conditions) // некоторые условия { $where='id=3'; } echo $query='SELECT id, title, description FROM table ' .'WHERE '.(IsSet($where)?$where:'id=4') ?>В адресной строке напишем:
"index.php?where=id=0 + UNION + ALL + SELECT + login, + password, + null + FROM + admin + where + login='admin'",
получим sql-инъекцию:
SELECT id, title, description FROM table WHERE id=0
UNION ALL SELECT login, password, null FROM admin where login='admin'
И взломщик получает ваши явки и пароли
Как вы видите, все примеры имеют дыры в защите, которые можно эксплуатировать через включенный register_globals.
Справиться с подобным можно, если всегда определять переменную вне зависимости от условий. Или же использовать инкапсуляцию переменных в функциях, т.е. когда вы определяете функцию, то переменные внутри нее будут закрыты извне, например:
<? function asd() { // Какие то действия if(IsSet($where)) { echo $where; } else echo '$where не существует'; } asd(); ?>
Теперь, если мы напишем в адресной строке: "index.php?where=123"
Даст: "$where не существует"
Но это при условии, что вы не устанавливаете переменную $where как глобальную, т.е. "global $where"
Я могу придумать еще очень много примеров, но думаю, что приведенных мною вам будет достаточно для понимания.
Хочу сказать, что все эти проблемы канут в лета, когда вы установите опцию register_globals=Off и попробуете заново все приведенные выше примеры.
Это можно сделать как в php.ini, но большинство хостинг провайдеров вам это не позволят, потому придется воспользоваться файлом .htaccess
Создаем файл с названием: .htaccess
Запишем в него:
php_flag register_globals off
И все, теперь некоторые вопросы безопасности решены
Немного о причине написания мной этой статьи:
Лично я никогда не использовал register_globals = on, т.к. мне казалось это нелогичным. Также я знал, что это еще один "+" к защите. Но в полной мере я не осознавал, насколько это может быть опасно. Случилось это когда я решил написать GSMgen - Google SiteMap generator, который должен был работать безопасно и при включенном register_globals. Когда же я начал его тестировать, у меня был шок: так как мне нравится использовать функцию IsSet(), я нашел в ней непосредственную уязвимость, и в процессе мне пришлось от этого отказаться Что поделаешь...
Я очень надеюсь, что эта статья изменит ваше мнение относительно register_globals. Думаю, что со временем все хостинг провайдеры будут ставить register_globals = off по умолчанию. Но пока этого нет, вы знаете как с этим бороться;-)
Rating:
-2
Views: 1788Comments (3) »