09.08.2022

Почему опасно включать параметр PHP register_globals? Создание простой системы регистрации пользователей на PHP и MySQL Необозримый index php register


В связи с тем, что очень часто возникают вопросы по глобальным переменным и проблемам, связанным с отключением директивы 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 нужно написать:

$var=$_GET["var"];

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

$var=$_POST["var"];

Reg.ru: домены и хостинг

Крупнейший регистратор и хостинг-провайдер в России.

Более 2 миллионов доменных имен на обслуживании.

Продвижение, почта для домена, решения для бизнеса.

Более 700 тыс. клиентов по всему миру уже сделали свой выбор.

*Наведите курсор мыши для приостановки прокрутки.

Назад Вперед

Создание простой системы регистрации пользователей на PHP и MySQL

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

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

В этом уроке, мы создадим очень простую систему регистрации, которая не требует и не хранит паролей вообще! Результат будет легко изменить и добавить к уже существующему PHP-сайту. Хотите выяснить, как это работает? Читайте ниже.



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

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

После этого создаётся некий случайный уникальный набор символов (токен), который отправляется на указанную пользователем почту в виде ссылки, которая будет актуальна в течение 10 минут;
- По ссылке пользователь переходит на наш сайт. Система определяет наличие токена и авторизует пользователя;

Преимущества такого подхода:

Не нужно хранить пароли и осуществлять валидацию полей;
- Нет необходимости в восстановлении пароля, секретных вопросов и т.д.;
- С момента как пользователь зарегистрировался/авторизовался вы можете всегда быть уверены, что этот пользователь будет в вашей зоне доступа (что email-адрес является истинным);
- Невероятно простой процесс регистрации;

Недостатки:

Безопасность аккаунта пользователя. Если кто-то имеет доступ к почте пользователя, он может авторизоваться.
- Email не защищён и может быть перехвачен. Имейте в виду, что этот вопрос актуален и в случае, когда пароль был забыт и его необходимо восстановить, или в любой системе авторизации, которая не использует HTTPS для передачи данных (логин/пароль);
- Пока вы настроите как нужно почтовый сервер, существует шанс, что сообщения со ссылками на авторизацию будут попадать в спам;

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

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

Как пользоваться этой системой

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

Вам нужно скачать исходники, приложенные к уроку
- В архиве найти файл tables.sql Импортируйте его в вашу базу данных используя опцию импорта в phpMyAdmin. Альтернативный способ: открыть этот файл через текстовый редактор, скопировать SQL запрос и выполнить его;
- Открыть includes/main.php и заполнить настройки связи с вашей базой данных (указать пользователя и пароль для связи с базой а также хост и имя базы). В этом же файле, вы также должны указать email, который будет использован в качестве оригинального адреса для сообщений отправляемых системой. Некоторые хосты блокируют исходящие мейлы пока в форме не будет указан настоящий email адрес, который был создан из панели управления хостом, так что укажите реальный адрес;
- Загрузите все файлы index.php , protected.php и папки assets и includes через FTP на ваш хост;
- Добавьте код ниже на каждую PHP-страницу, где нужно отобразить форму авторизации;

Require_once "includes/main.php"; $user = new User(); if(!$user->loggedIn()){ redirect("index.php"); }
- Готово!

Для тех же, кому интересно, как это всё работает - вперёд к чтению ниже!

Первый шаг - написание HTM- кода формы авторизации. Данный код располагается в файле index.php . Этот файл также содержит PHP-код, обрабатывающий данные формы и другие полезные функции системы авторизации. Узнать об этом больше можно в разделе ниже, посвящённом обзору PHP кода.

index.php

Tutorial: Super Simple Registration System With PHP & MySQL Login or Register

Enter your email address above and we will send
you a login link.

Login / Register

В головной секции (между тегами и ) я подключил основные стили (в этом уроке они не разбираются, поэтому вы можете посмотреть их сами. Папка assets/css/style.css). До закрывающего тега я подключил библиотеку jQuery и файл script.js, который мы напишем и разберём чуть ниже.


JavaScript

jQuery отслеживает состояние кнопки "Зарегистрироваться/авторизоваться" с помощью функции e.preventDefault() и отправляет AJAX-запросы. В зависимости от ответа сервера, выводит то или иное сообщение и определяет дальнейшие действия/

assets/js/script.js

$(function(){ var form = $("#login-register"); form.on("submit", function(e){ if(form.is(".loading, .loggedIn")){ return false; } var email = form.find("input").val(), messageHolder = form.find("span"); e.preventDefault(); $.post(this.action, {email: email}, function(m){ if(m.error){ form.addClass("error"); messageHolder.text(m.message); } else{ form.removeClass("error").addClass("loggedIn"); messageHolder.text(m.message); } }); }); $(document).ajaxStart(function(){ form.addClass("loading"); }); $(document).ajaxComplete(function(){ form.removeClass("loading"); }); });

был добавлен в форму для отображения текущего состояния AJAX-запроса (это стало возможным благодаря методам ajaxStart() ) и ajaxComplete() , которые вы сможете найти ближе к концу файла).

Этот класс показывает крутящийся анимированный gif-файл (как бы намекающий нам на то, что запрос обрабатывается), и также выступает как флаг, предотвращающий повторную отправку формы (когда кнопка зарегистрироваться была уже однажды нажата). Класс .loggedIn - это другой флаг, - устанавливается тогда, когда был отправлен email. Этот флаг моментально блокирует любые дальнейшие действия с формой.

Схема базы данных

Наша невероятно простая система регистрации использует 2 MySQL таблицы (SQL-код находится в файле tables.sql ). Первая хранит данные об аккаунтах пользователей. Вторая хранит информацию о количестве попыток входа.


Схема таблицы пользователей.

Система не использует паролей, что видно на схеме. На ней же можно увидеть колонку token с токенами, соседствующую с колонкой token_validity . Токен устанавливается как только пользователь подключается к системе, задаёт свой email для отправки сообщения (чуть подробнее об этом в следующем блоке). Колонка token_validity устанавливает время на 10 минут позже, после которого токен перестаёт быть актуальным.


Схема таблицы, считающая количество попыток авторизации.

В обоих таблицах IP-адрес хранится в обработанном виде, с помощью функции ip2long в поле типа integer.

Теперь мы можем написать немножко PHP-кода. Основной функционал системы возложен на класс User.class.php , который вы можете видеть ниже.

Данный класс активно использует idorm (docs), эти библиотеки являются минимально необходимыми инструментами, для работы с базами данных. Он обрабатывает доступ к базе данных, генерацию токенов и их валидацию. Он представляет собой простой интерфейс, позволяющий легко подключить систему регистрации к вашему сайту, если он использует PHP.

User.class.php

Class User{ // Частный ORM случай private $orm; /** * Найти пользователя по токену. Только валидные токены, приняты к рассмотрению. Токен генерируется только на 10 минут с того момента как был создан * @param string $token. Это искомый токен * @return User. Вернуть значение функции User */ public static function findByToken($token){ // найти токен в базе и убедиться, что установлен корректный временной штамп $result = ORM::for_table("reg_users") ->where("token", $token) ->where_raw("token_validity > NOW()") ->find_one(); if(!$result){ return false; } return new User($result); } /** * Авторизовать или зарегистрировать пользователя * @param string $email. Пользовательский email-адрес * @return User */ public static function loginOrRegister($email){ // Если такой пользователь уже существует, вернуть значение функции User от заданного email-адреса хранимого в базе if(User::exists($email)){ return new User($email); } // В противном случае создать нового пользователя в базе и вернуть значение функции User::create от указанного email return User::create($email); } /** * Создать нового пользователя и сохранить в базу * @param string $email. Пользовательский email-адрес * @return User */ private static function create($email){ // Записать нового пользователя и вернуть результат функции User от этих значений $result = ORM::for_table("reg_users")->create(); $result->email = $email; $result->save(); return new User($result); } /** * Проверить, существует ли такой пользователь в базе и вернуть булево значение переменной * @param string $email. Пользовательский email-адрес * @return boolean */ public static function exists($email){ // Существует ли пользователь в базе? $result = ORM::for_table("reg_users") ->where("email", $email) ->count(); return $result == 1; } /** * Создать новый пользовательский объект * @param экземпляр $param ORM , id, email or 0 * @return User */ public function __construct($param = null){ if($param instanceof ORM){ // ORM проверка пройдена $this->orm = $param; } else if(is_string($param)){ // Проверка на email пройдена $this->orm = ORM::for_table("reg_users") ->where("email", $param) ->find_one(); } else{ $id = 0; if(is_numeric($param)){ // идентификатору пользователя передаётся значение переменной $param $id = $param; } else if(isset($_SESSION["loginid"])){ // В противном случае смотри сессию $id = $_SESSION["loginid"]; } $this->orm = ORM::for_table("reg_users") ->where("id", $id) ->find_one(); } } /** * Сгенерировать новый SHA1 токен авторизации, записывает в базу и возвращает его значение * @return string */ public function generateToken(){ // Сгенерировать токен для авторизованного пользователя и сохранить его в базу $token = sha1($this->email.time().rand(0, 1000000)); // Сохранить токен в базе // И пометить его, что он актуален только в течение 10 следующих минут $this->orm->set("token", $token); $this->orm->set_expr("token_validity", "ADDTIME(NOW(),"0:10")"); $this->orm->save(); return $token; } /** * Авторизовать пользователя * @return void */ public function login(){ // Отметить пользователя, как авторизованного $_SESSION["loginid"] = $this->orm->id; // Обновить значение поля базы last_login $this->orm->set_expr("last_login", "NOW()"); $this->orm->save(); } /** * Уничтожить сессию и разлогинить пользователя * @return void */ public function logout(){ $_SESSION = array(); unset($_SESSION); } /** * Проверка, заходил ли пользователь * @return boolean */ public function loggedIn(){ return isset($this->orm->id) && $_SESSION["loginid"] == $this->orm->id; } /** * Проверка является ли пользователь администратором * @return boolean */ public function isAdmin(){ return $this->rank() == "administrator"; } /** * Найти тип пользователя, может быть либо administrator либо regular * @return string */ public function rank(){ if($this->orm->rank == 1){ return "administrator"; } return "regular"; } /** * Метод позволяющий получить приватную информацию пользователя в *качестве свойств объекта User * @param string $key Имя свойства, получающего доступ * @return mixed */ public function __get($key){ if(isset($this->orm->$key)){ return $this->orm->$key; } return null; } }

Токены генерируются с помощью SHA1 алгоритма и сохраняются в базе данных. Я использую функции времени MySQL, дабы задать 10-минутное ограничение актуальности токена.

Когда токен проходит процедуру валидации, мы напрямую говорим обработчику, что мы рассматриваем только токены, у которых ещё не истёк срок годности, хранимый в столбце token_validity.

Обратите внимание, что я использую волшебный метод __get библиотеки docs в конце файла, чтобы перехватить доступ к свойствам объекта User.

Благодаря этому становится возможным получить доступ к информации, хранящейся в базе, благодаря свойствам $user->email, $user->token и др. В следующем фрагменте кода рассмотрим для примера, как использовать эти классы.


Защищённая страница

Ещё один файл, хранящий полезный и необходимый функционал - это файл functions.php . Здесь есть несколько так называемых хелперов - функций-помощников, которые позволяют создавать более чистый и читабельный код в других файлах.

functions.php

Function send_email($from, $to, $subject, $message){ // Хелпер, отправляющий email $headers = "MIME-Version: 1.0" . "\r\n"; $headers .= "Content-type: text/plain; charset=utf-8" . "\r\n"; $headers .= "From: ".$from . "\r\n"; return mail($to, $subject, $message, $headers); } function get_page_url(){ // Определить URL PHP-файла $url = "http".(empty($_SERVER["HTTPS"])?"":"s")."://".$_SERVER["SERVER_NAME"]; if(isset($_SERVER["REQUEST_URI"]) && $_SERVER["REQUEST_URI"] != ""){ $url.= $_SERVER["REQUEST_URI"]; } else{ $url.= $_SERVER["PATH_INFO"]; } return $url; } function rate_limit($ip, $limit_hour = 20, $limit_10_min = 10){ // Количество попыток входа за последний час по этому IP-адресу $count_hour = ORM::for_table("reg_login_attempt") ->where("ip", sprintf("%u", ip2long($ip))) ->where_raw("ts > SUBTIME(NOW(),"1:00")") ->count(); // Количество попыток входа за последние 10 минут по этому IP-адресу $count_10_min = ORM::for_table("reg_login_attempt") ->where("ip", sprintf("%u", ip2long($ip))) ->where_raw("ts > SUBTIME(NOW(),"0:10")") ->count(); if($count_hour > $limit_hour || $count_10_min > $limit_10_min){ throw new Exception("Too many login attempts!"); } } function rate_limit_tick($ip, $email){ // Создать новую запись в таблице, считающей количество попыток входа $login_attempt = ORM::for_table("reg_login_attempt")->create(); $login_attempt->email = $email; $login_attempt->ip = sprintf("%u", ip2long($ip)); $login_attempt->save(); } function redirect($url){ header("Location: $url"); exit; }

Функции rate_limit и rate_limit_tick следят за количеством попыток авторизации за истёкший период времени с момента первой попытки. Попытка входа записывается в базе в столбец reg_login_attempt. Эти функции вызываются когда происходит обработка и отправка данных формы как вы можете видеть из следующего фрагмента кода.

Код ниже взят из файла index.php и он обрабатывает отправку формы. Он возвращает JSON-ответ, который, в свою очередь, обрабатывается jQuery в файле assets/js/script.js , который мы уже разбирали ранее.

index.php

Try{ if(!empty($_POST) && isset($_SERVER["HTTP_X_REQUESTED_WITH"])){ // Output a JSON header header("Content-type: application/json"); // Является ли этот email-адрес валидным if(!isset($_POST["email"]) || !filter_var($_POST["email"], FILTER_VALIDATE_EMAIL)){ throw new Exception("Please enter a valid email."); } // Проверка. Позволено ли пользователю авторизоваться, не превысил ли он количество допустимых подключений? (файл functions.php для большей информации) rate_limit($_SERVER["REMOTE_ADDR"]); // Записать эту попытку авторизации rate_limit_tick($_SERVER["REMOTE_ADDR"], $_POST["email"]); // Отправить письмо пользователю $message = ""; $email = $_POST["email"]; $subject = "Your Login Link"; if(!User::exists($email)){ $subject = "Thank You For Registering!"; $message = "Thank you for registering at our site!\n\n"; } // Попытка авторизовать или зарегистрировать пользователя $user = User::loginOrRegister($_POST["email"]); $message.= "You can login from this URL:\n"; $message.= get_page_url()."?tkn=".$user->generateToken()."\n\n"; $message.= "The link is going expire automatically after 10 minutes."; $result = send_email($fromEmail, $_POST["email"], $subject, $message); if(!$result){ throw new Exception("There was an error sending your email. Please try again."); } die(json_encode(array("message" => "Thank you! We\"ve sent a link to your inbox. Check your spam folder as well."))); } } catch(Exception $e){ die(json_encode(array("error"=>1, "message" => $e->getMessage()))); }

После успешной авторизации/регистрации код выше отправит пользователю ссылку для авторизации. Токен становится доступным, т.к. он передаётся в качестве переменной в генерируемой ссылке методом $_GET с маркером tkn

index.php

If(isset($_GET["tkn"])){ // Является ли этот токен валидным для авторизации? $user = User::findByToken($_GET["tkn"]); if($user){ // Да, является. Осуществить редирект на защищённую страницу $user->login(); redirect("protected.php"); } // Нет, токен не валидный. Осуществить редирект, на страницу с формой авторизации/регистрации redirect("index.php"); }

$user->login()

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

Похожим образом устроена и обработка функции на выход из системы.

index.php

If(isset($_GET["logout"])){ $user = new User(); if($user->loggedIn()){ $user->logout(); } redirect("index.php"); }

В конце кода, я снова поставил редирект на index.php, таким образом параметр ?logout=1 передаваемый посредством URL не требуется.

Наш файл index.php требует доп. защиты - мы не хотим, чтобы люди, которые когда-либо однажды авторизовались в системе опять видели форму регистрации. Для этих целей, мы используем метод $user->loggedIn() .

index.php

$user = new User(); if($user->loggedIn()){ redirect("protected.php"); }

Наконец-то, вот кусок кода, позволяющий защитить страницы вашего сайта и сделать её доступной только после авторизации.

protected.php

// Чтобы защитить каждую страницу на вашем сайте подключите к ней файл // main.php и создайте новый объект User. Вот как это просто! require_once "includes/main.php"; $user = new User(); if(!$user->loggedIn()){ redirect("index.php"); }

После этой проверки можете быть уверенными, что пользователь был успешно авторизован. Вы также можете получить доступ к хранимой информации в базе с помощью свойств объекта $user . Для вывода email-а пользователя и его статуса используйте этот код:

Echo "Your email: ".$user->email; echo "Your rank: ".$user->rank();

Метод rank() используется здесь потому что в базе обычно хранятся номера (0 для обычного пользователя, 1 для администратора) и нам нужно преобразовать эти данные в статусы, к которым они относятся, в чём нам и помогает этот метод.

Чтобы сделать из обычного пользователя администратора, просто отредактируйте пользовательскую запись через phpMyAdmin (или любую другую программу, позволяющую управлять базами данных). Статус администратора не даёт каких-либо привилегий, в данном примере на странице будет выведено, что вы администратор - и всё.

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

Мы закончили!

С этой невероятно супер квази простой формой мы закончили! Вы можете использовать её в ваших PHP-сайтах, это достаточно просто. Также вы можете модифицировать её под себя и сделать её такой, как вы хотите.

Материал подготовил Денис Малышок специально для сайта сайт

P.S. Хотите двигаться дальше в освоении PHP и ООП? Обратите внимание на премиум-уроки по различным аспектам сайтостроения, включая программирование на PHP, а также на бесплатный курс по созданию своей CMS-системы на PHP с нуля с использованием ООП:

Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!


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

В этой статье я постараюсь вытащить из танка всех тех, кто в нём сидит, и растолковать, что к чему (специально для тех, кто на бронепоезде – прим.ред.). Всё таки не зря некоторые хостеры отключают эту директиву. Итак…

О том, как это работает

В настройках PHP (файл php.ini) есть такая директива register_globals. Смысл её заключается в том, что если она включена (register_globals = on), то все переменные, переданные через GET и POST, будут зарегистрированы автоматически как глобальные. Что это значит?

К примеру, мы передаём сценарию index.php методом GET некоторое значение page: index.php?page=2. Переданное значение хранится в массиве GET и может быть использовано в сценарии как $_GET["page"]. Однако если у нас включена register_globals, то для переданного значения будет создана переменная $page, которая доступна в любой части сценария index.php.

Небольшой итог и дополнение. При включенном register_globals создаётся три копии переменной: в массиве GET, в массиве GLOBALS и просто сама переменная ($_GET["page"], $GLOBALS["page"], $page), в то время как при выключенном register_globals переданное значение может быть доступно только через массив GET ($_GET["page"]). Запомнили.

Опасность использования

Рассмотрим простой пример, чтобы понять, что нам светит (от 3 до 5 лет – прим.ред. ). Чтобы было проще, скажу сразу, что $login и $password – это переменные, переданные методом GET/POST.

Кратко о том, что делает сценарий:

    Строка 2. Делаем запрос к БД с целью вытащить настоящий пароль для введённого пользователем логина.

    Строка 3. Получаем этот пароль и присваиваем его переменной $real_pass.

    Строка 4. Сравниваем настоящий и введённый пароль и если они совпадут, то переменной $check будет присвоено true.

    Строки 5-8. Если $check равен true, то пишем, что авторизация проведена успешно и т.д.

Предложенный сценарий по определению самый дырявый на свете и сейчас я покажу Вам эти дыры. Условие – register_globals включен.

Допустим, передача идёт методом GET. Тогда url будет выглядить приблизительно следующим образом:
www.site.com/index.php?login =admin&password =qwerty
Понятное дело, что сразу же создаются глобальные переменные $login и $password. А теперь посмотрите сценарий. В нём есть переменная $check. А что если её передать через урл?

www.site.com/index.php?login =admin&password =qwerty&check =1
Тогда минуется проверка соотнесения паролей и пользователь получается сразу авторизованным (ведь Вы помните, что 1 – это true, а 0 – это false?). Тот же самый результат будет, если написать www. site. com/ index. php? check =1 . И даже если вы используете метод POST, всё равно все подобные махинации прокатят, так как при включённом register_globals не имеет значения какой у Вас метод - GET или POST.

Думаю, у кого-то возник вопрос, а откуда крякер узнает про переменную check, что она за всё отвечает? Если Вы никому не показывали сценарий, то он врядли это узнает. Однако не все используют свои сценарии, CMS и прочее, а пользуются тем, что есть в сети. В таких случаях крякер, к примеру, может изучить код CMS и делать атаки на сайты, созданные при его помощи.

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

Возьмём наш пример. Чтобы его защитить на случай, если register_globals включен, нужно после строки if ($ password==$ real_ pass) $ check = true; дописать следующее: else $ check = false; . В этом случае, даже если методом GET будет передана переменная check равная единице, то сценарий при неправильном пароле всё равно установит $check=false.

Да, ещё обращу Ваше внимание на то, что если выключить register_globals, то наш пример работать не будет. А чтобы он заработал, надо перед сценарием написать $login = $_POST["login"]; $password = $_POST["password"];

Подведём итоги…

и сделаем два основных вывода:

1) При включённом register_globals можно передавать различные переменные, значения для которых получать через GET или POST не рассчитывалось.

2) Не столько опасен сам 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

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

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

В большинстве случаев, применяют более упрощенную систему регистрации, которая написана на php в одном файле register.php .

Итак, мы немного отвлеклись, а сейчас рассмотрим более подробно файл регистрации.

Файл register.php

Для того, чтобы у вас это не отняло массу времени создадим систему, которая будет собирать пользователей, принимая от них минимальную контактную информацию. В данном случае все будем заносить в базу данных mysql. Для наибольшей скорости работы базы, будем создавать таблицу users в формате MyISAM и в кодировке utf-8.

Обратите внимание! Писать все скрипты нужно всегда в одной кодировке. Все файлы сайта и база данных MySql должны быть в единой кодировке. Самые распространенные кодировки UTF-8 и Windows-1251.

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

Как будет работать сам скрипт?

Мы хотим все упростить и получить быстрый результат. Поэтому будем получать от пользователей только логин, email и его пароль. А для защиты от спам-роботов, установим небольшую капчу. Иначе какой-нибудь мальчик из Лондона напишет небольшой робот-парсер, который заполнит всю базу липовыми пользователями за несколько минут, и будет радоваться своей гениальности и безнаказанности.

Вот сам скрипт. Все записано в одном файле register.php :

Пример скрипта регистрации register.php style.css" />

В данном случае скрипт обращается к самому себе. И является формой и обработчиком данных занесенных в форму. Обращаю ваше внимание, что файл сжат zip-архивом и содержит файл конфигурации config.php, дамп базы данных users, файл содержащий вспомогательные функции functions.php, файл стилей style.css и сам файл register.php. Также несколько файлов, которые отвечают за работу и генерацию символов капчи.


© 2024
maccase.ru - Android. Бренды. Железо. Новости