Skip to content

Commit

Permalink
Allow SameSite cookie attribute to be set (#37)
Browse files Browse the repository at this point in the history
* Allow SameSite cookie attribute to be set

Why: Changes to how browsers will handle the default SameSite attribute
means it's generally considered better to explicitely set it. Lax is
what browsers will default to.

Further reading:
https://www.chromium.org/updates/same-site

https://tools.ietf.org/html/draft-west-cookie-incrementalism-00

https://web.dev/samesite-cookie-recipes/

* Automatically set cookie to Secure if SameSite is set to None.
  • Loading branch information
timobleeker authored Mar 31, 2020
1 parent 3c8d869 commit 8746e96
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ end

`angular_rails_csrf_secure` defaults to `false`.

### SameSite

The SameSite attribute now defaults to `:lax`. You can override this in the config:

```ruby
# application.rb
class Application < Rails::Application
#...
config.angular_rails_csrf_same_site = :strict
end
```

**NOTE**: When using `SameSite=None`, this gem automatically sets the cookie to `Secure`.

### Exclusions

Sometimes you will want to skip setting the XSRF token for certain controllers (for example, when using SSE or ActionCable, as discussed [here](https://github.com/jsanders/angular_rails_csrf/issues/7)):
Expand Down
8 changes: 6 additions & 2 deletions lib/angular_rails_csrf/concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ def set_xsrf_token_cookie

config = Rails.application.config

same_site = config.respond_to?(:angular_rails_csrf_same_site) ? config.angular_rails_csrf_same_site : :lax
secure = config.angular_rails_csrf_secure if config.respond_to?(:angular_rails_csrf_secure)

cookie_options = {
value: form_authenticity_token,
domain: config.respond_to?(:angular_rails_csrf_domain) ? config.angular_rails_csrf_domain : nil
domain: config.respond_to?(:angular_rails_csrf_domain) ? config.angular_rails_csrf_domain : nil,
same_site: same_site,
secure: same_site == :none || secure
}
cookie_options[:secure] = config.angular_rails_csrf_secure if config.respond_to?(:angular_rails_csrf_secure)

cookie_name = config.respond_to?(:angular_rails_csrf_cookie_name) ? config.angular_rails_csrf_cookie_name : 'XSRF-TOKEN'
cookies[cookie_name] = cookie_options
Expand Down
38 changes: 38 additions & 0 deletions test/angular_rails_csrf_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,44 @@ def config.angular_rails_csrf_domain
end
end

test 'same_site is set to Lax by default' do
get :index
assert @response.headers['Set-Cookie'].include?('SameSite=Lax')
assert_valid_cookie
assert_response :success
end

test 'same_site can be configured' do
begin
config = Rails.application.config
config.define_singleton_method(:angular_rails_csrf_same_site) { :strict }

get :index
assert @response.headers['Set-Cookie'].include?('SameSite=Strict')
assert_valid_cookie
assert_response :success
ensure
config.instance_eval('undef :angular_rails_csrf_same_site', __FILE__, __LINE__)
end
end

test 'secure is set automatically when same_site is set to none' do
begin
@request.headers['HTTPS'] = 'on'

config = Rails.application.config
config.define_singleton_method(:angular_rails_csrf_same_site) { :none }

get :index
assert @response.headers['Set-Cookie'].include?('SameSite=None')
assert @response.headers['Set-Cookie'].include?('secure')
assert_valid_cookie
assert_response :success
ensure
config.instance_eval('undef :angular_rails_csrf_same_site', __FILE__, __LINE__)
end
end

private

# Helpers
Expand Down

0 comments on commit 8746e96

Please sign in to comment.