Регенерация сеанса вызывает истекший сеанс с быстрыми вызовами AJAX

Мое приложение представляет собой полноценную веб-страницу AJAX с использованием Codeigniter Framework и обработчика сеанса memcached.

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

Вот схематическое изображение, которое я сделал, чтобы ясно показать проблему: введите здесь описание изображения

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

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

введите описание изображения здесь


person Nicolas Thery    schedule 14.07.2016    source источник
comment
Какую версию КИ вы используете? Это похоже на постоянную ошибку в обработке сеансов CI, особенно с сеансами db. Я думаю, что поддержка нескольких идентификаторов сеанса может работать как хак, но похоже, что это напрашивается на неприятности. Можете ли вы использовать какой-либо другой обработчик сеансов, возможно, собственные сеансы PHP с Redis или аналогичные? Вы также просматривали эту тему?   -  person ldg    schedule 18.07.2016
comment
@Idg: да, я прочитал все эти темы. Это говорит о проблеме, и CI3 (моя версия) решил ее, отключив обновление сеанса с помощью запросов AJAX. Проблема в том, что в моем приложении только есть запросы AJAX....   -  person Nicolas Thery    schedule 18.07.2016
comment
@NicolasThery Можете ли вы просто объяснить, какая у вас проблема?   -  person Abdulla Nilam    schedule 18.07.2016
comment
@Abdulla Схемы, которые я сделал, такие сложные? Первый запрос получает новый идентификатор сеанса (регенерация идентификатора сеанса), а второй — асинхронный запрос, который выполняется до того, как первый ответ не имеет нового идентификатора сеанса. Серверы отвергают это.   -  person Nicolas Thery    schedule 18.07.2016
comment
все имена сеансов одинаковы??   -  person Abdulla Nilam    schedule 18.07.2016
comment
Есть два решения. Закройте сеанс, как только будет сделан вызов ajax, и поставьте вызовы ajax в очередь, чтобы они не запускались асинхронно. Еще любит смотреть на сервер, отправленный и обслуживающий персонал, чтобы обработать некоторые запросы. При регенерации проверьте, активна ли сессия (session_status() == 2).   -  person Nitin    schedule 19.07.2016


Ответы (2)


Во-первых, предложенное вами решение вполне разумно. Фактически, сотрудники OSWAP советуют именно это:

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

К сожалению, это невозможно реализовать с помощью стандартного управления сеансами PHP (или я не знаю, как это сделать). Тем не менее, реализация этого поведения в пользовательском драйвере сеанса 1 не должно создавать серьезных проблем.

Теперь я собираюсь сделать смелое заявление: вся идея периодической регенерации идентификатора сеанса нарушена. Теперь не поймите меня неправильно, повторно генерируя идентификатор сеанса при входе в систему (или, точнее, as По словам OSWAP, «изменение уровня привилегий») действительно является очень хорошей защитой от фиксация сеанса.

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

Есть лучшая (и более простая) защита от простой кражи сеанса: используйте SSL (HTTPS). Периодическое обновление сеанса следует рассматривать как обходной путь для этого вектора атаки.


1 ссылка на стандартный путь PHP

person RandomSeed    schedule 20.07.2016
comment
Мне очень нравится ваш ответ, потому что вы искали утверждения OWASP, которые являются ссылкой на безопасность, на которую я действительно полагаюсь. Однако HTTPS недостаточно, многие компании имеют бреши в своих расшифровках/шифрованиях SSL, что делает внутренний взлом белым ящиком. Надежная безопасность — это безопасность со многими барьерами. На данный момент я буду полагаться на сборщик мусора сеанса memcached и использовать функцию «Не уничтожать сеансы при обновлении». Это не оптимально, но все же это будет лучше, чем ничего. - person Nicolas Thery; 23.07.2016
comment
Я не совсем уверен, от какой модели угроз вы защищаете. Если вы обеспокоены атакой, использующей плохую реализацию SSL, исправьте ее в первую очередь, потому что любая другая защита становится бессмысленной, если она скомпрометирована. Если вы беспокоитесь о внутренней работе, то я считаю, что периодическая регенерация сеанса вообще не поможет. - person RandomSeed; 25.07.2016
comment
У МНОГИХ крупных компаний есть программный брандмауэр, который блокирует какие-то потоки, например, VOIP. Для этого у них есть передний прокси, с которым приложение создает SSL-рукопожатие, SSL-соединение НЕ выполняется на полном пути к пользователю. (Я это приложение, и я не в состоянии справиться со всей своей пользовательской инфраструктурой, я являюсь программным обеспечением облачного сервиса) После этого этот прокси читает сетевой пакет и выполняет свою работу, обнаруживая все его правила. ЗАТЕМ начинается новое рукопожатие с пользователем-сотрудником, использующим внутренний сертификат: ЭТОТ сертификат может быть поврежден. - person Nicolas Thery; 30.07.2016

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

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

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

Мне кажется, что вы пытаетесь найти техническое решение «деловой» проблемы. Я имею в виду, что либо вы неправильно истолковали свои требования, либо требования просто не так хорошо продуманы/указанны.

Я бы посоветовал вам попробовать что-то из следующего:

  • спросите себя, можно ли объединить эти несколько одновременных запросов в один

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

  • каждый раз, прежде чем вы запускаете серию запросов, запускайте «обновляющий» запрос ajax, чтобы получить новый сеанс, и только в случае успеха продолжайте выполнять все остальные запросы.

Надеюсь, что-то из того, что я написал, поможет вам найти решение. Удачи

person Vlad Lyga    schedule 17.07.2016
comment
Учитывая количество людей с похожей проблемой, я не думаю, что изменение вашей бизнес-логики в конечном итоге станет ответом. Я согласен с тем, что могут быть некоторые улучшения бизнес-логики, но здесь также, похоже, есть реальная техническая проблема CodeIgniter. Использование цепочек промисов на FE также может быть полезным и затрагивает обе стороны (техническую и логическую), но, опять же, не решит проблему полностью. - person ldg; 18.07.2016
comment
привет, я пытаюсь направить, чтобы попробовать и думать по-другому о вашей проблеме. Но я предложил два технических способа смягчить это. Реализация, конечно, на ваше усмотрение. Во всяком случае, я до сих пор интуитивно чувствую, что запуск множества одновременных вызовов Ajax для одного и того же пользователя является странным, и его можно и следует избегать. Так что да, я бы все же сказал, что вы, вероятно, решаете не ту проблему. Может быть, вы могли бы описать здесь вариант использования, чтобы дать контекст, и тогда, может быть, я увижу, что ошибаюсь, и смогу помочь вам лучше? - person Vlad Lyga; 18.07.2016
comment
@VladLyga Во-первых: Спасибо за ваши ответы. Как сказал Идг, проблема может возникнуть в разных бизнес-кейсах. Я описал случай использования пакета, который я могу преобразовать в групповой запрос (это также будет лучше для пропускной способности сети, производительности и надежности). Но проблема может возникнуть в гораздо более простом (и не поддающемся изменению) варианте использования: допустим, у меня есть счетчик обновления, который запускается каждую минуту. Если я одновременно запускаю другой асинхронный запрос, во время регенерации сеанса, первый request регенерирует сеанс, а второй получает кик и выдает всплывающее окно аутентификации. - person Nicolas Thery; 18.07.2016
comment
@Idg: Можете ли вы объяснить или связать меня с цепочками обещаний на FE, я не знаю об этом. Кстати, я проверю первую ссылку, которую вы мне прислали. - person Nicolas Thery; 18.07.2016
comment
Цепочки обещаний: solutionoptimist.com/2013/12/27/javascript- promise-chains-2 Это не вариант: мои запросы отправляются из разных частей кода, я не могу легко связать их - person Nicolas Thery; 18.07.2016
comment
@NicolasThery Лично я бы не стал реализовывать предложенный вами хак для CI. Но если вы полны решимости «исправить» его в любом случае на стороне сервера, я бы реализовал его как «свободу действий». Это означает, что если запрос с просроченной сессией сделан в течение, скажем, 1 минуты после истечения срока действия, то этот запрос все равно будет пропущен. Или просто выберите гораздо более простое "исправление" на стороне клиента - создайте оболочку вокруг вызова ajax для проверки истечения срока действия сеанса, тогда все ваши вызовы ajax должны пройти через эту функцию, и она позаботится об обработке обновления сеанса. - person Vlad Lyga; 18.07.2016