Laravel - данные сеанса выживают при выходе из системы/регистрации, даже для разных пользователей

Сегодня я заметил что-то тревожное, проверяя файлы сеанса в папке storage/framework/sessions, созданной Laravel 5.

Вот что произошло:

  • Я вошел как пользователь A
  • Я перешел на страницу, в которой хранится переменная X в сеансе
  • Я вышел из системы, но не закрыл браузер.
  • Файл сеанса в storage/framework/sessions был все еще там, и браузер печенье было живым.
  • Я вошел в систему как пользователь B.
  • Старый файл сеанса в storage/framework/sessions удален и появился новый файл сеанса.
  • Я просмотрел новый файл сеанса - удивление! переменная X выжила и все еще существует, доступна для пользователя B!

Это приводит к проблемам безопасности, поскольку теперь пользователь B имеет доступ к данным пользователя A.

Во время отладки через исходный код Laravel я обнаружил, что Session Store никогда не очищается во время процесса выхода из системы/входа в систему. Только учетные данные для входа удаляются в методе Illuminate\Auth\Guard::clearUserDataFromStorage(), но все атрибуты Store Store все еще существуют, а затем позже, когда вызывается $kernel->terminate($request, $response);, что в свою очередь приводит к Illuminate\Session\Middleware\StartSession::terminate() вызову Store::save(), который вслепую сохраняет $this->attributes к новому сеансу, игнорируя тот факт, что он теперь принадлежит другому пользователю.

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

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

Очистка при выходе из системы не будет надежной, потому что пользователь никогда не сможет нажать ссылку "Выход", но дождитесь окончания срока действия сеанса, что для Laravel все еще не очищает сеанс.

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

Я нашел тему форума, которая также пытается решить несколько схожую проблему:

http://laravel.io/forum/04-27-2014-how-to-expire-session-data

Я смутился этим:

У меня был еще один вопрос на этом сегодня и понял, в чем проблема: Session:: flush() не удаляет данные сеанса, которые создает приложение, например данные корзины покупок

Если это так, то единственный способ полностью избавиться от сеанса - использовать PHP native session_unset() и session_destroy(), но я бы не хотел идти таким путем - я бы предпочел найти чище, Решение Laravel-ish, если возможно.

Как сообщить Laravel, что я хочу, чтобы мои старые данные сеанса удалялись вместе с данными аутентификации пользователя, когда истекает срок аутентификации или пользователь выходит из системы?

Ответ 1

В laravel docs говорится, что вы можете:

Удаление элемента из сеанса

Session::forget('key');

Удаление всех элементов из сеанса

Session::flush();

Вы можете перейти к признаку AuthenticatesAndRegistersUsers.php и переписать

   /**
     * Log the user out of the application.
     *
     * @return \Illuminate\Http\Response
     */
    public function getLogout()
    {
        $this->auth->logout();

        return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/');
    }

к

   /**
     * Log the user out of the application.
     *
     * @return \Illuminate\Http\Response
     */
    public function getLogout()
    {
        Session::flush();

        $this->auth->logout();

        return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/');
    }

Я не знаю, действительно ли это работает, но попробуйте:)

Обновление

В соответствии с этим ответом здесь, в разделе "Переполнение стека" , вы можете установить срок действия сеанса при закрытии браузера или через XXX минуты. Используемый вместе с вышеупомянутым решением, он должен решить проблему?

В config/session.php

   /*
    |--------------------------------------------------------------------------
    | Session Lifetime
    |--------------------------------------------------------------------------
    |
    | Here you may specify the number of minutes that you wish the session
    | to be allowed to remain idle before it expires. If you want them
    | to immediately expire on the browser closing, set that option.
    |
    */

    'lifetime' => 120,

    'expire_on_close' => false