×
Закрытие
×

Дополнительные материалы бесплатно предоставляются только зарегистрированным пользователям.

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

Для тех кто не зарегистрирован, можно это сделать на вкладке Регистрация.

  • Создаем сайт для работы в Интернете

    1. Причины создания пошаговой инструкции по разработке самописного сайта
    2. Тема создаваемого сайта
    3. В чем будет заключаться монетизация
    4. Функционал
    5. Этапы создания
    6. Текущее состояние создаваемого сайта

    Здравствуйте уважаемый посетитель!

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

    Причем чтобы такой сайт был создан не в стандартном исполнении на основе какой-нибудь бесплатной СMS, а заточенный под себя, с возможностью обеспечить ему должную безопасность и реализовать все свои индивидуальные потребности.

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

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

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

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

Самописный сайт своими руками!

Текущее состояние создаваемого сайта

Здесь можно посмотреть текущее состояние самописного сайта, который создается для работы в Интернете в рамках цикла статей Как сделать сайт.

Где в дополнительных материалах можно бесплатно скачать исходные файлы сайта с таблицами MySQL.

Вы здесь: Главная → Сборник статей → Авторизация  → Привязка сессии к IP-адресу


Автор: / Дата:

Защищаем сессию используя IP-адрес

Здравствуйте уважаемый посетитель!

Сегодня рассмотрим еще один из возможных методов защиты сессий от хакерских атак, основанный на привязке к IP-адресу.

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

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

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

Содержание


  • Механизм привязки пользователя к IP-адресу
  • Дополняем систему авторизации проверкой по IP-адресу
  • Проверяем достоверность пользователя на соответствие IP-адреса
  • Исходные файлы сайта

Механизм привязки пользователя к IP-адресу


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

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

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

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

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

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

Дополняем систему авторизации проверкой по IP-адресу


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

Это можно сделать, как через имеющуюся на сайте форму регистрации на вкладке "Получить скидку", так и создав вручную новую запись в таблице MySQL "orders", предназначенную для хранения учетных записей пользователей.

А теперь приступим к написанию кода, который при успешной аутентификации пользователя при вводе данных учетной записи администратора (логин "admin"), сохранит в предназначенной для этого переменной сессии значение его IP-адреса (IP-адрес передается в сервер при запросе пользователя).

Ниже показан фрагмент такого кода (выделен светлым фоном), который вставлен в ранее созданный обработчик формы авторизации, размещенный в файле "auth.php".

  1. <?php

  2. require_once "start.php";

  3. if (!empty($_POST["auth-button"])) {

  4. //----Получение введенных в форму данных логина и пароля-------------

  5. if (isset($_POST["auth-login"])) $auth_login = $_POST["auth-login"];

  6. else

  7. $auth_login = $_POST["auth-login"];

  8. $auth_login = check_symbol($auth_login, "Логин", "1", "0");

  9. if (isset($_POST["auth-password"])) $auth_password = $_POST["auth-password"];

  10. else

  11. $auth_password = $_POST["auth-password"];

  12. $auth_password = check_symbol($auth_password, "Пароль", "1", "0");

  13. //----Извлечение хеш-строки из базы данных по логину из формы----

  14. $table = "orders";

  15. $column = "client-login";

  16. $value = $auth_login;

  17. $data_bd = getLine($table, $column, $value);

  18. $password_hash = $data_bd["password-hash"];

  19. echo nl2br("Извлеченный из базы данных хеш пароля: ".$password_hash. "\n\n");

  20. //----Формирование хеша пароля из формы-----

  21. $full_salt = substr($password_hash, 0, 29);

  22. $new_hash = crypt($auth_password, $full_salt.'$');

  23. //----Проверка на совпадение хеша пароля из формы с хеш-строкой из базы данных----

  24. if (!empty($password_hash) && $password_hash == $new_hash) { //При успешной аутентификации

  25. session_start(); //Создаем сессию

  26. $key1_hash = hash('sha256', microtime()); //Формируем одноразовый хеш-ключ

  27. setcookie ("key1", $key1_hash, time()+900, "/", $_SERVER['SERVER_NAME'], 0, 1); //Отправляем на сторону клиента cookie с созданным одноразовым ключем

  28. $_SESSION['key1'] = $key1_hash; //Записываем данные ключа в переменную сессии с именем "key1"

  29. $_SESSION['login'] = $auth_login; //Сохраняем в переменной сессии логин пользователя

  30. $_SESSION['agent'] = $_SESSION["HTTP_USER_AGENT"]; //Записываем данные по HTTP-заголовку User-Agent в переменную сессии

  31. if ($auth_login == 'admin') { //Если логин соответствует учетной записи администратора

  32. $addr = $_SERVER['REMOTE_ADDR']; //Получаем данные IP-адреса пользователя

  33. //$addr = '192.54.12.23'; //Вариант с фиксированным значением IP-адреса

  34. $reg_addr = preg_replace("/[^0-9]/", "", $addr); //Преобразуем адрес по регулярному выражению

  35. $addr_hash = hash('sha256', $reg_addr); //Формируем хеш адреса

  36. $_SESSION['addr'] = $addr_hash; //Записываем данные хеша адреса в переменную сессии

  37. }

  38. }

  39. else { //При неправильном вводе логина и/или пароля

  40. setcookie ("alert", "Неверные Логин и/или Пароль!", time()+60, "/", $_SERVER['SERVER_NAME']); //Передаем сообщение об ошибке

  41. }

  42. }

  43. //----Редирект на предыдущую страницу----

  44. header ("Location: ".$_SERVER["HTTP_REFERER"]);

  45. exit;

  46. ?>

Рис.1 Добавление в обработчик формы авторизации привязки к IP-адресу (файл auth.php)

Как видно, здесь в строке 31 условным оператором if проверяется, относятся ли введенные в форму авторизации данные к учетной записи администратора с логином "admin". И если да, то полученный из запроса IP-адрес (поз.32) сначала преобразуется по регулярному выражению (поз.34), а затем хешируется (поз.35) и записывается в предназначенную для такого случая переменную сессии $_SESSION['addr'] (поз.35).

При этом предусмотрен и вариант фиксированного значения. Для этого достаточно раскомментировать строку 33, задав нужный IP-адрес.

Привязку IP-адреса к сессии мы сделали. Теперь только осталось для заданной учетной записи выполнить проверку достоверности пользователя на его соответствие.

Соответствующий фрагмент кода, добавленный в файл "auth_check.php", показан на рис.2 (выделено светлым фоном).

  1. <?php

  2. $session_check = 0; //Устанавливаем запрещающий флаг авторизации

  3. if (isset($_COOKIE['alert'])) { //При наличии cookie 'alert' с сообщением об ошибке

  4. $GLOBALS['alert'] = $_COOKIE['alert']; //Для вывода в диалоговое окно браузера записываем в глобальную переменную $GLOBALS['alert'] ообщения об ошибке

  5. setcookie ("alert", $key1_hash, time()-60*60*24, "/", $_SERVER['SERVER_NAME'], 0, 1); //Удаляем cookie 'alert'

  6. }

  7. else {

  8. if (!empty($_COOKIE[ini_get('session.name')])) { //Если существует активная сессия

  9. session_start(); //Возобновляем сессию

  10. if (isset($_SESSION['key1'])) $session_key1 = $_SESSION['key1']; //Если переменная "key1" в сессии существует, то PHP-переменной $session_key1 присваивается ее значение

  11. else //Если нет

  12. $session_key1 = ""; //Переменной $session_key1 присваивается пустое значение

  13. if (isset($_COOKIE['key1'])) $cookie_key1 = $_COOKIE['key1']; //Если cookie "key1" существует, то PHP-переменной $cookie_key1 присваивается ее значение

  14. else //Если нет

  15. $cookie_key1 = ""; //Переменной $cookie_key1 присваивается пустое значение

  16. if ($session_key1 != "" && $cookie_key1 != "" && $session_key1 == $cookie_key1) { //Если одноразовый ключ сессии и cookie совпадают (подтверждение подлинности пользователя)

  17. $key1_hash = hash('sha256', microtime()); //Формируем одноразовый хеш-ключ

  18. setcookie ("key1", $key1_hash, time()+900, "/", $_SERVER['SERVER_NAME'], 0, 1); //Отправляем на сторону клиента cookie со вновь созданным одноразовым ключем

  19. $_SESSION["key1"] = $key1_hash; //Записываем данные ключа в переменную сессии с именем "key1"

  20. if (isset($_SESSION['agent'])) { //Проверяем, определена ли переменная сессии, содержащая данные HTTP-заголовка User-Agent

  21. $agent = $_SERVER['HTTP_USER_AGENT']; //Получаем данные об агенте из запроса

  22. if ($_SESSION['agent'] == $agent) { //Если данные об агенте совпадают с данными сессии

  23. $session_check = 1; //Устанавливаем разрешающий флаг авторизации

  24. }

  25. else { //Если данные об агенте не совпадают с данными сессии

  26. $error_auth = 'Подпись пользователя не подтверждена. В целях безопасности текущая сессия закрыта!\nДля получения прав доступа необходимо вновь авторизоваться через соответствующую форму.'; //Сообщение об ошибке

  27. sessionDelete($error_auth); //Вызываем функцию уничтожения сессии

  28. }

  29. }

  30. else { //Если переменная сессии, содержащая данные HTTP-заголовка User-Agent не определена

  31. $error_auth = 'Отсутствует подпись пользователя. В целях безопасности текущая сессия закрыта!\nДля получения прав доступа необходимо вновь авторизоваться через соответствующую форму.'; //Текст сообщения об ошибке

  32. sessionDelete($error_auth); //Вызываем функцию уничтожения сессии

  33. }

  34. if (isset($_SESSION['addr'])) { //Проверяем, определена ли переменная сессии с данными IP-адреса пользователя

  35. $addr = $_SERVER['REMOTE_ADDR']; //Получаем данные IP-адреса пользователя

  36. //$addr = '192.54.12.23'; //Вариант с фиксированным значением IP-адреса

  37. $reg_addr = preg_replace("/[^0-9]/", "", $addr); //Преобразуем адрес по регулярному выражению

  38. $addr_hash = hash('sha256', $reg_addr); //Формируем хеш адреса

  39. if ($_SESSION['addr'] != $addr_hash) { //Если данные хеша IP-адреса не совпадают с данными сессии

  40. $session_check = 0; //Устанавливаем запрещающий флаг авторизации

  41. $error_auth = 'Попытка несанкционированного входа в систему. В целях безопасности текущая сессия закрыта!\nДля получения прав доступа необходимо вновь авторизоваться через соответствующую форму.'; //Сообщение об ошибке

  42. sessionDelete($error_auth); //Вызываем функцию уничтожения сессии

  43. }

  44. }

  45. }

  46. else { //При не подтверждении подлинности пользователя

  47. $error_auth = 'Достоверность пользователя не подтверждена. В целях безопасности текущая сессия закрыта!\nДля получения прав доступа необходимо вновь авторизоваться через соответствующую форму.'; //Текст сообщения об ошибке

  48. sessionDelete($error_auth); //Вызываем функцию уничтожения сессии

  49. }

  50. }

  51. }

  52. ?>

Рис.2 Добавление проверки на соответствие IP-адреса (файл auth_check.php)

Здесь в строке 34 проверяется, определена ли в сессии переменная $_SESSION['addr'] с данными IP-адреса пользователя. И если да, то далее производятся аналогичные преобразования извлеченного из запроса IP-адреса: сначала по регулярному выражению (поз.37), а затем по формированию хеша (поз.38). Также предусмотрен и вариант фиксированного значения. Для этого также, как и в предыдущем случае, достаточно раскомментировать строку 36, задав нужный IP-адрес.

После чего полученное значение сравнивается с данными переменной $_SESSION['addr'] (поз.39). И если они не совпадают, то устанавливается запрещающий флаг авторизации (поз.40). А вместе с этим с помощью пользовательской функции sessionDelete() (поз.42) сессия уничтожается вместе с выводом оповещающего об этом сообщения (поз.41)

Таким образом мы сформировали необходимые элементы системы авторизации для проверки заданной учетной записи на соответствие IP-адреса. И теперь посмотрим, как это работает.

Проверяем достоверность пользователя на соответствие IP-адреса


Для более объективной оценки проведем данную проверку на сайте, размещенном не на локальном веб-сервере, а на хостинге с реальными IP-адресами.

Проверку проведем в два этапа: сначала выполним авторизацию с логином "admin" при подключенном компьютере к сети Интернет через статический адрес. А затем, не выходя из сессии, заменим соединение к Интернет на другое, с отличным IP-адресом. После чего вновь попробуем авторизоваться, обновив, или перейдя на какую-либо другую страницу сайта. И посмотрим, удастся ли нам это.

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

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

  1. . . .

  2. <body>

  3. <?php

  4. echo nl2br("\nХеш IP-адреса, хранящиеся в переменной сессии: " . "\n" . $_SESSION['addr'] ."\n\n"."Хеш IP-адреса, полученного из запроса браузера: "."\n".$addr_hash."\n\n");

  5. if (!empty($GLOBALSE['alert'])) { //При наличии сообщения об ошибке

  6. require_once"alert.php"; //Подключаем файл alert.php для вывода сообщения на экран браузера

  7. $GLOBALSE['alert'] = ""; //Очищаем сообщение

  8. }

  9. ?>

  10. <div "wrapper">

  11. . . .

Рис.3 Вывод на страницу данных текущих значениях хеша IP-адреса (добавлено в файл index.php)

И так, приступим. Сначала авторизуемся под учетной записью администратора с логином admin с компьютера, подключенного к Интернет со статическим адресом (для авторизации будем использовать ранее созданный пароль 2Vm3Nrt1).

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

Одинаковый хеш IP-адреса в переменной сессии и в запросе пользователя

Рис.4 Одинаковый хеш IP-адреса в переменной сессии и в запросе пользователя

А теперь заменим соединение компьютера к Интернет, и соответственно, изменим IP-адрес. После чего не закрывая сессию попробуем вновь авторизоваться обновив или перейдя на другую страницу сайта. Тем самым проверив, обнаружит ли система авторизации подмену адреса для данной учетной записи.

Уничтожение сессии при обнаружении несоответствия IP-адреса

Рис.5 Уничтожение сессии и вывод сообщения при обнаружении несоответствия IP-адреса

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

Если же закрыть это информационное сообщение, то можно будет увидеть, что в этом случае полученный хеш IP-адреса не соответствует первоначальному адресу, отмеченному на рис.3, который ранее использовался при авторизации.

Не соответствие хеша IP-адреса первоначальному адресу

Рис.6 Не соответствие хеша IP-адреса первоначальному адресу

Таким образом мы дополнили систему авторизации дополнительной проверкой достоверности пользователя на соответствие IP-адреса. И убедились в эффективности ее использования в целях повышения уровня безопасности при работе с сессиями.

При этом следует обратить внимание, что в данном случае эта проверка применена только для конкретной учетной записи администратора с логином "admin". Для всех остальных пользователей элементы данной проверки не задействуются. И для них авторизация может происходить при любом IP-адресе.

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


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

Исходные файлы сайта


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

  • Файлы каталога www
  • Таблицы базы данных MySQL

При этом, временно сформированные в данной статье PHP-скрипты, размещенные в файле "main.php" папки "articles" корневого каталога, закомментированы. Для проверки рассмотренных здесь примеров, следует раскомментировать соответствующие фрагменты кода.

Дополнительные материалы бесплатно предоставляются только зарегистрированным пользователям.

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

Для тех кто не зарегистрирован, можно это сделать на вкладке Регистрация.

С уважением, Николай Гришин


Комментарии


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

Буду Вам за это очень признателен!

comments powered by HyperComments