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

Add support for SameSite session cookies #215

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Add support for SameSite session cookies #215

wants to merge 1 commit into from

Conversation

mentalstring
Copy link
Contributor

@mentalstring mentalstring commented Nov 22, 2019

Starting from PHP 7.3 there's native support for SameSite cookies (RFC6265bis) which requires using a new session_get_cookie_params() parameter syntax.

@michilehr
Copy link

Maybe add sfWebResponse->setCookie to be feature complete?

Starting from PHP 7.3 there's native support for SameSite cookies (RFC6265bis) which requires using a new session_get_cookie_params() parameter syntax
Copy link
Contributor

@alquerci alquerci left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello,

Comments

Taking Symfony as reference and to not reinvent the wheel.

I suggest to do the same kind of implementation.

  • With constant
  • When same site is null do not add on cookie parameters.

Also the implementation is not complete as it is missing on test component (sfTesterResponse).

Add it for PHP < 7.3

To implement this feature fully for all PHP version cookies should be sent with header() ref.
But it will need to use Symfony\Component\HttpFoundation\Cookie that's a bit maybe a good idea use it if the class exists. And add symfony/http-foundation on composer suggestion.

@@ -288,7 +288,7 @@ public function normalizeHeaderName($name)
// ->setCookie() ->getCookies()
$t->diag('->setCookie() ->getCookies()');
$response->setCookie('foo', 'bar');
$t->is($response->getCookies(), array('foo' => array('name' => 'foo', 'value' => 'bar', 'expire' => null, 'path' => '/', 'domain' => '', 'secure' => false, 'httpOnly' => false)), '->setCookie() adds a cookie for the response');
$t->is($response->getCookies(), array('foo' => array('name' => 'foo', 'value' => 'bar', 'expire' => null, 'path' => '/', 'domain' => '', 'secure' => false, 'httpOnly' => false, 'samesite' => '')), '->setCookie() adds a cookie for the response');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This modification tell that there is a BC break.

As the feature is only for PHP >= 7.3 then current tests should not be touch.
But add a test to target specific version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a BC break. The existence of ['samesite' => ''] in the output of getCookies() does not affect behavior - it gets ignored by setrawcookie and doesn't get sent in the header.

<?php
// Falsy values are simply ignored - don't get sent in the header by PHP
setrawcookie('samesite_null', 'testing', [
  'samesite' => null
]);
setrawcookie('samesite_emptystring', 'testing', [
  'samesite' => ''
]);
setrawcookie('samesite_false', 'testing', [
  'samesite' => false
]);

// Other values, whether legit or not, do get sent
setrawcookie('samesite_gibberish', 'testing', [
  'samesite' => 'asqewrqewrq'
]);
setrawcookie('samesite_none', 'testing', [
  'samesite' => 'none'
]);
?>
Here's the body content
❯ curl -I http://localhost/cookie.php
HTTP/1.1 200 OK
Date: Thu, 05 Oct 2023 23:33:55 GMT
Server: Apache/2.4.57 (Unix) PHP/7.4.33
X-Powered-By: PHP/7.4.33
Set-Cookie: samesite_null=testing
Set-Cookie: samesite_emptystring=testing
Set-Cookie: samesite_false=testing
Set-Cookie: samesite_gibberish=testing; SameSite=asqewrqewrq
Set-Cookie: samesite_none=testing; SameSite=none
Content-Type: text/html; charset=UTF-8

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BC break does not impact PHP >= 7.3 but for PHP < 7.3.

What is the problem to have behaviour depending on PHP version?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behavior does depend on PHP version: https://github.com/FriendsOfSymfony1/symfony1/pull/215/files#diff-5aa2248855efa9ca1219f04cb7575c93a0a1f4af85e30ff32013bf84afcbf0d5R370-R381

In PHP < 7.3, it calls session_set_cookie_params in the original form. In PHP >= 7.3, it uses the new form (passing options as an array, including the samesite setting which is a no-op unless a value has been explicitly set). Yes, $response->getCookies() returns something different, but I don't think returning an extra key in an array from a getter of an internal property should be considered a BC break.

Copy link
Contributor

@alquerci alquerci Oct 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I think

As you said: The behaviour does depend on PHP version.
And tests are a proof that behaviour work as it should.

The tests should expose this behaviour.

getCookies() is parts of the public interface, not the private one.
So it should not lie on what value is passed to PHP internal functions.

It is just my opinion.

Between: the property $cookies is protected, so part of the public interface.

In practice

Let's say that we can spy arguments passed to functions:

  • session_set_cookie_params
  • setrawcookie

On those tests, we will see something like that:

// test/unit/**

if (PHP_VERSION_ID < 70300) {
    // behaviour without samesite
    givenCookie(array(
        'name' => 'some cookie',
        ...
    ));

    whenSendHttpHeaders();
    
    assertCookies(array(
        'cookie name' => array(
            'name' => 'some cookie',
            ...
        )
    ));
    assertSetrawcookieWasCalledWith('some cookie', ..., array(
        ...
    ));
} else {
    // behaviour with samesite
    givenCookie(array(
        'name' => 'some cookie',
        ...,
        'samesite' => 'samesite_value'
    ));

    whenSendHttpHeaders();
    
    assertCookies(array(
        'cookie name' => array(
            'name' => 'some cookie',
            ...
            'samesite' => 'samesite_value'
        )
    ));
    assertSetrawcookieWasCalledWith('some cookie', ..., array(
        ...,
        'samesite' => 'samesite_value'
    ));
}

@mkopinsky
Copy link
Contributor

It looks like this PR was never merged. @alquerci does this just need a PHP-7.3-specific test in sfWebResponseTest.php?

@alquerci
Copy link
Contributor

It looks like this PR was never merged. @alquerci does this just need a PHP-7.3-specific test in sfWebResponseTest.php?

@mkopinsky yes
The idea is the following:
Write the test that forces you to write the code you already know you want to write.

@thePanz can you tell us what is the minimum PHP version supported now ?

@thePanz
Copy link
Member

thePanz commented Nov 17, 2023

@alquerci @mkopinsky (damn, that's quite an old ticket 😅 )

My plan is to move to PHP v7.4 as min version as a first step.
... and later to require PHP v8.1 as min version by removing all PHP v5.x and 7.x support

WDYT?

@alquerci
Copy link
Contributor

@thePanz I think that make sf1 compatible with latest PHP version is another topic than removing support for old PHP versions.

What problem will be fixed by removing all PHP v5.x and 7.x support?

My point of view

We should be able to have information about the usage of sf1 in terms of, at least:

  • PHP version used
  • sf1 version used

Because the segment of sf1 usage is the main target of the purpose of the support provided by FriendsOfSymfony1.

The main goal is to provide an easy path to migrate to the latest Symfony LTS version, or at least the first Symfony2 version.
"at least the first Symfony2 version" because Symfony2 itself have a migration path.

Nothing new as FriendsOfSymfony1 organization what next? #201

Provide a list of instructions how to switch from symfony 1.4.20 to FriendsOfSymfony1 #244
is the first step, the next one is from FriendsOfSymfony1 to Symfony2+

Do you agree with that goal?

What I know

  • Removing PHP <=7.2 version support will block the migration to Symfony 2.8.
    • Because Symfony 2.8 supports PHP >=5.3.2 <=7.2
Symfony version PHP version supported
1.4 5.2 <= version <= 5.3
1.5.15 5.3 <= version <= 8.2
1.5.16-dev 7.1 <= version <= 8.2
2.8 5.3.2 <= version <= 7.2
3.4 5.5.9 <= version <= 7.4
4.4 7.1.3 <= version <= 7.4
6.4 8.1 <= version <= 8.2

Hypothesis

  • Does migrate from sf1.4 to latest Symfony version is possible? Who did it?
  • Does migrate from FriendsOfSymfony1 to Symfony2 is possible?

That's why, like a production management, we need to know users of sf1.

@connorhu
Copy link
Collaborator

Removing PHP <=7.2 version support will block the migration to Symfony 2.8

Who wants to migrate to an unsupported outdated version of symfony?

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

Successfully merging this pull request may close these issues.

6 participants