Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend Cookie Support for SameSite=None, Secure #30832

Closed
ganeshkarki opened this issue Dec 13, 2019 · 16 comments
Closed

Extend Cookie Support for SameSite=None, Secure #30832

ganeshkarki opened this issue Dec 13, 2019 · 16 comments

Comments

@ganeshkarki
Copy link

  • Laravel Version: 5.5

Description:

Google introduces new Chrome policy, marking all Cookie without samesite flag to 'strict' by default. If you want to allow third party cookies you must set samesite flag to none.

For cookie related logic laravel uses symfony/http-foundation and they already have released the support for it. I am not sure if its good idea or not, but can we update the composer.json to use proper version of htttp-foundation to extend the same support to laravel too?

Symfony Ticket: symfony/symfony#31475
For symfony/http-foundation, the version is 3.4.28

Please consider change like this:

//composer.json
"require": {
    ...
    "symfony/http-foundation": "~3.4.28",
   ...
},
@driesvints
Copy link
Member

Hey there,

Unfortunately we don't support this version anymore. Please check out our support policy on which versions we are currently supporting. Can you please try to upgrade to the latest version and see if your problem persists? We'll help you out and re-open this issue if so.

Thanks!

@stzahi
Copy link

stzahi commented Mar 4, 2020

Inside config/session.php
You can inject it into the cookie through the path argument.
'path' => '/;samesite=none',

Another thing is you must make sure that
'secure' => true

@Ardakilic
Copy link

Thanks @stzahi , your trick works nicely even on Laravel 4!

However, when I do this on v4.2, it only sets the laravel_sessions key as intended. Custom session keys didn't have secure flag even though the secure => true variable was set. So I had to alter the path line to make custom session values also have secure flag.

So, I had to alter path key like this:

 'path' => '/;SameSite=None; secure',

In addition to altering the secure key to true.

And voila! Worked nicely.

Thanks again for the trick.

@stzahi
Copy link

stzahi commented Mar 17, 2020

@Ardakilic secure=>true worked for me on laravel 4.2,
Make sure you've cleared the config cache (php artisan config:cache).

@Ardakilic
Copy link

@stzahi Yup, it didn't help sadly. I set the cookies via Cookie::queue('key', 'value', $expire); and these ones didn't have the secure flag, unlike the default cookie key for sessions such as laravel_session which it worked nicely for like your example. Anyways, thanks again!

@Jimbolino
Copy link
Contributor

please note that newer versions of php (7.0 and up) do not support this workaround because extra validation was added to setcookie().

ErrorException (E_WARNING) Cookie paths cannot contain any of the following ',; \t\r\n\013\014'

https://bugs.php.net/patch-display.php?bug_id=69948&patch=0001-Fix-69948&revision=latest

@Ardakilic
Copy link

Ardakilic commented Mar 25, 2020

@Jimbolino I've just tried this cookie path fix with Laravel 4.2 and PHP7.1 on a project, no warning thrown at all. I enabled debug, and I have error_reporting(E_ALL ^ E_DEPRECATED) on my app for mcrypt.

But yeah, it throws error as you mentioned, but I guess for PHP versions bigger than 7.3.0: https://3v4l.org/iMo7C

@Jimbolino
Copy link
Contributor

Yeah i was not sure about the 7.0 statement.
Figured that a commit to master @ 2015-06-28 would land in the next major php release, but they sat on it for a couple of years:
7.0 release date: 2015-12-03
7.3 release date: 2018-12-06

Alternatively i was looking for a fix via .htaccess, however:
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=None
does not work for my *.localhost and *.companydev.com develop environments

And a more complex regex example got me spooked:
Header edit Set-Cookie (?i)^(.*)(;\s*secure)??((\s*;)?(.*)) "$1; SameSite=None$3$4"

Luckily prod still runs php 5.5 🤣

@viraljetani
Copy link

Inside config/session.php
You can inject it into the cookie through the path argument.
'path' => '/;samesite=none',

Another thing is you must make sure that
'secure' => true

This worked for me.. Thank you!

@mahmoudelshenawy
Copy link

i am using laravel 7 and this trick does not work can anybody help me with that? i am using datatable and coulding redirect to another page based on data from datatable page ?

@stzahi
Copy link

stzahi commented Sep 9, 2020 via email

@tegola
Copy link

tegola commented Nov 12, 2020

Anyone having issues with cookies when developing locally might need to add an exception in the configuration:

// config/session.php
'path' => env('APP_ENV') === 'local' ? '/' : '/;SameSite=None',
'secure' => env('APP_ENV') === 'local' ? false : true,

@isupremedyou
Copy link

@tegola I have added that but I still get a 419 while testing my login page. Login redirects to a 419 page and in console, I see a message that Set-Cookie failed because it still has the secure attribute.

Did you have to do anything else to get Laravel to stop marking the cookie as secure?

@tegola
Copy link

tegola commented Nov 13, 2020

@isupremedyou Make sure you clear the cached configuration with php artisan config:clear.

@Ardakilic
Copy link

Ardakilic commented Dec 19, 2020

I succeeded to achieve this with Laravel 4.2 and PHP7.4 (and will work possibly with PHP8), but I ended up editing some core files:

  1. Revert the path to / or whatever it was at config/session.php

  2. Open vendor/symfony/http-foundation/ResponseHeaderBag.php

Find:

$cookies .= 'Set-Cookie: '.$cookie."\r\n";

Replace With:

$cookies .= 'Set-Cookie: '.$cookie."; SameSite:None\r\n";
  1. Open vendor/symfony/http-foundation/Response.php

Find

setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());

Replace With:

if (PHP_VERSION_ID < 70300) {
    setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
} else {
    setcookie($cookie->getName(), $cookie->getValue(), [
        'expires' => $cookie->getExpiresTime(),
        'path' => $cookie->getPath(),
        'domain' => $cookie->getDomain(),
        'secure' => $cookie->isSecure(),
        'samesite' => 'None',
        'httponly' => $cookie->isHttpOnly(),
    ]);    
}
  1. Open vendor/symfony/http-foundation/Cookie.php

Find the __toString() method, add the following line just above the last line return $str;:

$str .= '; SameSite=None';

And voila! I have PHP7.4, and Laravel 4.2 (mcrypt installed from php-pear), having cookies for the site with proper SameSite attribute enabled.

This will possibly work with Laravel 5.0, etc. too. I'm sure the locations of the files are same or quite similar.

I may create a fork in the future to override the symfony/http-foundation, but it's 3 am now and I'm quite tired.

@Ardakilic
Copy link

Ardakilic commented Dec 31, 2020

I have created a fork regarding my last message:

https://github.com/Ardakilic/http-foundation

Here's my commit: Ardakilic/http-foundation@5f1cb06

Simply altering your composer.json like this should suffice:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/Ardakilic/http-foundation"
        }
    ],
    "require": {
        "symfony/http-foundation": "dev-2.7-samesite as 2.7.999"
    }
}

I'd appreciate if any one of you could try this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants