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

Setting SameSite cookie attribute conditionally #459

Closed
arashb31 opened this issue Jan 28, 2021 · 4 comments
Closed

Setting SameSite cookie attribute conditionally #459

arashb31 opened this issue Jan 28, 2021 · 4 comments

Comments

@arashb31
Copy link

arashb31 commented Jan 28, 2021

Is there a way to be able to set the SameSite=None or SameSite=Strict conditionally in a controller action?
For example, if current_user.admin?, upgrade the session_store cookie with SameSite=Strict, otherwise, keep it as None.

@oreoshake
Copy link
Contributor

@arashb31 There is a way! In fact, it's probably the best way to retroactively roll out samesite in general.

SecureHeaders::Configuration.override(:admin_hardening) do |config|
  config.cookies = {
    samesite: {
      strict: { only: ["my_admin_cookie"] },
      none: { only: ["saml_csrf_token", "saml_return_to"] },
      lax: { except: ["my_admin_cookie", "saml_csrf_token", "saml_return_to"] },
    },
  }
end
# you'll want to do this as early as possible as you would lose 
# any modifications to the config to this point (append/override_content_security_policy_directives)
def some_before_action
  if admin?
    use_secure_headers_override(request, :admin_hardening)
  end
end

What I can't recall is if you'd need to copy over whatever other cookie settings or if you only need to supply the modifications. I suspect you'd need to duplicate the config (or read from config.cookies)

@arashb31
Copy link
Author

arashb31 commented Jan 29, 2021

Wow that worked very nicely!
One unexpected side effect was that a lot of other headers were set that I was not expecting.
I'm guessing the gem sets a default hardening. Is there a way to disable all those default hardenings?

Edit: As a quick workaround I simply set all the settings in the config to SecureHeaders::OPT_OUT

One other thing I did notice is that if a cookie's value does not change during a single request lifecycle, then changing its SameSite value like above does not work.

I believe this is due to the fact that Rails only creates a 'Set-Cookie' header if the value has changed from the value initially sent by the user.

I believe this gem uses Rack Middleware to modify the cookies security settings. Since Rails does not know about the middleware, it doesn't realize the SameSite value wants to be changed, so if the cookie's actually value does not change, Rails doesn't generate the header again.

Would you know any way to force Rails to create the 'Set-Cookie' header, so that the Rack Middleware can then modify it's SameSite value?

Thanks for your help!

@oreoshake
Copy link
Contributor

There was an example of someone doing this recently: #450

There isn't a single-line config option but you can turn off the safe defaults using that strategy.

@arashb31
Copy link
Author

Thanks so much. Appreciate the help, and an excellent gem!

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

2 participants