diff options
author | Jeremy Daer <jeremydaer@gmail.com> | 2015-12-04 19:07:53 -0700 |
---|---|---|
committer | Ben Toews <mastahyeti@users.noreply.github.com> | 2016-03-17 13:37:54 -0600 |
commit | cc21d02a7d0fa1df5008e70127a57ab6f1e38cb5 (patch) | |
tree | d6631884f07fd6febc6e572c28243435e3636239 | |
parent | 2fd9df71aff4af8a3ab8088a6919f5d9a5e4ab95 (diff) | |
download | rack-cc21d02a7d0fa1df5008e70127a57ab6f1e38cb5.tar.gz |
First-Party cookies, another line of CSRF defense
Set `first_party: true` to set the First-Party attribute telling browsers to only send the cookie with legit first-party requests. * https://tools.ietf.org/html/draft-west-first-party-cookies-00 * https://www.chromestatus.com/feature/4672634709082112
-rw-r--r-- | lib/rack/utils.rb | 3 | ||||
-rw-r--r-- | test/spec_response.rb | 14 |
2 files changed, 16 insertions, 1 deletions
diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb index 3b6f69f3..ab36ed84 100644 --- a/lib/rack/utils.rb +++ b/lib/rack/utils.rb @@ -311,12 +311,13 @@ module Rack rfc2822(value[:expires].clone.gmtime) if value[:expires] secure = "; secure" if value[:secure] httponly = "; HttpOnly" if (value.key?(:httponly) ? value[:httponly] : value[:http_only]) + first_party = "; First-Party" if value[:first_party] value = value[:value] end value = [value] unless Array === value cookie = escape(key) + "=" + value.map { |v| escape v }.join("&") + - "#{domain}#{path}#{max_age}#{expires}#{secure}#{httponly}" + "#{domain}#{path}#{max_age}#{expires}#{secure}#{httponly}#{first_party}" case header["Set-Cookie"] when nil, '' diff --git a/test/spec_response.rb b/test/spec_response.rb index 6b13c0c9..c0354934 100644 --- a/test/spec_response.rb +++ b/test/spec_response.rb @@ -97,6 +97,20 @@ describe Rack::Response do response["Set-Cookie"].should.equal "foo=bar" end + it "can set First-Party cookies" do + response = Rack::Response.new + response.set_cookie "foo", {:value => "bar", :first_party => true} + response["Set-Cookie"].must_equal "foo=bar; First-Party" + end + + [ nil, false ].each do |non_truthy| + it "omits First-Party attribute given a #{non_truthy.inspect} value" do + response = Rack::Response.new + response.set_cookie "foo", {:value => "bar", :first_party => non_truthy} + response["Set-Cookie"].must_equal "foo=bar" + end + end + it "can delete cookies" do response = Rack::Response.new response.set_cookie "foo", "bar" |