-
-
Notifications
You must be signed in to change notification settings - Fork 30.5k
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
bpo-29613: Added support for SameSite cookies #214
Conversation
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA). Unfortunately we couldn't find an account corresponding to your GitHub username on bugs.python.org (b.p.o) to verify you have signed the CLA. This is necessary for legal reasons before we can look at your contribution. Please follow these steps to help rectify the issue:
Thanks again to your contribution and we look forward to looking at it! |
Looks good to me! @akash0x53 please go ahead and get the CLA filled out so this can be merged. (Note for other core devs: I'm not really up to speed on merging procedures, so I'm hoping someone else will do that part) |
Lib/http/cookies.py
Outdated
@@ -281,6 +281,7 @@ class Morsel(dict): | |||
"secure" : "Secure", | |||
"httponly" : "HttpOnly", | |||
"version" : "Version", | |||
"samesite" : "SameSite" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the documentation with this entry at Doc/library/http.cookies.rst
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include a trailing comma so that if more items are added later, this line doesn't have to be modified again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the docs.
Should there be entries in misc/ACKS and/or misc/News for this? I can do the merge once CLA is signed. |
Per the usual feature/bug division, I think this would be considered a feature and only go on Thanks for catching the need for docs! |
Sounds good. Thanks @alex 😄 |
@the-knights-who-say-ni I signed the CLA and appeared on b.p.o. |
I think a The first comment on the PR says, "If you just signed the CLA, please wait at least one US business day". |
Thanks @timgraham ! @akash0x53:
^ ensure the above wraps at 80 chars, and add it under Please add yourself to Thanks! |
Usually |
The attribute :attr:`samesite` specifies that browser is not allowed to send the | ||
cookie along with cross-site requests. This help to mitigate CSRF attacks. Valid | ||
values for this attribute are "Strict" and "Lax". | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add below this line:
.. versionchanged:: 3.7
Added support for :attr:`samesite` attribute.
Thanks @alex for the clarification about this :)
Doc/library/http.cookies.rst
Outdated
|
||
The attribute :attr:`httponly` specifies that the cookie is only transferred | ||
in HTTP requests, and is not accessible through JavaScript. This is intended | ||
to mitigate some forms of cross-site scripting. | ||
|
||
.. versionchanged:: 3.7 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@akash0x53 I'm really sorry that I wasn't being clear about this :(
The versionchanged
info is to be added after the paragraph about samesite
attribute.
Overall the change should look like this:
...
to mitigate some forms of cross-site scripting.
The attribute :attr:`samesite` specifies that browser is not allowed to send the
cookie along with cross-site requests. This help to mitigate CSRF attacks. Valid
values for this attribute are ``'Strict'`` and ``'Lax'``.
.. versionchanged:: 3.7
Added support for :attr:`samesite` attribute.
The keys are case-insensitive and their default value is ``''``.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless I'm missing something, currently this will accept any value other than "Lax" and "Strict". I wonder if we should discard invalid values like "SameSite=invalid".
I think this PR needs some RFC reading and research on other programming languages.
Lib/test/test_http_cookies.py
Outdated
@@ -121,6 +121,18 @@ def test_set_secure_httponly_attrs(self): | |||
self.assertEqual(C.output(), | |||
'Set-Cookie: Customer="WILE_E_COYOTE"; HttpOnly; Secure') | |||
|
|||
def test_samesite_strict_attrs(self): | |||
C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could use self.subTest()
to make the tests shorter: https://docs.python.org/3/library/unittest.html#distinguishing-test-iterations-using-subtests
Doc/library/http.cookies.rst
Outdated
cookie along with cross-site requests. This help to mitigate CSRF attacks. Valid | ||
values for this attribute are "Strict" and "Lax". | ||
|
||
.. versionchanged:: 3.7 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this to below the other version directives:
[...]
.. versionchanged:: 3.5
[...]
.. versionchanged:: 3.7
[...]
.. versionchanged:: 3.7
Added support for :attr:`samesite` attribute.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So that should be like this, (description of attribute also moved under 3.7)
+ .. versionchanged:: 3.7
+ Added support for :attr:`samesite` attribute.
+
+ The attribute :attr:`samesite` specifies that browser is not allowed to send the
+ cookie along with cross-site requests. This help to mitigate CSRF attacks. Valid
+ values for this attribute are "Strict" and "Lax".
+
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see the diff below:
+ The attribute :attr:`samesite` specifies that browser is not allowed to send the
+ cookie along with cross-site requests. This help to mitigate CSRF attacks. Valid
+ values for this attribute are "Strict" and "Lax".
The keys are case-insensitive and their default value is ``''``.
.. versionchanged:: 3.5
:meth:`~Morsel.__eq__` now takes :attr:`~Morsel.key` and :attr:`~Morsel.value`
into account.
.. versionchanged:: 3.7
Attributes :attr:`~Morsel.key`, :attr:`~Morsel.value` and
:attr:`~Morsel.coded_value` are read-only. Use :meth:`~Morsel.set` for
setting them.
+ .. versionchanged:: 3.7
+ Added support for :attr:`samesite` attribute.
Hi @Mariatta and @berkerpeksag , I made few changes as per suggestions. |
|
||
The attribute :attr:`httponly` specifies that the cookie is only transferred | ||
in HTTP requests, and is not accessible through JavaScript. This is intended | ||
to mitigate some forms of cross-site scripting. | ||
|
||
The attribute :attr:`samesite` specifies that browser is not allowed to send the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think "The samesite attribute" is better English (not sure if the pattern from the previous paragraph is commonly used).
"the browser" (add "the")
|
||
The attribute :attr:`httponly` specifies that the cookie is only transferred | ||
in HTTP requests, and is not accessible through JavaScript. This is intended | ||
to mitigate some forms of cross-site scripting. | ||
|
||
The attribute :attr:`samesite` specifies that browser is not allowed to send the | ||
cookie along with cross-site requests. This help to mitigate CSRF attacks. Valid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This helps
@@ -153,6 +159,9 @@ Morsel Objects | |||
:attr:`~Morsel.coded_value` are read-only. Use :meth:`~Morsel.set` for | |||
setting them. | |||
|
|||
.. versionchanged:: 3.7 | |||
Added support for :attr:`samesite` attribute. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for the
C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"') | ||
C['Customer']['samesite'] = val | ||
self.assertEqual(C.output(), | ||
'Set-Cookie: Customer="WILE_E_COYOTE"; SameSite=%s' % val) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation missing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Negative. It just an illusion i guess. Perfectly showing in my vim.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What Tim meant was that the second argument needs to be indented, like:
self.assertEqual(C.output(),
'Set-Cookie: Customer="WILE_E_COYOTE"; SameSite=%s' % val)
or even better:
expected = f'Set-Cookie: Customer="WILE_E_COYOTE"; SameSite={val}'
self.assertEqual(C.output(), expected)
|
||
The attribute :attr:`httponly` specifies that the cookie is only transferred | ||
in HTTP requests, and is not accessible through JavaScript. This is intended | ||
to mitigate some forms of cross-site scripting. | ||
|
||
The attribute :attr:`samesite` specifies that browser is not allowed to send the | ||
cookie along with cross-site requests. This help to mitigate CSRF attacks. Valid | ||
values for this attribute are "Strict" and "Lax". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the meaning of these values?
Are invalid values rejected? I don't see any code/tests for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Explaining the values would be out of scope of the Python documentation. I think invalid values should be accepted, after all its browser's job to discard invalid values. Suppose, in future they proposed or added another value for SameSite
then we need to make space for that too. By the way i'm not sure about this, let the member decide.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tim is correct that we need to add a test for invalid values. However, we need to decide on what we should do with invalid values first. I don't have time to do a research at the moment, but just a note that Firefox doesn't implement SameSite support yet: https://bugzilla.mozilla.org/show_bug.cgi?id=795346
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. However, chrome implemented SamSite. Right now only Chrome implemented this. https://bugs.chromium.org/p/chromium/issues/detail?id=459154
I checked the test cases they wrote for the same, i didn't find test cases for invalid values.
https://chromium.googlesource.com/chromium/src/+/f71d0bde417518f99f977a0ecbf480b375cf49ca/net/cookies/canonical_cookie_unittest.cc#86
I messed with this branch :( Should I open new PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to fix the branch by rebasing and force pushing.
@@ -121,6 +121,15 @@ def test_set_secure_httponly_attrs(self): | |||
self.assertEqual(C.output(), | |||
'Set-Cookie: Customer="WILE_E_COYOTE"; HttpOnly; Secure') | |||
|
|||
def test_samesite_attrs(self): | |||
samesite_values = ("Strict", "Lax") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use single quotes for consistency?
@akash0x53 please fix your branch. There are a lot of unrelated commits. |
And suggestions by members.
72156b7
to
a6cbc20
Compare
It looks like there a few outstanding issues here still. Do you have the time to fix them up? |
Yes @alex , I fix it asap. |
@akash0x53 Are we still on track for 3.7 with this change? As Django PR#8380 depends on this one I can help if necessary! |
I definitely need help on this @kravietz . I checked your PR, it allow to set invalid values to the cookie. If that approach is taken here then this PR good to go. I'm confused whether we should allow invalid values or not 😕 |
@akash0x53 Correct, I have updated the Django code to check for an invalid samesite values and ready to help with the Python patch. I guess it might be easier if we could chat in real time and plan next steps - IRC or something? BTW for Django I've created a work-around the Python dependency by patching the Morsel and SimpleCookie objects. |
Please rebase. |
I've rebased this over at #6413, should be ready to merge. |
…ted in CPython. Ref python#214.
…and not a compatibility feature. Add DegenerateFiles for readers that don't implement the files API such that the rest of the API can rely on it being implemented. Fixes python#214.
Implemented as per draft
https://tools.ietf.org/html/draft-west-first-party-cookies-07