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

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

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

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

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

Ответы

Ответ 1

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

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

РЕДАКТИРОВАТЬ. Этот ответ был изначально написан в 2008 году. Сейчас он 2016, и нет оснований не иметь SSL на вашем сайте. Нет более простого текстового HTTP!

Ответ 2

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

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

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

SessionUUID, серийный номер, текущая дата/время

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

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

Ответ 3

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

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

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

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

    • После перезагрузки выполняется несколько проверок.
    • Исходный IP-адрес
    • HTTP_USER_AGENT
    • Идентификатор сеанса
    • вы поняли смысл.
  • Короткий сеанс проверки подлинности сеанса. как указано выше, cookie, содержащий защищенную строку, которая является одной из прямых ссылок на достоверность сеансов, является хорошей идеей. Завершить его каждые x минут, переиздавая этот токен и повторно синхронизируя сеанс с новыми данными. Если какие-либо неверные совпадения в данных, либо выведите пользователя из системы, либо повторите аутентификацию их сеанса.

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

Ответ 4

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

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

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

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

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

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

Ответ 5

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

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

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

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

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

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

Ответ 6

Невозможно предотвратить захват сеанса на 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 equal with $_COOKIE['user_token'] only for $_SESSION['request'] > 0
    if($_SESSION['request'] > 0){

        // if it 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-маркер с помощью ajax-запроса Примечание: приведенный выше код является примером. примечание: если пользователь выходит из системы, то токен cookie должен быть уничтожен, а также сеанс

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

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

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

Ответ 7

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

Ответ 8

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

  • IP и/или проверки X-FORWARDED-FOR. Эти работы и довольно безопасны... но представьте себе боль пользователей. Они приходят в офис с WiFi, получают новый IP-адрес и теряют сессию. Необходимо снова войти в систему.

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

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

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

Ответ 9

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

Ответ 10

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

Ждем ваших комментариев.

Ответ 11

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

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

Ответ 12

Защитить:

$ip=$_SERVER['REMOTE_ADDER'];
$_SESSEION['ip']=$ip;