Веб-приложение - захват сеанса с использованием файлов cookie [дубликат]

Используйте sprintf :

sprintf('%08d', 1234567);

В качестве альтернативы вы также можете использовать str_pad :

str_pad($value, 8, '0', STR_PAD_LEFT);

112
задан Chris 23 August 2008 в 16:33
поделиться

12 ответов

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

Единственным реальным решением является HTTPS. Если вы не хотите использовать SSL на своем сайте (возможно, у вас есть проблемы с производительностью), вы можете уйти с помощью только SSL, защищающего чувствительные области. Для этого сначала убедитесь, что ваша страница входа в систему - HTTPS. Когда пользователь входит в систему, установите безопасный файл cookie (то есть браузер будет передавать его только по ссылке SSL) в дополнение к обычному cookie сеанса. Затем, когда пользователь посещает одну из ваших «чувствительных» областей, перенаправляет их на HTTPS и проверяет наличие этого безопасного файла cookie.

EDIT: Этот ответ был первоначально написан в 2008 году. Сейчас 2016 год, и нет оснований не иметь SSL на всем сайте. Нет больше текстового HTTP!

111
ответ дан Josh Hinman 24 August 2018 в 22:53
поделиться
  • 1
    HTTPS предотвратит только обнюхивание. Но если у вас XSS, или идентификаторы сеансов могут быть легко угаданы, или вы уязвимы для фиксации сеанса, или ваше хранилище идентификаторов сеансов слабо (SQL-инъекция?), SSL вообще не будет улучшен. – Calimo 22 January 2012 в 20:15
  • 2
    @Josh Если злоумышленник имеет физический доступ к машине, они все равно могут посмотреть на файловую систему, чтобы получить действительный файл cookie сеанса и использовать его для захвата сеанса? – Pacerier 14 June 2012 в 02:57
  • 3
    Если у злонамеренного пользователя есть физический доступ к файловой системе, им не нужно захватывать сеанс. – Josh Hinman 15 June 2012 в 07:28
  • 4
    @Josh. Неверно, иногда пользователь имеет ограниченный физический доступ к файловой системе. Представьте, что ноутбук остался разблокированным коллегой, мчащейся в туалет, теперь мне нужно только пойти на этот ноутбук, установить плагин EditThisCookie, захватить его файлы cookie на сайте plus.google.com, используя функцию экспорта EditThisCookie , и теперь у меня есть его счет . Время: 18 секунд. – Pacerier 13 October 2012 в 21:47
  • 5
    Я уверен, что у google будет встроенная функция безопасности, так как это, очевидно, первое, что вы могли бы подумать, когда говорили о захвате сеанса – xorinzor 4 December 2012 в 19:10

Защита от:

$ip=$_SERVER['REMOTE_ADDER'];
$_SESSEION['ip']=$ip;
-13
ответ дан Apurv 24 August 2018 в 22:53
поделиться

Попробуйте протокол Secure Cookie, описанный в этой бумаге Лю, Ковача, Хуанга и Гауды:

Как указано в документе:

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

Что касается простоты развертывания:

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

Вкратце: это безопасный, легкий, работает для меня просто отлично.

9
ответ дан Crowie 24 August 2018 в 22:53
поделиться
  • 1
    Ваша ссылка - это спецификация протокола - есть ли у вас ссылка на реализацию? Это было бы здорово - спасибо. – Adam 7 August 2010 в 18:17

Рассматривали ли вы чтение книги по безопасности PHP? Очень рекомендую

У меня был большой успех со следующим методом для сайтов, не сертифицированных SSL.

  1. Отключить несколько сеансов в одной учетной записи, t проверяя это только по IP-адресу. Скорее проверьте токен, созданный при входе в систему, который хранится в сеансе пользователя в базе данных, а также IP-адрес, HTTP_USER_AGENT и т. Д.
  2. Использование гиперссылок, основанных на отношениях. Создает ссылку (например, http: //example.com/secure.php?token=2349df98sdf98a9asdf8fas98df8) Ссылка добавляется с произвольной соляной строкой MD5 с произвольным размером x-BYTE (предпочтительный размер), при перенаправлении страницы случайно сгенерированный токен соответствует запрошенной странице. После перезагрузки выполняется несколько проверок. Исходный IP-адрес HTTP_USER_AGENT Session Token вы получаете.
  3. Короткое время ожидания проверки подлинности сеанса. как указано выше, cookie, содержащий защищенную строку, которая является одной из прямых ссылок на достоверность сеансов, является хорошей идеей. Завершить его каждые x минут, переиздавая этот токен и повторно синхронизируя сеанс с новыми данными. Если какие-либо неправильные совпадения в данных, либо выведите пользователя из системы, либо повторите аутентификацию их сеанса.

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

21
ответ дан Cœur 24 August 2018 в 22:53
поделиться
  • 1
    Есть ли какие-нибудь книги, которые вы бы порекомендовали? – Rikki 10 June 2012 в 23:49
  • 2
    Особенно учитывая, что ОП не указал ничего о PHP конкретно, я бы сказал, что лучше смотреть только на общую книгу безопасности (тем более, что безопасность между разными языками отличается только деталями реализации, но концепции остаются прежними). – matts1 17 March 2014 в 11:07
  • 3
    в 2017 году даже facebook / gmail и т. д. допускают несколько сеансов под одной учетной записью (особенно с мобильными устройствами), если вы не ненавидите своих пользователей, # 1 немного устарел. – cowbert 24 January 2018 в 05:32

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

1
ответ дан davej 24 August 2018 в 22:53
поделиться
  • 1
    Но как вы хотите сохранить эту соль на стороне клиента, чтобы никто не мог ее украсть? – Dcortez 24 June 2016 в 05:40

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

  • Проверки IP и / или X-FORWARDED-FOR. Эти работы и довольно безопасны ... но представьте себе боль пользователей. Они приходят в офис с WiFi, получают новый IP-адрес и теряют сессию. Необходимо снова войти в систему.
  • Проверяет пользовательский агент. То же, что и выше, новая версия браузера отсутствует, и вы теряете сеанс. Кроме того, это действительно легко «взломать». Трудно хакерам посылать поддельные строки UA.
  • localStorage token. При входе в систему создайте токен, храните его в хранилище браузера и храните его в зашифрованном файле cookie (зашифрованном на стороне сервера). Это не имеет побочных эффектов для пользователя (localStorage сохраняется через обновления браузера). Это не так безопасно, поскольку это просто безопасность через неясность. Кроме того, вы могли бы добавить некоторую логику (шифрование / дешифрование) в JS, чтобы еще больше затушевать ее.
  • Переиздание файлов cookie. Вероятно, это правильный способ сделать это. Хитрость заключается только в том, чтобы позволить одному клиенту одновременно использовать файл cookie. Таким образом, у активного пользователя будет выгружаться cookie каждый час или меньше. Старый cookie недействителен, если новый. Хаки по-прежнему возможны, но гораздо сложнее сделать - либо хакер, либо действительный пользователь получит доступ к отказу.
3
ответ дан Hatch 24 August 2018 в 22:53
поделиться

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

Проверка заголовков реферирования также может быть опцией, но это более легко подделать.

0
ответ дан Julio César 24 August 2018 в 22:53
поделиться
  • 1
    Нет, вы не можете использовать исходный IP-адрес, поскольку он может измениться - либо через динамические IP-адреса, либо изменяться при временном отключении пользователя, либо через (неявное или явное) использование прокси-фермы. Кроме того, угонщики сеансов, исходящие от одного и того же интернет-провайдера, могут использовать один и тот же прокси и amp; IP как законный пользователь ... – Olaf Kock 3 October 2008 в 16:35
  • 2
    У PHP-Nuke есть хорошая страница об их сеансовом подходе, и они подробно рассказывают о том, как привязать ее к IP-адресу не работает со всеми интернет-провайдерами phpnuke.org/… – Sembiance 29 June 2010 в 20:02
  • 3
    Изменение Ip очень распространено среди мобильных интернет-провайдеров. С Vodafone мой IP изменяется с КАЖДОМ запросом. – Blaise 27 March 2011 в 19:02
  • 4
    В некоторой степени старый пост, но для этого. IP-адреса называются плохой идеей. Как упоминалось, мобильные пользователи склонны перемещаться по IP-адресам. Некоторые из провайдеров в прошлом также имели роуминговые IP-адреса (такие как AOL), однако этот подход становится все более популярным сейчас с нехваткой IPv4 IP. Такие провайдеры включают в себя Plus net и BT – Peter 26 March 2013 в 22:33

AFAIK объект сеанса недоступен на клиенте, поскольку он хранится на веб-сервере. Однако идентификатор сеанса хранится как файл cookie, и он позволяет веб-серверу отслеживать сеанс пользователя.

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

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

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

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    HttpSession session = request.getSession();
    String sessionKey = (String) session.getAttribute("sessionkey");
    String remoteAddr = request.getRemoteAddr();
    int remotePort = request.getRemotePort();
    String sha256Hex = DigestUtils.sha256Hex(remoteAddr + remotePort);
    if (sessionKey == null || sessionKey.isEmpty()) {
        session.setAttribute("sessionkey", sha256Hex);
        // save mapping to memory to track which user attempted
        Application.userSessionMap.put(sha256Hex, remoteAddr + remotePort);
    } else if (!sha256Hex.equals(sessionKey)) {
        session.invalidate();
        response.getWriter().append(Application.userSessionMap.get(sessionKey));
        response.getWriter().append(" attempted to hijack session id ").append(request.getRequestedSessionId()); 
        response.getWriter().append("of user ").append(Application.userSessionMap.get(sha256Hex));
        return;
    }
    response.getWriter().append("Valid Session\n");
}

Я использовал алгоритм SHA-2 для хэширования значения, используя пример, приведенный в SHA-256 Hashing at baeldung

С нетерпением ждем ваших комментариев.

1
ответ дан Jzf 24 August 2018 в 22:53
поделиться
  • 1
    @zaph Извините, но я не добавил ответа, чтобы получить репутацию. Дело не в шифровании SHA-2. Но тот факт, что я смог обнаружить использование Cookie в другом сеансе пользователя в сеансе другого пользователя, т. Е. Захват сеанса, как в исходном вопросе. Я протестировал свое решение и нашел, что он работает. Но я не эксперт в этом, поэтому я хотел бы, чтобы сообщество проверило, достаточно ли мой ответ. Возможно, вы можете увидеть, что делает мой фрагмент кода, и решить, отвечает ли он на вопрос. Благодаря! – Jzf 11 February 2018 в 14:26
  • 2
    @zaph Спасибо, что указали на ошибку. Я обновил свой ответ в соответствии с вашим предложением. Пожалуйста, удалите свой голос, если вы считаете, что ответ полезен. – Jzf 11 February 2018 в 16:37

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

4
ответ дан Kibbee 24 August 2018 в 22:53
поделиться

Невозможно предотвратить захват сеанса на 100%, но с некоторым подходом мы можем сократить время атаки злоумышленника на сеанс.

Способ предотвращения захвата сеанса:

1 - всегда использовать сеанс с сертификатом ssl;

2 - отправлять cookie cookie только с httponly, установленным в true (запретить javascript для доступа к cookie сеанса)

2 - использовать идентификатор регенерации сеанса в логин и выход из системы (обратите внимание: не используйте регенерацию сеанса при каждом запросе, потому что если у вас есть последовательный запрос ajax, то у вас есть возможность создать несколько сеансов.)

3 - установить тайм-аут сеанса

4 - сохранить пользовательский агент браузера в переменной $ _SESSION, сравнить с $ _SERVER ['HTTP_USER_AGENT'] при каждом запросе

5 - установить токен-файл cookie и установить время истечения этого файла cookie равным 0 ( пока браузер не будет закрыт). Восстановите значение cookie для каждого запроса. (Для запроса ajax не регенерировать cookie-файл-токен). EX:

    //set a token cookie if one not exist
    if(!isset($_COOKIE['user_token'])){
                    //generate a random string for cookie value
        $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));

        //set a session variable with that random string
        $_SESSION['user_token'] = $cookie_token;
        //set cookie with rand value
        setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
    }

    //set a sesison variable with request of www.example.com
    if(!isset($_SESSION['request'])){
        $_SESSION['request'] = -1;
    }
    //increment $_SESSION['request'] with 1 for each request at www.example.com
    $_SESSION['request']++;

    //verify if $_SESSION['user_token'] it's equal with $_COOKIE['user_token'] only for $_SESSION['request'] > 0
    if($_SESSION['request'] > 0){

        // if it's equal then regenerete value of token cookie if not then destroy_session
        if($_SESSION['user_token'] === $_COOKIE['user_token']){
            $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));

            $_SESSION['user_token'] = $cookie_token;

            setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
        }else{
            //code for session_destroy
        }

    }

            //prevent session hijaking with browser user agent
    if(!isset($_SESSION['user_agent'])){
        $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
    }

    if($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']){
      die('session hijaking - user agent');
    }

note: не регенерировать файлы cookie Token с примечанием ajax request: приведенный выше код является примером. примечание: если пользователь выходит из системы, то токен cookie должен быть уничтожен, а также сеанс

6 - не рекомендуется использовать пользовательский ip для предотвращения захвата сессии, поскольку некоторые пользователи ip изменяются с каждым запросом. ЧТО ВЛИЯНИЕ ДЕЙСТВИТЕЛЬНЫХ ПОЛЬЗОВАТЕЛЕЙ

7 - лично я храню данные сеанса в базе данных, зависит от вас, какой метод вы принимаете

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

7
ответ дан ROMANIA_engineer 24 August 2018 в 22:53
поделиться
  • 1
    привет, я пытаюсь предотвратить захват сеанса (в ASP.NET) и рассмотрел все вышеперечисленные шаги, которые вы предложили. Это приблизительная работа, но когда я использую InPrivateBrowsing / режим инкогнито браузера, сеанс Hijacked. Можете ли вы предложить любую дополнительную вещь для добавления в строку sessionId? – Vishwanath Mishra 16 December 2014 в 13:33
// Collect this information on every request
$aip = $_SERVER['REMOTE_ADDR'];
$bip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$agent = $_SERVER['HTTP_USER_AGENT'];
session_start();

// Do this each time the user successfully logs in.
$_SESSION['ident'] = hash("sha256", $aip . $bip . $agent);

// Do this every time the client makes a request to the server, after authenticating
$ident = hash("sha256", $aip . $bip . $agent);
if ($ident != $_SESSION['ident'])
{
    end_session();
    header("Location: login.php");
    // add some fancy pants GET/POST var headers for login.php, that lets you
    // know in the login page to notify the user of why they're being challenged
    // for login again, etc.
}

Что это значит, это «контекстная» информация о сеансе пользователя, фрагменты информации, которые не должны меняться в течение одного сеанса. Пользователь не будет одновременно на компьютере в США и в Китае, верно? Поэтому, если IP-адрес внезапно изменяется в пределах одного сеанса, что сильно подразумевает попытку захвата сеанса, поэтому вы защищаете сеанс, завершая сеанс и заставляя пользователя повторно аутентифицироваться. Это препятствует попытке взлома, злоумышленник также вынужден войти в систему вместо того, чтобы получить доступ к сеансу. Известить пользователя о попытке (ajax it it bit) и vola, Слегка раздражать + информированный пользователь и их сеанс / информацию защищены.

Мы бросаем User Agent и X-FORWARDED-FOR, чтобы сделать наш лучший способ захватить уникальность сеанса для систем, находящихся за прокси-серверами / сетями. Вы можете использовать больше информации, чем тогда, не стесняйтесь быть творческими.

Это не 100%, но это довольно эффективно.

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

Завершить сеансы, не позволяйте им оставаться действительными на неопределенный срок.

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

19
ответ дан theironyis 24 August 2018 в 22:53
поделиться
  • 1
    Я столкнулся с ситуацией, прежде чем какой-то (довольно большой, но технически отсталый) провайдер будет время от времени изменять IP-адрес браузера пользователя на основе повторной маршрутизации соединений своих пользователей. Это заставило REMOTE_ADDR проверить возврат ложных негативов для нас. – goofballLogic 20 August 2015 в 15:36
  • 2
    Зачем создавать хэш? $_SESSION['ident'] = $aip . $bip . $agent; будет столь же безопасным. – Dan Bray 9 May 2017 в 19:53
  • 3
    Если у вас есть пользователи мобильных устройств, которые используют ваш сайт на ходу и переходят с одной точки доступа на другую, их IP-адреса будут меняться, и они будут продолжать получать свою учетную запись. – Kareem 29 October 2017 в 19:09
  • 4
    Что относительно прокси и VPN? Любой, кто использует прокси-сервер TOR, будет постоянно выходить из своих учетных записей .. каждые несколько минут на самом деле. – Brad 15 December 2017 в 04:18
  • 5
    Даже если вы упускаете из виду, что IP-адреса могут обрабатываться клиентом, так что это не сильно повлияет на то, чтобы отговорить злоумышленника. – Brad 15 December 2017 в 04:19

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

По крайней мере, убедитесь, что старые файлы cookie теряют свою ценность через некоторое время. Даже успешная атака хиджака будет сорвана, когда cookie перестанет работать. Если у пользователя есть cookie из сеанса, который был зарегистрирован более месяца назад, заставьте их повторно ввести свой пароль. Убедитесь, что всякий раз, когда пользователь нажимает ссылку «выйти из системы» вашего сайта, старый UUID сеанса никогда не может использоваться снова.

Я не уверен, что эта идея будет работать, но здесь идет: добавьте серийный номер в ваш cookie сеанса, возможно, такую ​​строку:

SessionUUID, Serial Num, Current Date / Время

Шифруйте эту строку и используйте ее в качестве файла cookie сеанса. Регулярно меняйте серийный номер - возможно, когда cookie имеет 5 минут, а затем переиздает файл cookie. Вы можете даже переиздать его на каждом просмотре страницы, если хотите. На стороне сервера сохраните запись последнего серийного номера, который вы выпустили для этого сеанса. Если кто-то отправляет cookie с неправильным серийным номером, это означает, что злоумышленник может использовать куки-файлы, которые они перехватили ранее, поэтому аннулирует UUID сеанса и просит пользователя повторно ввести свой пароль, а затем переиздать новый файл cookie.

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

40
ответ дан user 24 August 2018 в 22:53
поделиться
  • 1
    Я знаю, что это старый пост, но просто хотел включить, что если злоумышленник должен был захватить сеанс в окне, выделенном «серийным номером», то это не повлияло бы на него. – crush 15 February 2013 в 18:11
  • 2
    @crush, но тогда атакующий будет заблокирован после выделенного окна, верно? Таким образом, по крайней мере, окно атаки небольшое (er). – Johanneke 11 July 2013 в 17:46
  • 3
    Очень умная идея! – Gabriel Graves 23 July 2013 в 22:51
  • 4
    Только проблема в том, что если пользователь покинет ваш сайт в течение 5 минут, им придется снова войти в систему – elipoultorak 16 November 2015 в 12:26
Другие вопросы по тегам:

Похожие вопросы: