Про безопасность: Привязка сессии к IP и(или) UserAgent
Недавно,
1. Модернизация кода:
1.1. Ищем файл
classes/actions/ActionLogin.class.php
В функцию EventAjaxLogin(), после строки (85 строка):
$this->User_Authorization($oUser,$bRemember);
Добавляем следующие строки
// * Если нужно то запоминаем IP в сессию if(getRequest('remember_ip', false)) { $this->Session_Set('user_ip', $_SERVER['REMOTE_ADDR']); $this->Session_SetCookie('check_ip', 1, Config::Get('sys.cookie.time')); } // * Если нужно то запоминаем браузер в сессию if(getRequest('remember_browser', false)) { $this->Session_Set('user_browser', md5($_SERVER['HTTP_USER_AGENT'])); $this->Session_SetCookie('check_useragent', 1, Config::Get('sys.cookie.time')); }
Сохраняем.
1.2. Ищем файл
classes/modules/user/User.class
В функцию Init(), после строки (71 строка):
if ($this->oSession=$oUser->getSession()) {
Добавляем следующие строки
#Проверка IP адреса if($this->Session_Get('user_ip')){ #Проверяем совпадает ли IP в сессии и IP клиента if($this->Session_Get('user_ip') != $_SERVER['REMOTE_ADDR']) { $this->Logout(); return; } } #Проверка браузера if($this->Session_Get('user_browser')){ #Проверяем совпадает ли хеш агента браузер в сессии и хеш агента браузера клиента if($this->Session_Get('user_browser') != md5($_SERVER['HTTP_USER_AGENT'])) { $this->Logout(); return; } }
В функцию Authorization(), после строк (после 526 строки):
if ($bRemember) { setcookie('key',$sKey,time()+Config::Get('sys.cookie.time'),Config::Get('sys.cookie.path'),Config::Get('sys.cookie.host'),false,true); }
Добавляем следующие строки
/** * Если нужно то запоминаем IP в сессию и продляем жизнт куке */ if($this->Session_GetCookie('check_ip')) { $this->Session_Set('user_ip', $_SERVER['REMOTE_ADDR']); $this->Session_SetCookie('check_ip', 1, Config::Get('sys.cookie.time')); } /** * Если нужно то запоминаем агент браузера в сессию и продляем жизнт куке */ if($this->Session_GetCookie('check_useragent')) { $this->Session_Set('user_browser', md5($_SERVER['HTTP_USER_AGENT'])); $this->Session_SetCookie('check_useragent', 1, Config::Get('sys.cookie.time')); }
В функцию Logout(), после строки (571 строка):
$this->Session_Drop('user_id');
Добавляем следующие строки
// * Удаляем IP из сессии $this->Session_Drop('user_ip'); // * Удаляем куки флага проверки IP адреса $this->Session_DelCookie('check_ip'); // * Удаляем хэш агента браузера из сессии $this->Session_Drop('user_browser'); // * Удаляем куки флага проверки хэша агента браузера $this->Session_DelCookie('check_useragent');
Сохраняем.
2. Модернизация шаблона (на примере дефолтного шаблона synio):
2.1. Ищем файл
templates/skin/synio/window_login.tpl
В функцию EventAjaxLogin(), после строки (85 строка):
$this->User_Authorization($oUser,$bRemember);
После 40 строки:
<label class="remember-label"><input type="checkbox" name="remember" class="input-checkbox" checked /> {$aLang.user_login_remember}</label>
Добавляем следующие строки
<label class="remember-label"><input type="checkbox" name="remember_ip" class="input-checkbox" /> {$aLang.user_login_remember_ip}</label> <label class="remember-label"><input type="checkbox" name="remember_browser" class="input-checkbox" /> {$aLang.user_login_remember_browser}</label>
Сохраняем.
2.2. Ищем файл
templates/skin/synio/actions/ActionLogin/index.tpl
После 18 строки:
<p><label><input type="checkbox" name="remember" checked class="input-checkbox" /> {$aLang.user_login_remember}</label></p>
Добавляем следующие строки
<p><label><input type="checkbox" name="remember_ip" class="input-checkbox" /> {$aLang.user_login_remember_ip}</label></p> <p><label><input type="checkbox" name="remember_browser" class="input-checkbox" /> {$aLang.user_login_remember_browser}</label></p>
Сохраняем.
3. Добавляем языки (на примере Русского языка)
3.1. Ищем файл
templates/language/russian.php
После 23 строки
return array(
Добавляем следующие строки
'user_login_remember_ip' => 'Привязать сессию к IP', 'user_login_remember_browser' => 'Привязать сессию к браузеру',
Сохраняем и пользуемся.
22 комментария
Вот с этого места бы по подробней, т.е. присутствуют в последнем релизе (1.0.3), если правильно понял. Желательно с описанием к Администрации, и последующей публикацией найденных XSS.
gowebpro.github.io/lsp-securesession/
Тестируем, баг-репортим
Теперь внимание, UserAgent — включает номер версии, который будет меняться после каждого обновления браузера, что так же будет приводить к сбросу.
Испортите user experience. Лучше реально выявлять и закрывать XSS.
Исправим
галочкой «запомнить меня» создается кука, которая дропается функцией Logout модуля User.
Какбэ функционал добавляет опции, а не жесткие правила привязки к IP и UserAgent.
Писать что-либо в сессию и проверять бессмысленно, сессия снова дропнется. Этот прием защищает только если злоумышленник украдет вашу сессионную куку и нарисуется в итервале времени жизни сессии на сервере. Если же он украл персистентную куку (ключ сессии) то он спокойно зайдет, переоткрыв новую сессию. На другой чаше весов испорченный пользовательский опыт.
Надо делать как я сказал выше — писать IP в таблицу сессий, закрывать старые и открывать новые, принудительно закрывать при смене IP, проверять помимо прочего не закрылась ли сессия.
Элементарный способ проверки смены IP.
Осталось разобраться с принципом хранения чекбоксов.
В куках или сессии хранить метку о том, что это нужно чекать, бессмысленно. Придется добавить поле в табличку сессий, другого варианта не вижу