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 to Cookies #28297
Add SameSite to Cookies #28297
Conversation
@cfabianski is there any risk of breaking an app when upgrading from an older version if we now enable Generally though 👍 |
We could have a global setting to make it backward compatible. Though, I thought |
5fa9239
to
c950717
Compare
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.
looks good, just noticed a teeny tiny typo
...lib/rails/generators/rails/app/templates/config/initializers/cookies_same_site_protection.rb
Outdated
Show resolved
Hide resolved
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.
🎉
@pixeltrix does it look better now? |
@maclover7 Do you have any thoughts about it? |
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.
Coming along very nicely. Two quick things:
- Can you also add an entry to Action Pack's CHANGELOG.md about this?
- Can you add a test for what happens to the cookies when the config value is
:no_protection
?
@@ -534,6 +543,10 @@ def digest | |||
def key_generator | |||
request.key_generator | |||
end | |||
|
|||
def same_site_protection |
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'm probably just missing it, but where is this method used? I didn't see any calls in the 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.
It's not but I followed the pattern which is to have access to this as part of the cookie. Want me to remove it?
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 you're not calling it anywhere directly, then I'd say to not add the method right now. If it's needed in the future, it's easy to add :)
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.
Here we go :)
@maclover7 Done |
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.
👍 looks good to me, but Security Team folks will probably want to review this 😬
@maclover7 great thanks. |
@cfabianski They'll review it when they get the chance |
@maclover7 do you have any update on that one? |
Maybe a good feature for Rails 6? |
@swrobel I hope so! 😺 |
@swrobel fixed the conflicts just in case somebody wants to make it part of Rails 6 :) /cc @maclover7 |
I'll have a look at the failures and I'll get them fixed in the meantime |
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.
SameSite
is still absent in Rails 6 (2d3a28b) cookie headers. I think it should be added! 👍 If you're still interested in getting this merged, please rebase and squash your commits.
actionpack/CHANGELOG.md
Outdated
@@ -1,5 +1,15 @@ | |||
## Rails 6.0.0.alpha (Unreleased) ## | |||
|
|||
* Add SameSite to cookies. | |||
|
|||
With this change in place, the CSRF protection will become useless. |
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 note that not all browsers support this feature. Also, since this is just text added to a header that browsers magically obey would it really ever deprecate authenticity tokens?
@@ -364,6 +369,10 @@ def handle_options(options) # :nodoc: | |||
|
|||
options[:path] ||= "/" | |||
|
|||
if %i[lax strict].include?(request.cookies_same_site_protection) |
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 %i[lax strict]
should be moved to a frozen constant.
|
||
# Specify the SameSite level protection for the cookies | ||
# Valid options are :no_protection, :lax, and :strict. | ||
Rails.application.config.action_dispatch.cookies_same_site_protection = :no_protection |
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.
Should this be grouped with config/initializers/cookies_serializer.rb
as just a cookies.rb
initializer?
c740c8c
to
4fa8b05
Compare
Hey @gmcgibbon, thank you for your review. I managed to implement the changes you asked for. |
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.
👍 Code and tests look great but I'm still a little hesitant on the changelog entry.
actionpack/CHANGELOG.md
Outdated
@@ -1,3 +1,13 @@ | |||
* Add SameSite to cookies. | |||
|
|||
With this change in place, the CSRF protection will become useless. |
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.
According to the IETF doc, this isn't true:
"SameSite" cookies offer a robust defense against CSRF attack when
deployed in strict mode, and when supported by the client. It is,
however, prudent to ensure that this designation is not the extent of
a site's defense against CSRF, as same-site navigations and
submissions can certainly be executed in conjunction with other
attack vectors such as cross-site scripting.
Developers are strongly encouraged to deploy the usual server-side
defenses (CSRF tokens, ensuring that "safe" HTTP methods are
idempotent, etc) to mitigate the risk more fully.
You should re-word to describe SameSite
as a CSRF protection additive as opposed to a replacement.
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 missed the update here sorry. I've updated it as well now (squashed)
4fa8b05
to
cff096e
Compare
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.
One last comment regarding the changelog and then this should be good to go! 😄
actionpack/CHANGELOG.md
Outdated
For now, the default is `:no_protection` which makes it backward compatible. | ||
By switching from `:no_protection` to `:lax` | ||
in `config/initializers/cookies`, the cookies will get | ||
more secure than ever. |
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 this sentence, I would say
By switching from `:no_protection` to `:lax` in `config/initializers/cookies.rb`,
cookies won't be sent by browsers in cross-site POST requests.
`:strict` will disable cookies from being sent in both cross-site GET and POST requests.
to provide a little more detail on this feature.
cff096e
to
beac956
Compare
@gmcgibbon Thank you. I've updated it! |
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.
💯
@gmcgibbon let's hope we can get it merged now :) |
Thanks for sharing that! Fortunately it appears about 80% of clients are on
Yeah Rails will probably need to begin intelligently parsing
@HarrisonB I would love to see this sample code if you have it. 🙏 After February 4 there are going to be a lot of Rails developers scrambling to find workarounds. |
@KelseyDH unfortunately I cannot share the code at this time. |
@KelseyDH I can share our code. We're manipulating the class SameSite
def initialize(app)
@app = app
end
def call(env)
status, headers, response = @app.call(env)
headers['Set-Cookie'] = headers['Set-Cookie'].split("\n").map do |cookie|
next cookie if cookie.blank?
next cookie if cookie =~ /;\sSameSite/
cookie + '; SameSite=None' + '; Secure'
end.join("\n")
[status, headers, response]
end
end This is a stripped down version. In our production code we also check that we only set Also note that we're making sure the cookie is |
There's also: https://github.com/pschinis/rails_same_site_cookie |
@KelseyDH: You got me startled here for a second ;) But if I got the announcement right, Chrome 80 is not disposing all cookies without the @kaspth, on an unrelated matter: Sorry for not answering you back then, I was on vacation for a few weeks and was somehow under the impression that it hadn't been merged yet (may need to improve my GitHub skills there^^). |
@p8 It works on Rails 5. |
I understand your point of view. What everyone here wants is a working internet. The fact that Google acts the way they do, doesn't mean we need to retaliate in the same way. We've been writing fixes for IE for years, not because we loved the browser, but because we wanted our users to be able to use our webapps. Chrome is the most used browser in the world. It would be great that one of the most popular web frameworks had a full support for it. |
The release of this in Chrome has been pushed back a little. "The SameSite-by-default and SameSite=None-requires-Secure behaviors will begin rolling out to Chrome 80 Stable for an initial limited population starting the week of February 17, 2020, excluding the US President’s Day holiday on Monday." But apps that need cookies to work in a cross-origin manner (like when embedded in an iframe) will need some fix soon. |
SameSite enforcements are being rolled out as of Mar 2. Any updates on this ticket? This is starting to cause breaks in some production apps. |
It turns out that old Safari browsers are broken with SameSite:None if you rely on cross-site cookies. For the convenience of other people needing to fix this, this monkey patch wil set SameSite:None if it sees a new Chrome browser to get some immediate relieve. Just drop in config/initialisers, should work on Rails 5 & 6, but you do need the latest version of the rack gem. (Edit: added Firefox)
|
For anyone running into this, this is already possible today for session cookies: Rails.application.config.session_store(:cookie_store, same_site: :none) Note that if you want to use This is because rails'
|
@yboulkaid That will set it on all browsers, so that's fine but only if you do need to worry about old Safari clients. |
How do you implement SameSite attribute for cookies in rails? Ok so I have searched and searched. May explanations on what is happening with SameSite. I can't find anything that shows me how or where to do that. It's like I am completely missing something. Can someone share some insight on how to set this attribute in Rails? I need something concise not vague. Thanks! |
ok so an update I have SameSite=None but it need to be secure as well any ideas on how todo that? |
@blackwellsmith you can add |
I tried that it didn’t work. I am currently trying it with the rails same site cookie gem and I can see the cookie. I am still trouble shooting some issues. |
@Fjan Solution above worked beautifully as a short term patch given browsers currently sparsely support this config. It would be nice to have this type of middleware easily configurable in the Rails base config somewhere; for API only applications this new cookie issue is becoming increasingly prevalent. |
@shawndeprey Note that the latest Firefox also drops cookies inside iframes unless they are secure and same-site. It's safe to set this on older Firefox browsers, I changed the test in the monkey patch to: |
@Fjan that's good to know and thanks for the updated config. This is super helpful. 👏 |
@yboulkaid I tried this on Rails 6.0.3.2 with Rack 2.2.3 and it had no effect on my In config/initializers/session_store.rb
|
Summary
Add
SameSite
to the cookies to reinforce the security.Define
Lax
as a first step.Strict
is also supported but is too strict as its name suggests 😸Other Information
SameSite
is the new recommended way to keep your website secure. It would makeCSRF
even more secure.Some links: