Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel session not working when switching protocol (https to http or http to https)

I am currently developing an App where i have to secure few pages using SSL. For example, Login, register pages. However, when protocol switches between https to http, Laravel session is not transmitted over HTTP.

is there any solution, Laravel will keep the session for both protocol.

like image 334
Anam Avatar asked Jun 11 '14 06:06

Anam


2 Answers

By default, Laravel is setting secure and/or httponly for auth and session cookies. I could not find a way to change this in configuration, and infact in Laravel 4.0 (this is no longer the case), the httponly is hard coded as a setting in vendor/laravel/framework/src/Illuminate/Session/SessionManager.php

Note that you should not leak cookies from HTTPS to HTTP, because it stops you from being able to keep sessions secure (I could still sniff a session from another user on my network logged into your website, for example).

Laravel 4.1+

Edit app/config/session.php. Change the 'secure' key to false if you want cookies set on https to also be read on http.

Alternatively, follow @martinstoeckli's advice and set the key depending on the value of your environment.

Laravel 4.0

Maybe the best way to implement this would be to replace CookieSessionHandler with your own handler.

For example, a new class could be created which would extend CookieSessionHandler with an updated write function which would mark all cookies as not being for https/http only.

Class NewCookieSessionHandler extends CookieSessionHandler implements \SessionHandlerInterface {
    /**
     * {@inheritDoc}
     */
    public function write($sessionId, $data)
    {
        // $this->cookie is \Illuminate\Cookie\CookieJar
        $this->setCookie($this->cookie->make($sessionId, $data, $this->minutes, '/', false, false));
    }

    /**
     * Set the given cookie in the headers.
     *
     * @param  \Symfony\Component\HttpFoundation\Cookie  $cookie
     * @return void
     */
    protected function setCookie($cookie)
    {
        if (headers_sent()) return;

        setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), false, false);
    }
    
}

Then inside app/config/session.php you can change the driver to NewCookie

and finally inside app/start/global.php register your new cookie driver that overrides setting the cookie

use Illuminate\Cache\Repository;

Cookie::extend('NewCookie', function($app)
{
    return new NewCookieSessionHandler;
});
like image 132
Tim Groeneveld Avatar answered Oct 16 '22 21:10

Tim Groeneveld


This is a problem not only with Laravel. You have to decide whether the cookie containing the session-id is restricted to HTTPS only, or if you send it to HTTP pages too.

  • If the cookie is restricted to HTTPS pages, it will not be sent by the browser to unsafe HTTP requests. In this case you will loose the session when switching to HTTP pages.
  • If the cookie is sent to HTTPS and HTTP pages, an attacker can read the session-id and therefore impersonate the user, when he can listen to an HTTP request. The cookie will be sent not only with html requests, but also with every request for pictures and other resources.

The config can be found in the \app\config\session.php file and is called secure. If you want to set it to true only on the live site (but not for development), you could write something like that:

'secure' => App::environment('production'),

To handle this problem you would have to split the two concerns, maintaining the session and authentication. I wrote a small article about this topic with example code. Keep in mind that when you switch between the protocols, you are always prone to an SSL-strip attack, so you may think about using HTTPS for the whole site. For todays servers this should not be a problem anymore.

like image 3
martinstoeckli Avatar answered Oct 16 '22 21:10

martinstoeckli