Позавчера обратился ко мне один из заказчиков с проблемкой…
Проблема заключалась в следующем - после переноса всех скриптов и бд с одного хостинга на другой возникла проблема - не открывались страницы, отличные от главной. После просмотра кода (код, кстати, ужасный) - догадался в чем проблема - на старом хостинге в PHP флаг register_globals был включен, в новом - выключен, поэтому код типа:
if($id > 0) {
// загружаем страничку, соответствующую данному id
} else {
// загружаем index
}
совсем не работал (переменной $id в глобальном пространстве имен не было). Через пару минут в голову пришло решение - эмулировать работу флага register_globals. Где-то я уже видел такое решение, кажется в Joomla’е, но искать времени особо не было.
В итоге получилось следующее решение:
function register_globals_array($array)
{
foreach($array as $key => $value)
if(preg_match("/[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*/", $key))
$GLOBALS[$key] = $value;
}
function register_globals()
{
register_globals_array($_GET);
register_globals_array($_POST);
register_globals_array($_COOKIE);
register_globals_array($_ENV);
register_globals_array($_SERVER);
}
Пользуйтесь на здоровье.
PS. Да… Ну почему бОльшая часть кода на PHP написана так херово… :(





September 9th, 2007 at 03:23
extract($_GET);
extract($_POST);
extract($_COOKIE);
extract($_ENV);
extract($_SERVER);
Ы?
September 9th, 2007 at 04:10
ммм :) не знал, спасибо.
September 9th, 2007 at 04:14
Я когда-то возмущался почему вот описано так, а на сервере не работает. Нашел и сделал этот хак. А через месяц таки прочел главу Security в мануале, почесал в затылке, и заменил на обращения к $_*.
September 9th, 2007 at 04:16
Да там просто система такая, что лучше переписать, что, собственно, сейчас и планируется. А пока что - пусть так живет. :)
September 9th, 2007 at 10:44
Давно ушел с вариантом extract, потому как он когда-то конченый админ в целях безопасности (???) отключил эту функцию.
С тех времен все конфиг файлы у меня начинаются со строк:
foreach($_GET as $key=>$value) $$key=$value;
foreach($_POST as $key=>$value) $$key=$value;
и все довольны ;)
September 9th, 2007 at 14:06
А если в QUERY_STRING будет “1=1″ у тебя будет ошибка. Я ж не из головы regexp взял ;)
September 9th, 2007 at 15:28
Какая ошибка? Нет никакой ошибки.
Другой вопрос доступа к таким переменным будет доступно только через $_GET (в независимости от опции регистерс_глобалс) или если создавать переменные с заданым префиксом.. это решает extract или если модернизировать чуть-чуть мой код выше.
September 9th, 2007 at 15:42
Мдя. Мне вот интересно, и как оно интерпретирует вот такую штуку.
Ошибок не выдает, хотя должно… Мдя. Не нравится мне пхп. Ох, как не нравится.
September 11th, 2007 at 00:50
А что, это по русски: эмулировать дыру в безопасности :).
September 11th, 2007 at 00:57
Ну, в данном случае там ни о какой безопасности речи вообще не шло :)
September 11th, 2007 at 01:10
Видимо такая задача ставилась изначально и сразу :)
September 11th, 2007 at 01:12
Задача ставилась: “сделай так, чтобы оно хотя бы работало. Все равно все переделывать прийдется”.
September 11th, 2007 at 10:01
При правильной обработке переменных никакой дыры это не создает..;)
September 11th, 2007 at 23:27
Не создает? С этого места подробнее, плиз.
September 11th, 2007 at 23:30
Что именно?
September 12th, 2007 at 03:50
Подробнее о мысли выдвигаемой в тезисе “При правильной обработке переменных никакой дыры это не создает..;)”.
September 12th, 2007 at 03:57
А что тут непонятного? Если register_globals включена, то это не означает, что у тебя автоматически будут проблемы с безопасностью. Если код написан нормально, проверки где нужно стоят - все будет ок, никаких проблем не будет.
Кстати, обратное тоже верно - если register_globals == off, то это не значит, что твой сайт не хакнут ;)
September 12th, 2007 at 04:48
Я почему-то так и думал, что мысль будет из разряда максимально абстрактных :). Я вот о чем: включение опции позволяет злоумышленнику писать в глобальный контекст. Это же катастрофа. Особенно для сложных проектов которые создавались из расчета разграничения контекстов (к слову, эмуляция namespaces статическими свойствами класса позволяет беспокоиться меньше). Не будете же вы проверять переменную цикла в какой-то функции на предмет ее безопасности? (вопрос целесообразности подмены такой важной переменной оставим ввиду академичности примера :))
September 12th, 2007 at 05:01
2 правила программирования, которые ты рано или поздно поймешь, программируя на пхп:
2 правила - и накакие register_globals тебе не страшны.
September 12th, 2007 at 10:14
Если у тебя 1й выполняемый скрипт начинается с таких строк:
$value) $$key=$value;
foreach($_POST as $key=>$value) $$key=$value;
if(!isset($a)) $a=”;
if($a==’add_news’)
{
… // add news
}
if($a==’view’)
{
…
}
—
то тут как ни крути регистерс не влияет …
September 12th, 2007 at 15:30
Ех… хозяину блога, imho, следует обратиться с этим полным апломба (может и заслуженного, не знаю. Поправьте, если я что-то путаю) советом ко всем “кто в этом чате” - http://www.google.com/search?as_q=register_globals&hl=ru&num=10&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA+%D0%B2+Google&as_epq=&as_oq=vulnerability+%D1%83%D1%8F%D0%B7%D0%B2%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D1%8C&as_eq=&lr=&as_ft=i&as_filetype=&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=&as_rights=&safe=images
Возможно это облегчит жизнь многим, не столь молодым, людям. Грустно слышать…
Господа, я вижу к чему идет разговор. Давайте так, если мы спорим ради спора, то тогда вы правы, можно даже два раза.
September 12th, 2007 at 16:28
Причем тут спорим или не спорим.
Суть в том, что в независимости от параметра регистер_глобалс если проверять переменные на существование и обрабатывать ее согласно нашей цели, то никаким образом значение офф или он на безопасность скрипта не влияет.
September 12th, 2007 at 16:53
Это верно, да. С маленьким уточнением - инициализация в текущем контексте (как отмечено FX Poster выше) и проверка в контексте использования. Однако есть одно НО и существенное - это все де юре, де факто же имеем то, что имеем (см. гуглолинк выше). Не так разве? Вот например, как часто Вы проверяете контент куки-переменных? Моя практика показывает, что подавляющее большинство кодеров им безоговорочно доверяет, хотя скурпулезно валидируют GET и POST данные.
September 12th, 2007 at 16:58
Конченные кодеры значит.. я таких кодеров называю криворукие… ибо так и есть.
Абсолютно все проверяю… вот приведу функцию которая отвечает пользователь в системе или нет:
–
код кривоват немного потому как писался быстро. но работает причем отлично.
Суть в том, что в куках 2 переменные, юзернейм и пасс.
.. дальше я думаю понятно:
September 12th, 2007 at 17:02
некороые вырезки можно опустить… но какова цель была уже не помню… код был написан эдак 2004го года.. с тех пор использую его + модификацию и никаких проблем с данными из кук не будет.
Короче думаю дискуссию можно прекратить и сойтись на том, что в независимости от значения регистерс если кодер криворукий - его не спасет ничего.)
September 13th, 2007 at 09:43
появляется много вопросов - а зачем, а почему.. но понять можно - времени было мало (3 года).
типа если кто из умных увидит косяки - сразу 5 раз повторил: всё было сделано в темпе и кривоватенько, но зато мегасекьюрно, чёрт возьми!… :)
очень много ненужного - какие то куски чего-то мегамерзкого разбросаны по бедной функции…
мне вообще кажется какая-то функция “ниочём” - что он там защищает непонятно :)
хотя, возможно, где-то здесь таится тайный смысл: $user = table(”users”);
но он опять же по причине секьюрности код скрыт от глаз простых смертных КРИВЫХ кодеров :(
September 13th, 2007 at 17:44
проехали.
September 14th, 2007 at 00:10
Ultima ratio :). Впрочем не важно, кое-что из беседы было вынесено.