Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ещё раз о сессиях, :dash1  
V
    Опции темы
HackMan
  Дата 1.7.2007, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Юзверь-программист
**


Профиль
Группа: Участник
Сообщений: 391
Регистрация: 18.6.2005
Где: .ua

Репутация: 8
Всего: 9



Есть скрипт, для авторизации администратора
login.php
Код

<?php
  session_start();
  session_destroy();
 
  unset($session); 
  $status = "Введите логин и пароль администратора<br>";

  if (isset($submit))
    {
      if (($UserName == "login")&&($UserPassword=="password"))
        {
          session_start(); 

          session_register("session"); 

          $session['start'] = time();
          $session['id'] = md5(get_ip());

          header("Location: index.php");
          exit;
        }
       else
        {
          $status = '<font color="red">Неверный логин или пароль!</font><br>';
        } 
    }    
?>

<?php
function get_ip()
{
  if ($ip = getenv("HTTP_CLIENT_IP"))
    return $ip;
 
  if ($ip = getenv("HTTP_X_FORWARDED_FOR"))
    {
      if ($ip == '' || $ip == "unknown")
        $ip = getenv("REMOTE_ADDR");
      return $ip;
    }

  if ($ip = getenv("REMOTE_ADDR"))
    return $ip;

?>

<html>
<head>
  <title>Авторизация</title>
  <meta http-equiv="content-type" content="text/html; charset=windows-1251">
  <meta http-equiv="content-language" content="ru">    
</head>

<style type="text/css" media="all">
  @import "style.css";
</style>

<body>

<table width="100%" height="100%">
  <tr>
    <td align="center">
      <form action="" method="POST" style="margin:0">
        <table>
          <tr>
            <td align="center">
              <?="<b>".$status."</b>"?><br>
         </td>
          </tr>

          <tr>
            <td>
              <table align="center">
                <tr>
                  <td align="right">Логин:</td>
                  <td><input class="edit" type="text" name="UserName"></td>
                </tr>

                <tr>
                  <td align="right">Пароль:</td>
                  <td><input class="edit" type="password" name="UserPassword"></td>
                </tr>

                <tr>
                  <td></td>
                  <td id="nb"><input class="button" type="submit" name="submit" value="Войти" style="cursor: hand"></td>
                </tr>
              </table>
            </td>
          </tr>
        </table>
      </form>
    </td>
  </tr>      
</table>

</body>
</html>

примечания: 
  • при заходе на эту страницу сессия уничтожается (происходит logout).
  • пользователь только один - новых регистрировать нельзя

Есть скрипт, для проверки валидности сессии, и для её продлевания
check.php
Код

<?php   
  require "globals.php";
  
  session_start(); 
  
  if (!isset($session)) 
    {
      header("Location: login.php");
      exit;
    }
   else 
    {
      if (time()-$session['start'] > $session_timeout || ($session['id'] != md5(get_ip())))
        {
          session_destroy();
          header("Location: login.php");
          exit;
        } 
        
      $session_lastactivity = time()-$session['start'];
      $session_id = $session['id'];

      $session['start'] = time();
    }
?>

<?php
function get_ip()
{
  if ($ip = getenv("HTTP_CLIENT_IP"))
    return $ip;
 
  if ($ip = getenv("HTTP_X_FORWARDED_FOR"))
    {
      if ($ip == '' || $ip == "unknown")
        $ip = getenv("REMOTE_ADDR");
      return $ip;
    }

  if ($ip = getenv("REMOTE_ADDR"))
    return $ip;

?>

примечания: 
  • globals.php состоит всего из одной строчки, в которой инициализируется время валидности сессии ($session_timeout = 900;)

И есть много страниц самой админки. Посути, страница одна, но от различных значений переменных инклудятся разные скрипты. 
Вопрос такой: нужно ли мне вставлять require "check.php" в каждый скрипт, который потом инклудится в главную страницу, или можно ограничеться только одной главной страницей?


--------------------

Завтра - это самый загруженный день недели smile

user posted image

user posted image
PM MAIL ICQ   Вверх
Golda
Дата 2.7.2007, 00:06 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 26.3.2007
Где: Ариель, Израиль

Репутация: 20
Всего: 42



Если есть один скрипт - точка входа, достаточно подключать в нем. 

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

Что если я, не проходя логина, вызову основную страницу следующим образом:

Код

index.php?session[start]=1111111111&session[id] =5


Переменной $session в сессии нет. Не зарегистрирована. Но вы же и не проверяете, что она зарегистрирована. Ваш скрипт спокойно "скушает" ее из GET. Никакой проверки на правдоподобность $session['id'] тоже нет. Хакеру остается только подобрать подходящий таймстемп.

Советую:
*) отключить register_globals
*) различать, откуда приходят переменные ($_GET, $_POST, $_COOKIE, $_SESSION)
*) возможно, добавить проверку на правдоподобность $session['id']

Ну и не стоит одну и ту же функцию get_ip() определять в двух файлах. Подключайте ее из какого-то одного

Добавлено через 10 минут и 58 секунд
Сами логин и пароль тоже безопаснее хранить не зашитыми hardcoded в скрипт, а где-нибудь в конфигурации за пределами DOCUMENT_ROOT или защищенной .htaccess 

Это сообщение отредактировал(а) Golda - 2.7.2007, 00:08


--------------------
"For every problem, there exists a simple and elegant solution which is absolutely wrong." -- J. Wagoner, U.C.B. Mathematics
PM MAIL   Вверх
HackMan
Дата 2.7.2007, 01:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Юзверь-программист
**


Профиль
Группа: Участник
Сообщений: 391
Регистрация: 18.6.2005
Где: .ua

Репутация: 8
Всего: 9



Цитата(Golda @  2.7.2007,  00:06 Найти цитируемый пост)
Что если я, не проходя логина, вызову основную страницу следующим образом:

Выделить всёБез подсветки
1:
    
index.php?session[start]=1111111111&session[id] =5


Ну как же... у меня в каждой странице стоит вначале require "check.php";
так что проверка на session[id] всё же есть  smile 

index.html
Код

<?php  
  require "check.php";
?>

<html>
<head>
  <title>Администратор</title>
  <meta http-equiv="content-type" content="text/html; charset=windows-1251">
  <meta http-equiv="content-language" content="ru">    
</head>

<style type="text/css" media="all">
  @import "style.css";
</style>

<body>

<?php
  echo '<b>Последняя активность на сайте была '.$session_lastactivity.' секунд назад</b><br>';
  echo '<b>ID сессии:</b> '.$session_id.'<br>';
  echo '<b>Ваш IP адрес:</b> '.get_ip().'<br>';
  echo '<a href="login.php">Выход</a><br>';
  echo '<a href="admin.php">Администрирование</a><br>';
?>

</body>
</html>


так что хакеру придётся ещё вычислить md5 от собственного ip  smile 


спасибо за то что указали на дырку. делалось ночию, недоглядел  smile 

Цитата(Golda @  2.7.2007,  00:06 Найти цитируемый пост)
Если есть один скрипт - точка входа, достаточно подключать в нем. 

а как же другим страницам узнать, что администратор авторизировался?

Цитата(Golda @  2.7.2007,  00:06 Найти цитируемый пост)
Сами логин и пароль тоже безопаснее хранить не зашитыми hardcoded в скрипт, а где-нибудь в конфигурации за пределами DOCUMENT_ROOT или защищенной .htaccess 

это всё будет. сейчас главное сделать авторизацию  smile 

Это сообщение отредактировал(а) HackMan - 2.7.2007, 01:13


--------------------

Завтра - это самый загруженный день недели smile

user posted image

user posted image
PM MAIL ICQ   Вверх
Golda
Дата 2.7.2007, 01:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 26.3.2007
Где: Ариель, Израиль

Репутация: 20
Всего: 42



Цитата(HackMan @  2.7.2007,  01:12 Найти цитируемый пост)
Ну как же... у меня в каждой странице стоит вначале require "check.php";


Ну и что? Ну, попал он в check.php. Там скрипт попытает поднять сессию (session_start()). Переменная $session из сессионных данных не появилась. Но зато она существует благодаря GET-запросу. Поэтому проверка isset($session) будет пройдена. Вторая проверка - тоже не невыполнимая задача.

Цитата(HackMan @  2.7.2007,  01:12 Найти цитируемый пост)
так что проверка на session[id] всё же есть  smile


Да, проверка на session[id] есть. Я проглядела. Но, поверьте, хакеру не сложно будет узнать как свой IP, так и md5()от него. Даже подбор значения по известному хешу md5() часто возможен. А уж прямое преобразование точно проблемы не представляет, если стало ясно, какие данные пользователя искать.

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

Цитата(HackMan @  2.7.2007,  01:12 Найти цитируемый пост)
спасибо за то что указали на дырку. делалось ночию, недоглядел  smile 


Со всеми бывает  smile 

Цитата(HackMan @  2.7.2007,  01:12 Найти цитируемый пост)
Цитата(Golda @  2.7.2007,  00:06 Найти цитируемый пост)
Если есть один скрипт - точка входа, достаточно подключать в нем. 

а как же другим страницам узнать, что администратор авторизировался?


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

Код

header("Location: login.php");
exit;


перенаправят пользователя на login.php и завершат работу скрипта. А если уж дальнейшие модули загрузились, значит с авторизацией все в порядке. Остальным модулям ничего и проверять не нужно


--------------------
"For every problem, there exists a simple and elegant solution which is absolutely wrong." -- J. Wagoner, U.C.B. Mathematics
PM MAIL   Вверх
HackMan
Дата 2.7.2007, 02:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Юзверь-программист
**


Профиль
Группа: Участник
Сообщений: 391
Регистрация: 18.6.2005
Где: .ua

Репутация: 8
Всего: 9



Я строчку unset($session) запихнул не в тот скрипт  smile 
Его надо было в check.php. Тогда переменная $session просто обнуляется, и неважно, чем она была раннее передана. А дальше открывается сессия, и если переменная $session не подгругилась из неё, то и проверка isset($session) не будет выполнена.

Но как я понимаю, мне придётся в каждый скрипт прописывать require "check.php" для того чтобы проверить, создана ли сессия. Иначе пользователь просто введёт в строке адреса путь к нужному скрипту, и смысла от авторизации никакой  smile. Или я не прав?


--------------------

Завтра - это самый загруженный день недели smile

user posted image

user posted image
PM MAIL ICQ   Вверх
Golda
Дата 2.7.2007, 07:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 26.3.2007
Где: Ариель, Израиль

Репутация: 20
Всего: 42



Цитата(HackMan @  2.7.2007,  02:24 Найти цитируемый пост)
Я строчку unset($session) запихнул не в тот скрипт  smile 


Да, это решает проблему. Я бы все же отключила register_globals, чтобы не нарваться в дальнейшем на подобные, но... вольному воля  smile 

Цитата(HackMan @  2.7.2007,  02:24 Найти цитируемый пост)
Но как я понимаю, мне придётся в каждый скрипт прописывать require "check.php" для того чтобы проверить, создана ли сессия. Иначе пользователь просто введёт в строке адреса путь к нужному скрипту, и смысла от авторизации никакой  smile. Или я не прав?


Можно так. Но мне больше нравятся и другие вариант: работы меньше, да и расчет идет не на потенциально уязвимый скрипт авторизации (я в данном случае не именно Ваш имею в виду, любой), а на средства сервера с гораздо более простой, прямолинейной, а значит и надежной логикой. К тому же такие лишние запросы обрабатываться будут быстрее, не доходя до PHP вообще
  • можно дать подключаяемым модулям специфическое расширение (наример, .inc.php) и запретить в .htaccess доступ к файлам с таким расширением

    Код

    <files "*.inc.php"> 
       Deny from all 
    </files> 

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


Это сообщение отредактировал(а) Golda - 2.7.2007, 07:47


--------------------
"For every problem, there exists a simple and elegant solution which is absolutely wrong." -- J. Wagoner, U.C.B. Mathematics
PM MAIL   Вверх
HackMan
Дата 2.7.2007, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Юзверь-программист
**


Профиль
Группа: Участник
Сообщений: 391
Регистрация: 18.6.2005
Где: .ua

Репутация: 8
Всего: 9



гениально!  smile 
вобщем, надо через .htaccess запретить доступ к подключаемым скриптам, а в основных писать require "check.php"  smile 

Большое спасибо!

P.S. Жалко, нехватает несколько постов, что бы мог плюсики выставлять...


--------------------

Завтра - это самый загруженный день недели smile

user posted image

user posted image
PM MAIL ICQ   Вверх
ilyalyu
Дата 2.7.2007, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 25.10.2006

Репутация: нет
Всего: нет



помнится, в manual-e по PHP учат вместо unset($_SESSION) использовать присваивание: $_SESSION = Array();
PM MAIL   Вверх
HackMan
Дата 3.7.2007, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Юзверь-программист
**


Профиль
Группа: Участник
Сообщений: 391
Регистрация: 18.6.2005
Где: .ua

Репутация: 8
Всего: 9



А где вы видели, что бы я использовал unset($_SESSION)?


--------------------

Завтра - это самый загруженный день недели smile

user posted image

user posted image
PM MAIL ICQ   Вверх
ilyalyu
Дата 10.7.2007, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 25.10.2006

Репутация: нет
Всего: нет



Цитата(HackMan @ 2.7.2007,  02:24)
Я строчку unset($session) запихнул не в тот скрипт  smile 

Вот. Извини, не заметил отсутствия прочерка smile

Это сообщение отредактировал(а) ilyalyu - 10.7.2007, 23:55
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1022 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.