Защита аутентифицированного сеанса PHP от перехвата сеанса через перехват пакетов

Меня интересует тема защиты сессий PHP без использования SSL.

К моему удивлению, если посредник прослушивает пакеты, которыми обмениваются пользователь и сервер, очень легко украсть сеанс, даже если он аутентифицирован. Я знаю, что есть некоторые тактики для ограничения убытков, такие как изменение идентификатора сеанса при входе / выходе из системы, запись / проверка параметров системы пользователя (например, ОС, браузера).

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

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

Исправлена ​​ли проблема? Каковы недостатки этого подхода, если предположить, что злоумышленник не может провести крипто-анализ первоначального обмена логином?

2 ответа

Решение

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

Если вы пишете Flash/Java-апплет /Unity или какой-либо из этих плагинов, то вы можете следовать своему плану, поскольку вы можете более тщательно контролировать клиента и добавлять подпрограммы для подписи.

Но я предполагаю, что вы доставляете HTML-страницы в браузер без использования плагина? Если так, у вас есть два варианта, правда. Во-первых, это SSL (который вы исключаете), поскольку он встроен в браузер. Вторым является Javascript. Для максимальной безопасности вам нужно каким-то образом имитировать SSL, в том числе с клиентским хранилищем шифровального (открытого) ключа / алгоритма (чтобы они никогда не перемещались вместе с сообщениями). Вы хотели бы получить как можно ближе к открытому / закрытому ключу + рукопожатию SSL - что не означает подвиг. Как предположил Сарнольд, вам нужен сильный ключ шифрования. Проверьте http://www.jcryption.org/ для примера - другие появляются с поиском в Google.

Если это немного чрезмерно, ваше наиболее жизнеспособное решение, вероятно, заключалось бы в согласовании более простого алгоритма шифрования с использованием JS: вы отправляете "ключ", сохраняете "ключ" в файле cookie в браузере, все коммуникации через AJAX и вы создаете более простой механизм подписи на основе этого ключа (плюс, возможно, еще одна переменная, которой клиент поделился с вами во время первоначального рукопожатия). Все, что не декодирует или не соответствует ключу, затем убивает весь сеанс и начинает снова.


Сарнольд имеет хорошие замечания в своем ответе, что md5 и SHA-1 следует избегать; а некоторые даже считают, что SHA256 станет отличным решением для современных компьютеров, но, учитывая, что вам нужно внедрить решение в JS, для скорости вы можете быть привязаны к чему-то столь же "легковесному" (моя аналогия), как к md5. Таким образом, ваша лучшая защита для этого - точное ведение журнала и обнаружение грубой силы / ошибок. Любые сообщения, поступающие искаженные (и вы можете проверить на любом конце) должны быть зарегистрированы и контролироваться. Слишком много сбоев и IP-адрес забанен - ​​и ведите журнал.

Вы хотели бы использовать что-то вроде HMAC вместо более простого MD5 - и вы хотели бы использовать SHA256 или более крупный, поскольку известно, что у MD5 есть слабые стороны, а SHA-1 тоже начинает ощущать слабость.

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

Так что вам нужно добавить одноразовый номер в протокол.

Возможны и другие проблемы - в конце концов, TLS теперь находится на версии 1.2 после трех итераций SSL. Просто придерживайтесь TLS и будьте счастливы.

Другие вопросы по тегам