Что я знаю о register_globals

Постоянно сталкиваюсь с серверами, где по умолчанию register_globals = On. Да, мне ничто не мешает взять .htaccess и отключить: php_value register_globals Off или написать письмо администратору сервера. Однако, иногда и сам забываешь о той угрозе, которую несёт в себе register_globals = On.

Для того, что-бы воспользоваться чем-то, что даёт вам register_globals = On, нужно либо иметь на руках исходники скрипта, либо быть очень счастливым с…м сыном (ну ещё есть шанс, что ошибки, выбрасываемые PHP вам помогут). Естественно, речь идёт о Global Scope.

На днях я перебирал один маленький сайтик, где PHP используется только для того, что бы можно было удобно и быстро подключить хедер и футер, меню и для страниц легко менять тайтл и мета данные. Такой классический сайт из учебника, плюс несколько наворотов, которые позволяют кешировать сайт на стороне клиента так, как будто это статически HTML. Теоретически, если отключить expose_php и сделать ServerSignature Off, а ServerTokens Prod мало кто догадается, что это PHP.
И нашёл я там одну переменную, которая отвечала за подключение отдельного CSS для страницы. Она была задекларированна не во всех файлах, а толxко там, где требовался дополнительный CSS файл. Именно в тех файлах, где эта переменная не была установлена, её можно было установить при помощи GET, POST или COOKIE (ведь мы помним о variables_order). Плюс никакой фильтрации. Идеальное место для XSS type1 атаки. Но для такой атаки имя переменной нужно знать.

Есть ещё такой стиль программирования, когда массивы никто не декларирует, а сразу к ним обращается. Я имею ввиду, что некоторые программисты не пользуются таким выражением: $arr = array ();, а сразу выполнят присваивание: $arr[] = ‘some value’;. Опять же через GET, POST или COOKIE в таком случае можно передать первые ключи для массива $arr. И тогда сколько таких переменных есть у них, которые можно поменять, зная их имена?

Вроде и нет ничего страшного, действует только на Global Scope, надо знать название переменной, но вы не можете гарантировать, что копия сайта е попала в руки мальчишам-плохишам. Так, однажды, получив исходники одной CMS, можно досконально изучить её код, найти уязвимые места, а потом вскрыть этак сайтов 10-15 с одной и той-же ошибкой. Именно так однажды случилось с CMS моего знакомого: CMS решал, человек залоглен или нет, опираясь на онду переменную $admin_id. Стоило сделать запрос admin.php?admin_id=1 и коробочка раскрылась и даже не смотря на то, что этот $admin_id должен был придти из сессии – н там не был установлен (я взял новую сессию) и скрипт пощитал, что всё впорядке и можно пользоваться.

Короткое резюме: пишите свои проекты с учётом register_globals = Off; если вы уверены, что вами написанный проект отлично работает с register_globals = Off, а на сервере register_globals = On – отключите register_globals, так как в редких случаях это может вызвать неадекватное поведения вашего проекта; если вам приходиться работать со скриптами, которые требуют register_globals = On (только в том случае, если это необходимо), будьте предельно бдительны, не сделайте глупых ошибок, связанных со свойством register_globals = On, а также проведите аудит скрипта на возможные ошибки – вы последний, кто его редактировал и все бочки посыпятся на вас.

11 thoughts on “Что я знаю о register_globals

  1. lonelysoulNo Gravatar

    Абсолютно согласен с автором. Глобальные переменные несут больше вреда, чем пользы. Пользуйтесь суперглобальными массивами.

    Вопрос Автору: не совсем понял, как в примере с admin_id могла переменная, передающаяся через сессию, быть инициализирована через строку admin.php?admin_id=1?
    По идее, если проверка на существование переменной проходила через _SESSION[‘admin_id’], то вышенаписанная строка никак на это не могла повлиять даже при включенных глобальных переменных!

    Еще вопрос: как советуете лучше отключить глобальные переменные – самому с помощью .htaccess(в корне?) или письмом админам?

  2. Сергей КуракинNo Gravatar Post author

    Проверка там была $admin_id, а если у вас в начале скрипта нет её декларации и в сессии его нет, то она будет декларирована из GPC переменных.

    Если у вас shared hosting и включены .htaccess – делайте через .htaccess; всё равно Apache будет их искать.
    Если у вас CGI/FastCGI то через php.ini (если я не ошибаюсь) – тут лучше посоветоваться с админами.

    Во всех других случаях – пишите админам.

  3. wws53No Gravatar

    Попытка установить register_globals = off через .htaccess приводит к потере доступа к странице (500 Internal Server Error). Как и куда вставлять директиву для .htaccess?

  4. Сергей КуракинNo Gravatar Post author

    Посмотрите в phpinfo() как установлен PHP. Внимательно смотрите на ключ “Server API” в первой таблице.

    Если там написано Apache, то вам нужно в .htaccess писать php_value register_globals Off.

    Если там написано CGI/FastCGI то попробуйте рядом с файлом положить php.ini и в нём написать register_globals = off.

    Если не помогло, попробуйте тогда прмо в файле написать ini_alter(‘register_globals’, ‘Off’);

    Вообще, странно, что у вас register_globals по умолчанию включены.

  5. СергейNo Gravatar

    Категорически не согласен с автором. register_globals on – единственно логичное решение. Все мои проекты изначально разрабатываются именно под register_globals on.

  6. Сергей КуракинNo Gravatar Post author

    Сергей, который со мной категорически не согласен, рекомендую прочесть вот это: http://www.php.net/register_globals – с версии 4.2.0 их по умолчания выключили, с версии 5.3.0 они не рекомендуются (DEPRECATED), с версии 6.0.0 этой настройки вообще не будет и эта функция будет выключена Наверно не зря так поступили.

    Так как сам лично я не раз взламывал сайты (во время аудита безопастности), у которых register_globals on и программисты пропускали защиту определённых мест – я по прежнему рекомендую всегда держать register_globals off.

    Но каждый волен делать так, как ему кажется более логичным.

  7. ВикторNo Gravatar

    Как отключить register_globals ???

    Создаешь htaccess.txt на рабочем столе и пишешь в нем:

    php_flag register_globals off
    php_value register_globals Off

    сохраняешь и закачиваешь файл на сервер и переименовываешь его в .htaccess расширение .txt тоже убираем. Все готово теперь он откючен.

  8. МаргаритаNo Gravatar

    Здравствуйте!!!пожалуйста помогите мне кто-нибудь запретить доступ к сайту с определённого IP.
    Я вычитала что нужно ввести следующую комбинацию:
    order allow deny
    deny from all
    denny from
    но я не поняла куда это нужно вводить…
    IP-адрес у меня есть
    Надеюсь на Вашу поддержку

  9. Сергей КуракинNo Gravatar Post author

    Маргарита, это “шаманство” пишется в .htaccess файл в каталоге, который требуется закрыть от посторонних глаз.

    order allow,deny
    deny from all
    allow from X.X.X.X

    Где X.X.X.X это IP с которого доступ разрешён

  10. WebfontanNo Gravatar

    На некоторых хостингах приходится делать php_value register_globals On, чтобы заработали сессии. При чем это всегда подсказывает сама техподдержка хостинга. Так что пока вопрос остается актуальным.

  11. KorniloFFNo Gravatar

    Согласен, глобальные переменные свое уже отжили. Да и раньше их не особо использовали.
    А вот про финт с подменой сессионной переменной переменной из Global Scope интересен. Думаю, мало кто знает о такой возможности. )

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.