Каков наилучший способ предотвратить перехват сеанса?

StackOverflow https://stackoverflow.com/questions/22880

  •  09-06-2019
  •  | 
  •  

Вопрос

В частности, это касается использования файла cookie сеанса клиента для идентификации сеанса на сервере.

Является ли лучшим решением использовать шифрование SSL / HTTPS для всего веб-сайта, и у вас есть наилучшая гарантия того, что ни один злоумышленник не сможет перехватить существующий файл cookie сеанса клиента?

И, возможно, лучше всего использовать какое-то шифрование для самого значения сеанса, которое хранится в вашем сеансовом файле cookie?

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

Идентификатор сеанса, Серийный номер, Текущая дата/ Время

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

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

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

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

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

  2. Использование гиперссылок на основе отношений Создает ссылку (например. http://example.com/secure.php?token=2349df98sdf98a9asdf8fas98df8 ) К ссылке добавляется x-байтовая (предпочтительного размера) строка MD5 с произвольным заполнением, при перенаправлении страницы случайно сгенерированный токен соответствует запрошенной странице.

    • После перезагрузки выполняется несколько проверок.
    • Исходный IP-адрес
    • HTTP_USER_AGENT_АГЕНТ
    • Токен сеанса
    • вы поняли, в чем дело.
  3. Файл cookie для аутентификации сеанса с коротким сроком службы.как сообщалось выше, хорошей идеей является файл cookie, содержащий защищенную строку, которая является одной из прямых ссылок на действительность сеансов.Сделайте так, чтобы срок его действия истекал каждые x минут, повторно выпуская этот токен и повторно синхронизируя сеанс с новыми данными.Если какие-либо неточности в данных, либо выйдите из системы, либо попросите пользователя повторно аутентифицировать свой сеанс.

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

// 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), и vola, Слегка раздраженный + проинформированный пользователь и его сессия / информация будут защищены.

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

Это не на 100%, но чертовски эффективно.

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

Истекают сеансы, не позволяйте им оставаться действительными бесконечно.

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

Попробуйте Безопасный протокол использования файлов cookie, описанный в это статья Лю, Ковача, Хуанга и Гауды:

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

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

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

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

Короче говоря:он безопасный, легкий, работает у меня просто отлично.

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

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

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

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

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

3 - установите время ожидания сеанса

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

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

    //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');
    }

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

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

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

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

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

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

  • IP и / или X-ПЕРЕАДРЕСОВАННЫЙ -ДЛЯ проверок.Они работают и довольно безопасны...но представьте себе боль пользователей.Они приходят в офис с Wi-Fi, получают новый IP-адрес и теряют сеанс.Нужно снова войти в систему.

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

  • Токен локального хранилища.При входе в систему сгенерируйте токен, сохраните его в хранилище браузера и сохраните в зашифрованном файле cookie (зашифрованном на стороне сервера).Это не имеет побочных эффектов для пользователя (localStorage сохраняется при обновлении браузера).Это не так безопасно - поскольку это просто безопасность через неизвестность.Кроме того, вы могли бы добавить некоторую логику (шифрование / дешифрование) в JS, чтобы еще больше скрыть ее.

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

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

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

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

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

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

@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 в baeldung

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

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

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

Защищать с помощью:

$ip=$_SERVER['REMOTE_ADDER'];
$_SESSEION['ip']=$ip;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top