register_globals=oN Вы в опасности! PHP


InterMaster.com.ru

Это может быть интересно не только мне

Как «обойти» проблему register_globals OFF

Бывают ситуации, когда хостер по каким-либо причинам ставит значение параметра register_globals OFF. В этом случае у многих вебмастеров возникают проблемы с работой сайтов. Я сам недавно столкнулся с такой ситуацией – в скрипты перестали передаваться параментры из URL’а. Служба поддержки хостера любезно сообщила, что постарается решить мою проблему, но, вероятно, из-за новогодних праздников никак не могла сконцентрироваться на решении вопроса. Пришлось действовать самостоятельно.

Из тематических форумов узнал, что обойти проблему глобального register_globals OFF можно одним из двух вариантов:

В файл .htaccess нужно вставить строку:

Однако, если PHP работает как CGI, то сайт работать не будет – полезет ошибка 500. В этом случае строку “php_value register_globals On” из файла .htaccess убираем, создаем файл php.ini, пишем в нем:

и загружаем в корневую директорию сайта. Теперь все работает 🙂

Register_globals=oN? Вы в опасности! PHP

Здесь могла бы быть ваша реклама

Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006
Откуда: Israel

Секрет
Теперь, когда вы уже наверняка второпях отправили свой запрос,
я расскажу вам простой секрет, который сэкономит вам уйму ожиданий,
даже если первый ответ по теме последуем сразу же.

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

После этого приходится начинать уточнять этим неграмотным что мне надо.
Они что, сами читать не умеют? А уточнять приходится.
И иногда пока они переварят то что я им скажу проходит и не одна ночь..

Уверен что если бы я им сказал что у меня есть
фиолетовый квадрат, и нужно превратить его в синий треугольник
и я пытался взять кисточку, макнуть в банку и поводить ей по квадрату
но почему то кисточка не принимала цвет краски в банке,
то на мой вопрос — где взять правильные банки мне бы ответили гораздо быстрее
предложив её открыть, а не тратить еще стольник на жестянку.

Поэтому с тех пор я строю свои вопросы по проверенной давным давно схеме:
Что есть
Что нужно получить
Как я пытался
Почему или что у меня не получилось.

На последок как оно происходит на форумах

Новичок: Подскажите пожалуста самый крепкий сорт дерева! Весь инет перерыл, поиском пользовался!
Старожил: Объясни, зачем тебе понадобилось дерево? Сейчас оно в строительстве практически не используется.
Новичок: Я небоскрёб собираюсь строить. Хочу узнать, из какого дерева делать перекрытия между этажами!
Старожил: Какое дерево? Ты вообще соображаешь, что говоришь?
Новичок: Чем мне нравиться этот форум — из двух ответов ниодного конкретного. Одни вопросы неподелу!
Старожил: Не нравится — тебя здесь никто не держит. Но если ты не соображаешь, что из дерева небоскрёбы не строят, то лучше бы тебе сначала школу закончить.
Новичок: Не знаите — лучше молчите! У меня дедушка в деревянном доме живёт! У НЕГО НИЧЕГО НЕ ЛОМАЕТСЯ.
Но у него дом из сосны, а я понимаю, что для небоскрёба нужно дерево прочнее! Поэтому и спрашиваю. А от вас нормального ответа недождёшся.
Прохожий: Самое крепкое дерево — дуб. Вот тебе технология вымачивания дуба в солёной воде, она придаёт дубу особую прочность:
Новичок: Спасибо, братан! То что нужно.

Отредактировано модератором: Uchkuma, 26 Апреля, 2011 — 10:21:12

Если register_globals=Off

В связи с тем, что очень часто возникают вопросы по глобальным переменным и проблемам, связанным с отключением директивы register_globals, попробуем немного раскрыть эту тему в данной статье.

Для начала определим, что такое внешние переменные. Это любые переменные, которые поступают в программу извне, т.е. не определены в самой программе. Для скрипта на php все переменные, которые передаются через строку браузера или через форму являются внешними.
Рассмотрим, как они создаются.

Если на сервере включена директива register_globals = On (в php.ini), то при передаче переменных через форму или через строку браузера, в скрипте, которому эти переменные предназначены, они будут созданы автоматически. Т.е. если у вас в строке браузера написано: www.server.ru/index.php?var=1, то в скрипте index.php будет автоматически создана переменная $var со значением равным 1.

Замечание


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

В настоящий момент у большинства хост-провайдеров эта директива включена и, по-видимому, будет оставаться включенной еще долгое время, поскольку в противном случае может нарушиться преемственность кода.

При отключенной директиве register_globals доступ к таким переменным возможен двумя способами:

  • через ассоциативные массивы HTTP_***_VARS (HTTP_POST_VARS и т.д.)
  • через суперглобальные массивы ($_ENV, $_GET, $_POST, $_SERVER, $_COOKIE, $_FILES и др.)

Суперглобальные массивы доступны в любой области видимости. Разработчики PHP рекомендуют отключать на сервере директиву register_globals и работать с переменными через суперглобальные массивы. Эта рекомендация связана с проблемами безопасности, которые могли возникнуть при включенной директиве register_globals.

Хотя до недавнего времени на хостингах директива register_globals оставалась включенной. Ситуация начала меняться с выходом PHP 5, где эта директива по умолчанию выключена и хостеры не спешат ее включать (может быть и правильно).

Итак, что же конкретно сделать чтобы получить переменные — нужно взять их из суперглобальных массивов. Например, для получения переменных, переданных через строку браузера, используют массив $_GET. Допустим, в строке браузера написано www.server.ru/index.php?var=1, Тогда для получения переменной var в index.php нужно написать:

А, например, для получения переменных переданных из формы методом POST в скрипте-обработчике формы нужно написать:

Характеристики загруженного файла доступны через двумерный суперглобальный-массив $_FILES. При этом переменная со значениями этого массива может иметь следующий вид:

  • $_FILES[«filename»][«name»] (содержит исходное имя файла на клиентской машине);
  • $_FILES[«filename»][«size»] (содержит размер загруженного файла в бай-тах);
  • $_FILES[«filename»][«type»] (содержит MIME-тип файла);
  • $_FILES[«filename»][«tmp_file»] (содержит имя временного файла, в кото-рый сохраняется загруженный файл).

А для того, чтобы к примеру, воспользоваться переменной $DOCUMENT_ROOT, нужно использовать суперглобальный массив $_SERVER:

Директива register_globals

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

Директива register_globals позволяет регистрировать переменные, полученные из GET-запроса. Допустим, был такой запрос: index.php?a=15. Таким образом, безусловно, создаётся переменная $_GET[«a»] и переменная a. Вот создание переменной a и произошло в результате включённой директивы register_globals.

Теперь о том, почему данную директиву надо всегда держать отключённой. Предположим, что Вы делаете авторизацию пользователя, и Вы написали такой код:

Теперь если файл называется, например, auth.php, то, обратившись к нему следующим образом: auth.php?check_user=1, то получится успешная авторизация, независимо от того, какие логин и пароль были отправлены и были ли отправлены вообще.

Мастер Йода рекомендует:  Как исправить распространённые ошибки в популярных языках программирования

Безусловно, данный пример является слегка мистическим, поскольку так никто не пишет (хотя бы из-за отсутствия else $check_user = false;), однако, данный пример наглядно показывает, к чему может привести включённая директива register_globals.

Теперь о том, как же отключить директиву register_globals. Для этого надо добавить в файл .htaccess всего одну строчку:

php_value register_globals 0

Есть небольшая вероятность, что если директива была раньше включена, то у Вас может что-нибудь сломаться, поэтому всё внимательно проверьте и устраните все возникшие ошибки, поскольку безопасность того действительно стоит.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.


Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

Она выглядит вот так:

  • BB-код ссылки для форумов (например, можете поставить её в подписи):
  • Комментарии ( 2 ):

    Mihail u vas opechatka v etoj statje , v pervom obzace » ob ja napishu v etoj statje».

    Уже исправил, спасибо!

    Для добавления комментариев надо войти в систему.
    Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.

    Copyright © 2010-2020 Русаков Михаил Юрьевич. Все права защищены.

    Эмуляция директивы register_globals on

    Есть в PHP такая интересная директива, под названием register_globals, определенная в php.ini. Директива указывает компилятору, что значения входящих (глобальных) переменных следует изъять из их системных массивов и представить в виде самостоятельных переменных. К таким данным относится все, что передается в скрипт «снаружи»: данные из форм, данные из URL, cookie и так далее. Лично мне эта директива нравится, ибо она экономит время написания скриптов и делает их более читаемыми. Сравните сами, что выглядит приятнее и удобнее для глаза:

    Вообще, лично я люблю PHP в основном за его удобочитаемость и быстрое написание.

    Тем не менее, в каждой удобной фишке обязательно таится какая-нибудь гадость. Не обошлось без неприятностей и с регистрацией глобальных переменных. Невнимательные программисты оставляли в своих скриптах дыры, которые можно было обнаружить и использовать со стороны пользователя. Проще говоря, если переменная внутри скрипта участвовала в работе, но не устанавливалась этим же скриптом, ее можно было установить «снаружи», передав ее имя и значение в скрипт через URL, cookie или еще как-нибудь.

    Эта дыра, которую записали в разряд «дыр в PHP» лично я считаю дырой в программировании, а не в языке, вынудила разработчиков PHP рекомендовать отключение register_globals. Что тут же было воспринято общественность как руководство к действию: все стали выключать регистрацию глобальных переменных на своих серверах.

    Может быть это и не так уж плохо, судить не буду, ведь ради безопасности иногда возводят и городят гораздо больше, чем код самой задачи.

    Но повальный отказ от регистрации глобальных переменных привело к новой проблеме — многие скрипты надо переписывать чуть ли не с нуля, ибо надо проверить каждую строку, найти все используемые переменные и поменять их на «защищенные» аналоги.

    Насколько я понимаю, подобная задача, в конце концов, сводится к тому, чтобы в начале работы скрипта присвоить привычным переменным их значения из глобальных массивов $_REQUEST, $_POST, $_GET, $_COOKIE, $_SERVER и т.д.

    Так к чему же я веду. А вот к чему. Нормальный программист не должен допускать дыр в своих скриптах, подобных дырам на основе автоматической регистрации глобальных переменных, но разве это будет волновать администратора сервера, на котором решено разместить код? Нет, это его не волнует и он по-своему прав.

    Поэтому, если вы написали на заказ программу с использованием глобальных переменных, а заказчик решил установить ее на сервере, где запрещена их регистрация, то ничего работать не будет — у вас проблемы.


    Если вы решили перенести все свои проекты на новый хостинг, а провайдер запрещает использовать регистрацию глобальных переменных — у вас проблемы.

    Как быть? Не вычитывать же десятки, сотни, а иногда и тысячи страниц кода в поисках использования глобальных переменных.

    Я предлагаю следующее решение. Надо просто эмулировать работу register_globals в одном отдельно взятом скрипте или в начале объектно-ориентированной стркутуры.

    Как это сделать. Да не очень уж и сложно. Давайте рассуждать логически: имена переменных и их значения содержатся в соответствующих глобальных массивах. Как правило, используется массив $_REQUEST, который объединяет в себе все переменных GET, POST и COOKIE. Т.е. все, что передается скрипту из браузера, то, с чем работают скрипты.

    Значит, надо извлечь из массива имена переменных, значения переменных и присвоить первому — второе. Извлечь — не проблема, для этого подойдет функция перебора всех ячеек массива foreach(), но как присвоить? Если у нас в $_REQUEST[username] содержится «atos», то как программно создать переменную $username со значением «atos»? Мы же не можем заранее знать, какие имена переменных будут в массиве $_REQUEST.

    Вот тут нам поможет изумительная функция eval(), которая редко используется в обычном программировании, но буквально незаменима в некоторых случаях. О самой функции стоит написать отдельно, поэтому скажу только пару слов для тех, кто с ней не знаком.

    Функция eval() заставляет PHP рассматривать обыкновенный текст, содержащийся в переменной, как фрагмент PHP-кода. Говоря языком примеров, результаты работы строк

    Вот eval() и поможет нам объявить все переменные из массива $_REQUEST. Выглядит это совсем коротко:

    Вставьте этот цикл в самом начале вашего скрипта; он переберет массив глобальных переменных и объявит их не хуже register_globals. А может быть даже и лучше, т.к. глобальных массивов много, а вытаскивать переменные не обязательно из всех. Как правило, данных из массива $_REQUEST — вполне достаточно.

    Однако, не стоит забывать и о безопасности вашего кода. Обратите внимание на специфику работы функции eval() — она обработает весь код, переданный ей в качестве параметра. Будьте осторожны, примите меры безопастности, чтобы злоумышленник не подсунул в качестве названия или содержимого переменной кусок своего php-кода или просто неверные данные, способные вызвать ошибку (например, имя переменной, начинающее с цифры или другого неразрешенного символа).

    P.S. После опубликования этой заметки, на форуме не один раз высказывались мысли о том, что вариант с eval() — не самый лучший. Лично я предпочитаю оставлять для себя «путь к отступлению», и eval() как раз привлекателен тем, что позволяет полностью контролировать процесс, добавляя необходимые проверки и ограничения в процедуру или наоборот — расширяя возможности кода. Например, можно добавить логирование регистрации отдельных переменных, чтобы знать — кто, куда, откуда, зачем, или четко запретить к регистрации определенные имена переменных или другие данные.

    Впрочем, у каждого метода есть свои плюсы и свои минусы — думайте сами, решайте сами — как поется в известной песне.

    Как видите, тоже простой метод, основанный на том, что значение переменной $k используется в качестве имени новой переменной. Удобно. Отличается автоматической регистрацией не только переменных, но и массивов. В случае с методом eval() придется проверять каждую переменную на is_array() и разворачивать (регистрировать) ее дополнительно, если такой массив вам нужен.

    И самый простой метод — extract().

    Весь код нашего примера будет выглядеть так:

    Это самый «тупой» метод, «разворачивающий» в переменные все, что содержится в массиве $_REQUEST. Нет абсолютно никакой гибкости в этом подходе — повлиять на регистрацию переменных или ввести какой-либо контроль вы не сможете, но выглядит очень лаконично.

    И, наконец, не забывайте о том, что register_globals можно активировать не только в конфигурационном файле Apache, но и в файле .htaccess вашего сайта.

    What are register_globals in PHP?

    Can someone give some examples of what register_globals are?
    And is global $user_id; considered a register global?

    7 Answers 7

    The register_globals directive:

    register_globals is an internal PHP setting which registers the $_REQUEST array’s elements as variables. If you submit a value in a form, via POST or GET , the value of that input will automatically be accessible via variable in the PHP script, named after the name of the input field.

    Мастер Йода рекомендует:  Python-фреймворк для веб-разработки Django обновился до версии 1.11

    In other words, if you submitted a form containing a username text field, the expression ($username === $_POST[‘username’]) at the very beginning of the script would return true .

    Its notoriety is attributed to the fact that it opens lots of security holes, especially for people that follow anything less than a strict coding style from a security perspective.


    Now, if you visited that script in a web browser and the server had register_globals on, you could simply append ?authorized=1 to the URL and god-mode would be enabled!

    The global keyword:

    global is a keyword has little to do with register_globals.

    Here is an example of its use:

    Everyone mentioning GET , POST , REQUEST , COOKIE has effect on register_globals=on .

    I’m just writing this to let you know that —

    $_SESSION will be affected aswell because of register_globals=on . http://php.net/manual/en/security.globals.php

    That means — if you do as following —

    The output will be asd .

    And this will cause serious security issues and bugs. I have experienced such a bad thing recently during using Hostgator shared hosting. By Default they have register_globals=on .

    When you have register_globals=on, anything passed via GET or POST or COOKIE automatically appears to be global variable in code, this might have security consequences.

    I.e. you click on url test.php?access_level=100 and you’ll have $access_level = 100 in PHP.

    When you do global $somevar — you are making your own global variable, which usually is not a big issue.

    The register_globals setting controls how you access form, server, and environment. variables.

    register_globals=On :

    You can access form attribute without Global Arrays ( GET[], POST[] & REQUEST[] )

    You can access directly in one.php

    register_globals=Off :

    You have to access all attributes only by Global Arrays.

    You have to access in one.php

    As I understand it, if you have register globals turned ON, then anything passed in a GET or POST gets automatically translated into a variable in PHP.

    without any further coding this would automatically get turned into a variable available to the rest of your php code

    With registered globals OFF, data passed in via GET or POST is NOT automatically translated into a variable, rather, you need to request it using the Superglobals $_GET, $_POST, and $_REQUEST, etc.

    http://php.net/manual/en/security.globals.php provides some further information as to the security implications of this.


    Others can feel free to correct me if I’m wrong.

    in relation to your question re global $user_id; , this does not create a ‘global’ in the sense of ‘register_globals’. It simply alters the scope of a variable within the PHP code.

    register_globals The feature causes data passed to a PHP script via cookies or GET and POST requests to be made available as global variables in the script.

    Default Value : «0»

    register_globals is affected by the variables_order directive.

    This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.

    Global variables in php are variables that are always accessible. They are also known as superglobals. They are built in variables that are always available regardless of the scope.

    There are nine superglobal variables in PHP. Some of these are relevant to this discussion.

    Now, let’s focus on the $_REQUEST superglobal. It is used to collect data after submitting an HTML form by user using the POST method.

    $_POST and $_REQUEST could be used loosely interchangeably. But $_REQUEST also contains $_GET and $_COOKIE along with $_POST so you are never sure if your data came from a web form.

    Now, as pointed out by @Tim register_globals is an internal PHP setting which registers the $_REQUEST array’s elements as variables. It is also known as a flag in your php setting. It is typically set in the PHP configuration file known as php.ini file. This setting can have two values.

    An “on” value means that PHP will automatically create global variables for many server variables as well as query string parameters. This is not good and is a security risk.

    База знаний

    Здесь Вы найдёте информацию о предоставляемых функциях, устранению неполадок,
    а также другую техническую информацию, связанную с хостингом Hostinger.

    • Категории
    • PHP
    • Просмотр Статьи

    Как активировать register_globals?

    PHP register_globals отключена на наших серверах по причинам безопасности. Все современные скрипты не используют register_globals и если Вы получаете какие-либо ошибки связанные с register_globals, Вам нужно проверить Ваш код, либо обратиться к разработчику скрипта за помощью. Однако, Вы можете включить register_globals добавив код в файл .htaccess:

    php_flag register_globals on

    Мы не рекомендуем включать эту функцию, т.к. это может привести к проблемам с безопасностью на Вашем сайте.

    Статьи и Руководства


    Полный список статей для знакомства с веб-разработкой. Узнайте о сфере программирования. Найдите информацию по использованию панели управления Hostinger.

    База знаний

    Здесь Вы найдёте информацию о предоставляемых функциях, устранению неполадок,
    а также другую техническую информацию, связанную с хостингом Hostinger.

    • Категории
    • PHP
    • Просмотр Статьи

    Как активировать register_globals?

    PHP register_globals отключена на наших серверах по причинам безопасности. Все современные скрипты не используют register_globals и если Вы получаете какие-либо ошибки связанные с register_globals, Вам нужно проверить Ваш код, либо обратиться к разработчику скрипта за помощью. Однако, Вы можете включить register_globals добавив код в файл .htaccess:

    php_flag register_globals on

    Мы не рекомендуем включать эту функцию, т.к. это может привести к проблемам с безопасностью на Вашем сайте.

    Статьи и Руководства

    Полный список статей для знакомства с веб-разработкой. Узнайте о сфере программирования. Найдите информацию по использованию панели управления Hostinger.

    Что такое register_globals в PHP?

    Может кто-нибудь дать некоторые примеры того, что register_globals ?
    И global $user_id; считается регистром глобальным?

    Директива register_globals :

    register_globals — внутренний параметр PHP, который регистрирует элементы массива $_REQUEST как переменные. Если вы передадите значение в форме, через POST или GET , значение этого ввода будет автоматически доступно через переменную в PHP скрипт, названной в имени имени поля ввода.

    Другими словами, если вы отправили форму, содержащую текстовое поле username , выражение ($username === $_POST[‘username’]) в самом начале script вернет true .

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

    Теперь, если вы посетили этот script в веб-браузере, а на сервере был register_globals , вы можете просто добавить ?authorized=1 к URL-адресу, и божественный режим будет включен!

    Ключевое слово global :

    global — ключевое слово имеет мало общего с register_globals.

    Вот пример его использования:


    Все, упоминающие GET , POST , REQUEST , COOKIE , влияют на register_globals=on .

    Я просто пишу это, чтобы вы знали, что —

    $_SESSION будет затронут, а также из-за register_globals=on . http://php.net/manual/en/security.globals.php

    Это означает — если вы делаете следующее:

    Выход будет asd .

    И это вызовет серьезные проблемы с безопасностью и ошибки. Недавно я столкнулся с такой плохой проблемой при использовании хостинга Hostgator. По умолчанию у них есть register_globals=on .

    Когда у вас есть register_globals = on, все, что передается через GET или POST или COOKIE, автоматически становится глобальной переменной в коде, это может иметь последствия для безопасности.

    т.е. вы нажимаете url test.php? access_level = 100, и у вас будет $access_level = 100 в PHP.

    Когда вы делаете глобальный $somevar — вы создаете свою собственную глобальную переменную, которая обычно не является большой проблемой.

    Параметр register_globals контролирует доступ к форме, серверу и среде. переменные.

    register_globals = On:

    Вы можете получить доступ к атрибуту формы без глобальных массивов (GET [], POST [] и REQUEST [])

    Вы можете получить доступ непосредственно в one.php

    register_globals = Выкл.:

    Вам нужно получить доступ ко всем атрибутам только глобальным массивам.

    Мастер Йода рекомендует:  Как Facebook масштабирует архитектуру чата с нагрузкой в миллиарды сообщений в день

    Вам нужно получить доступ в one.php

    Как я понимаю, если вы включили глобальные регистры, все, что передается в GET или POST, автоматически преобразуется в переменную в PHP.

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

    С зарегистрированными глобальными значениями ВЫКЛ данные, переданные через GET или POST, НЕ автоматически преобразуются в переменную, а вам нужно запросить его, используя Superglobals $_GET, $_POST и $_REQUEST и т.д.

    http://php.net/manual/en/security.globals.php содержит дополнительную информацию о последствиях для безопасности.

    Другие могут отреагировать на меня, если я ошибаюсь.

    изменить

    по отношению к вашему вопросу re global $user_id; , это не создает «глобального» в смысле «register_globals». Он просто изменяет область действия переменной в PHP-коде.

    Глобальные переменные в php — это переменные, которые всегда доступны. Они также известны как суперглобалы. Они встроены в переменные, которые всегда доступны независимо от области действия.


    В PHP существует девять суперглобальных переменных. Некоторые из них имеют отношение к этому обсуждению.

    Теперь сосредоточьтесь на суперглобале $_REQUEST . Он используется для сбора данных после отправки HTML-формы пользователем с использованием метода POST .

    $_POST и $_REQUEST можно использовать взаимозаменяемо. Но $_REQUEST также содержит $_GET и $_COOKIE вместе с $_POST , поэтому вы никогда не уверены, что ваши данные поступают из веб-формы.

    Теперь, как указано @Tim register_globals , это внутренний параметр PHP, который регистрирует элементы массива $_REQUEST в качестве переменных. Он также известен как flag в вашей настройке php. Обычно он задается в файле конфигурации PHP, который известен как php.ini . Этот параметр может иметь два значения.

    Значение «on» означает, что PHP автоматически создаст глобальные переменные для многих переменных сервера, а также параметры строки запроса. Это нехорошо и представляет угрозу безопасности.

    Эмуляция директивы register_globals on

    Есть в PHP такая интересная директива, под названием register_globals, определенная в php.ini. Директива указывает компилятору, что значения входящих (глобальных) переменных следует изъять из их системных массивов и представить в виде самостоятельных переменных. К таким данным относится все, что передается в скрипт «снаружи»: данные из форм, данные из URL, cookie и так далее. Лично мне эта директива нравится, ибо она экономит время написания скриптов и делает их более читаемыми. Сравните сами, что выглядит приятнее и удобнее для глаза:

    Вообще, лично я люблю PHP в основном за его удобочитаемость и быстрое написание.

    Тем не менее, в каждой удобной фишке обязательно таится какая-нибудь гадость. Не обошлось без неприятностей и с регистрацией глобальных переменных. Невнимательные программисты оставляли в своих скриптах дыры, которые можно было обнаружить и использовать со стороны пользователя. Проще говоря, если переменная внутри скрипта участвовала в работе, но не устанавливалась этим же скриптом, ее можно было установить «снаружи», передав ее имя и значение в скрипт через URL, cookie или еще как-нибудь.

    Эта дыра, которую записали в разряд «дыр в PHP» лично я считаю дырой в программировании, а не в языке, вынудила разработчиков PHP рекомендовать отключение register_globals. Что тут же было воспринято общественность как руководство к действию: все стали выключать регистрацию глобальных переменных на своих серверах.

    Может быть это и не так уж плохо, судить не буду, ведь ради безопасности иногда возводят и городят гораздо больше, чем код самой задачи.

    Но повальный отказ от регистрации глобальных переменных привело к новой проблеме — многие скрипты надо переписывать чуть ли не с нуля, ибо надо проверить каждую строку, найти все используемые переменные и поменять их на «защищенные» аналоги.

    Насколько я понимаю, подобная задача, в конце концов, сводится к тому, чтобы в начале работы скрипта присвоить привычным переменным их значения из глобальных массивов $_REQUEST, $_POST, $_GET, $_COOKIE, $_SERVER и т.д.

    Так к чему же я веду. А вот к чему. Нормальный программист не должен допускать дыр в своих скриптах, подобных дырам на основе автоматической регистрации глобальных переменных, но разве это будет волновать администратора сервера, на котором решено разместить код? Нет, это его не волнует и он по-своему прав.

    Поэтому, если вы написали на заказ программу с использованием глобальных переменных, а заказчик решил установить ее на сервере, где запрещена их регистрация, то ничего работать не будет — у вас проблемы.

    Если вы решили перенести все свои проекты на новый хостинг, а провайдер запрещает использовать регистрацию глобальных переменных — у вас проблемы.

    Как быть? Не вычитывать же десятки, сотни, а иногда и тысячи страниц кода в поисках использования глобальных переменных.

    Я предлагаю следующее решение. Надо просто эмулировать работу register_globals в одном отдельно взятом скрипте или в начале объектно-ориентированной стркутуры.

    Как это сделать. Да не очень уж и сложно. Давайте рассуждать логически: имена переменных и их значения содержатся в соответствующих глобальных массивах. Как правило, используется массив $_REQUEST, который объединяет в себе все переменных GET, POST и COOKIE. Т.е. все, что передается скрипту из браузера, то, с чем работают скрипты.

    Значит, надо извлечь из массива имена переменных, значения переменных и присвоить первому — второе. Извлечь — не проблема, для этого подойдет функция перебора всех ячеек массива foreach(), но как присвоить? Если у нас в $_REQUEST[username] содержится «atos», то как программно создать переменную $username со значением «atos»? Мы же не можем заранее знать, какие имена переменных будут в массиве $_REQUEST.

    Вот тут нам поможет изумительная функция eval(), которая редко используется в обычном программировании, но буквально незаменима в некоторых случаях. О самой функции стоит написать отдельно, поэтому скажу только пару слов для тех, кто с ней не знаком.

    Функция eval() заставляет PHP рассматривать обыкновенный текст, содержащийся в переменной, как фрагмент PHP-кода. Говоря языком примеров, результаты работы строк

    Вот eval() и поможет нам объявить все переменные из массива $_REQUEST. Выглядит это совсем коротко:

    Вставьте этот цикл в самом начале вашего скрипта; он переберет массив глобальных переменных и объявит их не хуже register_globals. А может быть даже и лучше, т.к. глобальных массивов много, а вытаскивать переменные не обязательно из всех. Как правило, данных из массива $_REQUEST — вполне достаточно.

    Однако, не стоит забывать и о безопасности вашего кода. Обратите внимание на специфику работы функции eval() — она обработает весь код, переданный ей в качестве параметра. Будьте осторожны, примите меры безопастности, чтобы злоумышленник не подсунул в качестве названия или содержимого переменной кусок своего php-кода или просто неверные данные, способные вызвать ошибку (например, имя переменной, начинающее с цифры или другого неразрешенного символа).

    P.S. После опубликования этой заметки, на форуме не один раз высказывались мысли о том, что вариант с eval() — не самый лучший. Лично я предпочитаю оставлять для себя «путь к отступлению», и eval() как раз привлекателен тем, что позволяет полностью контролировать процесс, добавляя необходимые проверки и ограничения в процедуру или наоборот — расширяя возможности кода. Например, можно добавить логирование регистрации отдельных переменных, чтобы знать — кто, куда, откуда, зачем, или четко запретить к регистрации определенные имена переменных или другие данные.

    Впрочем, у каждого метода есть свои плюсы и свои минусы — думайте сами, решайте сами — как поется в известной песне.

    Как видите, тоже простой метод, основанный на том, что значение переменной $k используется в качестве имени новой переменной. Удобно. Отличается автоматической регистрацией не только переменных, но и массивов. В случае с методом eval() придется проверять каждую переменную на is_array() и разворачивать (регистрировать) ее дополнительно, если такой массив вам нужен.

    И самый простой метод — extract().

    Весь код нашего примера будет выглядеть так:

    Это самый «тупой» метод, «разворачивающий» в переменные все, что содержится в массиве $_REQUEST. Нет абсолютно никакой гибкости в этом подходе — повлиять на регистрацию переменных или ввести какой-либо контроль вы не сможете, но выглядит очень лаконично.

    И, наконец, не забывайте о том, что register_globals можно активировать не только в конфигурационном файле Apache, но и в файле .htaccess вашего сайта.

    Добавить комментарий