Merge pull request #45501 from ghiculescu/same-site-false

Allow opting out of the `SameSite` cookie attribute when setting a cookie
This commit is contained in:
Jonathan Hefner 2022-07-05 11:06:45 -05:00 committed by GitHub
commit c0f71dac70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 7 deletions

View File

@ -1,3 +1,13 @@
* Allow opting out of the `SameSite` cookie attribute when setting a cookie.
You can opt out of `SameSite` by passing `same_site: nil`.
`cookies[:foo] = { value: "bar", same_site: nil }`
Previously, this incorrectly set the `SameSite` attribute to the value of the `cookies_same_site_protection` setting.
*Alex Ghiculescu*
* Allow using `helper_method`s in `content_security_policy` and `permissions_policy` * Allow using `helper_method`s in `content_security_policy` and `permissions_policy`
Previously you could access basic helpers (defined in helper modules), but not Previously you could access basic helpers (defined in helper modules), but not

View File

@ -453,8 +453,9 @@ module ActionDispatch
options[:path] ||= "/" options[:path] ||= "/"
cookies_same_site_protection = request.cookies_same_site_protection unless options.key?(:same_site)
options[:same_site] ||= cookies_same_site_protection.call(request) options[:same_site] = request.cookies_same_site_protection.call(request)
end
if options[:domain] == :all || options[:domain] == "all" if options[:domain] == :all || options[:domain] == "all"
# If there is a provided tld length then we use it otherwise default domain regexp. # If there is a provided tld length then we use it otherwise default domain regexp.

View File

@ -334,6 +334,16 @@ class CookiesTest < ActionController::TestCase
head :ok head :ok
end end
def set_same_site_strict
cookies["user_name"] = { value: "david", same_site: :strict }
head :ok
end
def set_same_site_nil
cookies["user_name"] = { value: "david", same_site: nil }
head :ok
end
end end
tests TestController tests TestController
@ -362,7 +372,7 @@ class CookiesTest < ActionController::TestCase
@request.host = "www.nextangle.com" @request.host = "www.nextangle.com"
end end
def test_setting_cookie_with_no_protection def test_setting_cookie_with_no_same_site_protection
@request.env["action_dispatch.cookies_same_site_protection"] = proc { :none } @request.env["action_dispatch.cookies_same_site_protection"] = proc { :none }
get :authenticate get :authenticate
@ -370,7 +380,7 @@ class CookiesTest < ActionController::TestCase
assert_equal({ "user_name" => "david" }, @response.cookies) assert_equal({ "user_name" => "david" }, @response.cookies)
end end
def test_setting_cookie_with_protection_proc_normal_user_agent def test_setting_cookie_with_same_site_protection_proc_normal_user_agent
@request.env["action_dispatch.cookies_same_site_protection"] = Proc.new do |request| @request.env["action_dispatch.cookies_same_site_protection"] = Proc.new do |request|
:strict unless request.user_agent == "spooky browser" :strict unless request.user_agent == "spooky browser"
end end
@ -380,7 +390,7 @@ class CookiesTest < ActionController::TestCase
assert_equal({ "user_name" => "david" }, @response.cookies) assert_equal({ "user_name" => "david" }, @response.cookies)
end end
def test_setting_cookie_with_protection_proc_special_user_agent def test_setting_cookie_with_same_site_protection_proc_special_user_agent
@request.env["action_dispatch.cookies_same_site_protection"] = Proc.new do |request| @request.env["action_dispatch.cookies_same_site_protection"] = Proc.new do |request|
:strict unless request.user_agent == "spooky browser" :strict unless request.user_agent == "spooky browser"
end end
@ -391,7 +401,7 @@ class CookiesTest < ActionController::TestCase
assert_equal({ "user_name" => "david" }, @response.cookies) assert_equal({ "user_name" => "david" }, @response.cookies)
end end
def test_setting_cookie_with_misspelled_protection_raises def test_setting_cookie_with_misspelled_same_site_protection_raises
@request.env["action_dispatch.cookies_same_site_protection"] = proc { :funky } @request.env["action_dispatch.cookies_same_site_protection"] = proc { :funky }
error = assert_raise ArgumentError do error = assert_raise ArgumentError do
@ -400,7 +410,7 @@ class CookiesTest < ActionController::TestCase
assert_match "Invalid SameSite value: :funky", error.message assert_match "Invalid SameSite value: :funky", error.message
end end
def test_setting_cookie_with_strict def test_setting_cookie_with_same_site_strict
@request.env["action_dispatch.cookies_same_site_protection"] = proc { :strict } @request.env["action_dispatch.cookies_same_site_protection"] = proc { :strict }
get :authenticate get :authenticate
@ -408,6 +418,30 @@ class CookiesTest < ActionController::TestCase
assert_equal({ "user_name" => "david" }, @response.cookies) assert_equal({ "user_name" => "david" }, @response.cookies)
end end
def test_setting_cookie_with_same_site_nil
@request.env["action_dispatch.cookies_same_site_protection"] = proc { nil }
get :authenticate
assert_cookie_header "user_name=david; path=/"
assert_equal({ "user_name" => "david" }, @response.cookies)
end
def test_setting_cookie_with_specific_same_site_strict
@request.env["action_dispatch.cookies_same_site_protection"] = proc { :lax }
get :set_same_site_strict
assert_cookie_header "user_name=david; path=/; SameSite=Strict"
assert_equal({ "user_name" => "david" }, @response.cookies)
end
def test_setting_cookie_with_specific_same_site_nil
@request.env["action_dispatch.cookies_same_site_protection"] = proc { :lax }
get :set_same_site_nil
assert_cookie_header "user_name=david; path=/"
assert_equal({ "user_name" => "david" }, @response.cookies)
end
def test_setting_cookie def test_setting_cookie
get :authenticate get :authenticate
assert_cookie_header "user_name=david; path=/; SameSite=Lax" assert_cookie_header "user_name=david; path=/; SameSite=Lax"