-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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 SameSite support - omit None for old browsers #4949
Conversation
Hi @BrianKopp. Thanks for your PR. I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/ok-to-test |
/assign @ElvinEfendi |
@BrianKopp please squash the commits |
@@ -12,6 +12,8 @@ Session affinity can be configured using the following annotations: | |||
|nginx.ingress.kubernetes.io/affinity-mode|The affinity mode defines how sticky a session is. Use `balanced` to redistribute some sessions when scaling pods or `persistent` for maximum stickyness.|`balanced` (default) or `persistent`| | |||
|nginx.ingress.kubernetes.io/session-cookie-name|Name of the cookie that will be created|string (defaults to `INGRESSCOOKIE`)| | |||
|nginx.ingress.kubernetes.io/session-cookie-path|Path that will be set on the cookie (required if your [Ingress paths][ingress-paths] use regular expressions)|string (defaults to the currently [matched path][ingress-paths])| | |||
|nginx.ingress.kubernetes.io/session-cookie-samesite|SameSite attribute to apply to the cookie|Browser accepted values are `None`, `Lax`, and `Strict`| | |||
|nginx.ingress.kubernetes.io/session-cookie-conditional-samesite-none|Will omit `SameSite=None` attribute for older browsers which reject the more-recently defined `SameSite=None` value|`"true"` or `"false"` |
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.
Why two annotations?
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.
session-cookie-samesite: "Lax"
and session-cookie-samesite: "Strict"
are perfectly valid inputs instead of session-cookie-samesite: "None"
. The need for conditionally applying the SameSite=None
cookie attribute is that some older browsers reject SameSite=None
cookies because the older browsers don't know about SameSite=None
, since that's a newer specification that came out after Lax & Strict. The session-cookie-conditional-samesite-none
flag allows users to turn on or off the SameSite=None User-Agent filtering functionality.
// SameSite attribute value | ||
SameSite string `json:"samesite"` | ||
// Flag that conditionally applies SameSite=None attribute on cookie if user agent accepts it. | ||
ConditionalSameSiteNone bool `json:"conditional_samesite_none"` |
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.
conditional_samesite_none -> conditional-samesite-none
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 may be a dumb question, but how does this relate to... the CookieSessionAffinity
type struct in internal/ingress/types.go
line 146ish?
/test pull-ingress-nginx-lualint |
/test pull-ingress-nginx-e2e-1-15 |
Codecov Report
@@ Coverage Diff @@
## master #4949 +/- ##
=========================================
Coverage ? 58.58%
=========================================
Files ? 88
Lines ? 6777
Branches ? 0
=========================================
Hits ? 3970
Misses ? 2372
Partials ? 435
Continue to review full report at Codecov.
|
/retest |
build/run-in-docker.sh
Outdated
@@ -25,6 +25,10 @@ set -o pipefail | |||
# temporal directory for the /etc/ingress-controller directory | |||
INGRESS_VOLUME=$(mktemp -d) | |||
|
|||
if [[ "$OSTYPE" == darwin* ]]; then | |||
INGRESS_VOLUME=/private$INGRESS_VOLUME | |||
fi |
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.
👍
|
||
if cookie_samesite then | ||
cookie_path = cookie_path .. "; SameSite=" .. cookie_samesite | ||
end |
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.
The lua-resty-cookie library has native support for samesite
, please use that attribute instead of misusing path
attribute. All you need to do is: samesite = cookie_samesite,
below after secure = ngx.var.https == "on",
.
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.
Would it be better to add a TODO here to fix this after that library adds SameSite=None support?
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.
FYI the upstream change was merged a day or two ago.
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.
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.
Will do both of these this weekend!
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.
Drafted, will poke on tests later on this weekend. #5040
local cookie_conditional_samesite_none = self.cookie_session_affinity.conditional_samesite_none | ||
if cookie_conditional_samesite_none | ||
and cookie_samesite == "None" | ||
and not same_site.same_site_none_compatible(ngx.var.http_user_agent) then |
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.
Looking at cloudflare/lua-resty-cookie@8f41439#diff-8944ed02502a8a0a1f17e24e9b28c7a7R145, it seems like the library we use won't let us pass "None"
for samesite
. But given the new Chrome change you linked we should be able to set samesite
to "Nonde"
.
I think I'd rather fix this in the upstream library than hack it here.
Therefore in the meantime I suggest we comply with what the upstream library provides, i.e not support "None"
value at all. Then we patch the upstream library to support this new Chrome change and come back here to reflect 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.
Yes, I'd rather fix it upstream as well. There is a currently a PR to that library to add support for SameSite=None, added 11 days ago. cloudflare/lua-resty-cookie#32
Unfortunately the library hasn't been updated in 3 years. Of the 5 contributors, only 1 has an active current github history.
According to Google Chrome's pages, version 80 is set to ship Feb 4th with 50% of users being on the new SameSite settings. I'm not sure we can wait around for a PR to go through on a repo that hasn't been touched in 3 years. I'm happy to come back through and change this to use the samesite argument in the library once it accepts it. What do you think?
https://www.chromestatus.com/features/schedule
https://www.chromium.org/updates/same-site
…ckwards compatibility
/retest |
5 similar comments
/retest |
/retest |
/retest |
/retest |
/retest |
@@ -169,6 +171,7 @@ If you use the ``cookie`` affinity type you can also specify the name of the coo | |||
|
|||
The NGINX annotation `nginx.ingress.kubernetes.io/session-cookie-path` defines the path that will be set on the cookie. This is optional unless the annotation `nginx.ingress.kubernetes.io/use-regex` is set to true; Session cookie paths do not support regex. | |||
|
|||
Use `nginx.ingress.kubernetes.io/session-cookie-samesite` to apply a `SameSite` attribute to the sticky cookie. Browser accepted values are `None`, `Lax`, and `Strict`. Some older browsers reject cookies with the more-recently-defined `SameSite=None`. To omit `SameSite=None` from these older browsers, add the annotation `nginx.ingress.kubernetes.io/session-cookie-conditional-samesite-none: "true"`. |
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.
Can you make it easier for users reading this doc to understand how the "older browsers" is defined?
Thanks for the patch @BrianKopp! I hope the PR in the upstream repository gets fixed soon and we revisit this. Otherwise I think we should fork and use our own version of lua-resty-cookie. I don't want to block this PR for #4949 (comment), but would be great if that gets addressed in a subsequent PR. /lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: BrianKopp, ElvinEfendi The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/retest |
-- This function compares the user agent against known | ||
-- browsers which will reject SameSite=None cookies. | ||
-- reference: https://www.chromium.org/updates/same-site/incompatible-clients | ||
function _M.same_site_none_compatible(user_agent) |
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.
@BrianKopp I lifted this code to implement a fix on one of my apps and ran into a problem. We have some idiotic code that apparently doesn't send a User-Agent
header. Running the request through this library causes a 502.
I don't know if there are safeguards in place for this but I thought I should warn you.
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.
Awesome thank you for pointing this out! I've added handling for that here #5091
This PR includes two main additions. First, a
session-cookie-samesite
attribute allows configuration of the cookieSameSite
attribute with the provided value. Second, ifSameSite=None
is specified andsession-cookie-conditional-samesite-none = "true"
, then the code which generates the cookie checks the client's User-Agent header and omits theSameSite=None
cookie attribute for old browsers which would otherwise reject aSameSite=None
. TheNone
option is relatively recent, and these old browsers simply reject cookies with this attribute.Supersedes #4878
What this PR does / why we need it:
This PR solves the impending Chrome 80 release in February which will treat all third-party cookies as SameSite=Strict if they omit the SameSite cookie attribute. This would otherwise break stickiness for users making third-party requests. E.g. you have an app on
hostone.com
, but you want stickiness for your api which is onhosttwo.com
. These two hosts are third-party, and withoutSameSite=None
on thehosttwo.com
response, Chrome 80 won't send thehosttwo.com
cookie to your backend which is expecting stickiness.Source: https://www.chromium.org/updates/same-site
Types of changes
How Has This Been Tested?
Unit tests have been added to test the conditional
SameSite=None
logic against various User-Agent headers.Checklist: