Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Fix for Issue #299 #304

wants to merge 1 commit into from

3 participants


Allow old_secret to be optional so we don't break backwards compatibility
Fix for Issue #299


Thanks for the patches, but I want to squash this before I merge.


@raggi cool thanks. Here it is squashed

@raggi raggi closed this pull request from a commit
@raggi raggi Add missing spec coverage for when secrets do not match (ACHTUNG!)
Fix Rack::Session::Cookie when old_secret or secret are not supplied.
Always encode cookies with one of the two secret options, if provided, preferencing :secret
Based on contribution from ciberch. Closes #304. Closes #299.
@raggi raggi closed this in 08e0eb0

Apologies, I actually rewrote your patch. Thank you for your contribution.


Thank you @ciberch and @raggi! James, what branch did you merge this into? I don't see it yet. I'll want to update my Rack gem once it's available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 7, 2012
  1. @ciberch
This page is out of date. Refresh to see the latest.
Showing with 8 additions and 3 deletions.
  1. +4 −3 lib/rack/session/cookie.rb
  2. +4 −0 test/spec_session_cookie.rb
7 lib/rack/session/cookie.rb
@@ -104,10 +104,11 @@ def unpacked_cookie_data(env)
request =
session_data = request.cookies[@key]
- if (@secret || @old_secret) && session_data
+ if @secret && session_data
session_data, digest = session_data.split("--")
- if (digest != generate_hmac(session_data, @secret)) && (digest != generate_hmac(session_data, @old_secret))
- session_data = nil
+ unless digest == generate_hmac(session_data, @secret)
+ # Clear the session data if secret doesn't match and old secret doesn't match
+ session_data = nil if (@old_secret.nil? || (digest != generate_hmac(session_data, @old_secret)))
4 test/spec_session_cookie.rb
@@ -147,6 +147,10 @@ def decode(str); @calls << :decode; str; end
res =, :secret => 'test')).
get("/", "HTTP_COOKIE" => cookie)
res.body.should.equal '{"counter"=>3}'
+ cookie = res["Set-Cookie"]
+ res =, :secret => 'another secret')).
+ get("/", "HTTP_COOKIE" => cookie)
+ res.body.should.equal '{"counter"=>1}'
it "loads from a cookie wih accept-only integrity hash for graceful key rotation" do
Something went wrong with that request. Please try again.