-
Notifications
You must be signed in to change notification settings - Fork 2.1k
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Session secret documentation does not encourage good secret management strategies #1187
Comments
A good example to add would be Ruby's SecureRandom as a way to generate a secure, random session secret, like this:
You could also use |
+1 I'm not a crypto expert -- but if my reading of rfc2104 is correct, we should recommend a key length equal to the length of the HMAC hash (by default, SHA-1, 160 bits). SecureRandom's length parameters are in bytes, so we'd say |
I'm no expert either, but I think that should be the correct length, especially since a bigger value won't make your app more secure. The RFC2104 spec also mentions that these keys should be refreshed periodically. Maybe it would be nice to create a Sinatra recipe to address this issue in a more insightful way. |
rack-protection has been a dependency of Sinatra since (I believe) 1.3.0: 1f1e58e I would recommend anyone to use it for session management, instead of generating your own token since this gem also protects against a number of session-based attacks. |
To @jacksingleton's point the README does recommend setting your own session token.
Sinatra generates a random secret by default using See: https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1797 This isn't something rack-protection handles as far as I can tell. I agree that some documentation to describe how to generate a secure secret would be helpful and a recommendation on how to keep out of source control would be 👍 |
I would also recommend setting the session secret in an environment variable. You can retrieve it within your code using the block form of Storing config like this in env vars is also a key tenet of 12 Factor Apps
Option 1Throws an exception if
Option 2Generate a secure value for
Towards Stronger KeysI would also recommend using the https://github.com/cryptosphere/sysrandom Example: Its exactly the same, except for installing the gem and a different
Choosing a Key LengthI think it is not desired as @jacksingleton said to reduce the random key length to 20 bytes (40 hex chars). I think you should use a secure key that is the same block size as the underlying HMAC hash function (64 bytes for SHA1) which is what is used by https://github.com/rack/rack/blob/master/lib/rack/session/cookie.rb#L108 I think Sinatra is also generating a 64 byte key if one isn't provided if this is the correct spot in the code where that is happening: Line 1797 in 1b0edc0
Here is some good reading on this topic courtesy of @atoponce https://pthree.org/2016/07/29/breaking-hmac/ tl;dr
Bonus PointsJust for kicks, here's Ruby Demo showing the same thing Aaron showed in Python in that article:
|
Sure, I am open to whatever you suggest we should add to our documentation or improve secure defaults. Could you submit us a patch? |
/cc #1216 |
I'm working on a docs patch. |
I have created a PR to improve the docs with what I consider to be better security practices and incorporating other suggestions in this issue. This PR does not address the following docs: http://www.sinatrarb.com/intro.html#Using%20Sessions These are largely duplicative of the README content I modified and I am not even sure where that content is being generated from. Perhaps someone can open a new issue to transfer my changes there. |
@grempe nice, that documentation looks pretty clear 👍. on key length, linking to the breaking-hmac article might be more confusing than anything else. the article itself states that the title is clickbait, hmac is not broken, and there are no known security implications to the property they point out. even if a key longer than the block size is used, and it is reduced to 160 bits, that is more than enough entropy to sleep well at night for the next few decades (http://security.stackexchange.com/questions/6141/amount-of-simple-operations-that-is-safely-out-of-reach-for-all-humanity/6149#6149). anyone uncomfortable about with that amount of entropy should be switching away from HMAC-SHA1 of course, a longer key won't hurt anything so I don't care if we recommend 512 bits but on line 1387 we should make it clear that the important thing is using /more/ than a certain amount of entropy, not /less/. |
Fair point about the link @jacksingleton I just made some tweaks to the document patch and I force overwrote my previous PR commit. I think that it is prudent to continue to recommend a 64 byte secret. The practical difference for dev/ops is almost zero so going with the stronger value is recommended. |
Thanks @grempe and @jacksingleton for your patch and feedback to get this done <3 |
Fixes #1187 Improve Session Secret documentation to encourage better security
This fallback is added to ensure a session secret for the app is always set/available in case the proper ENV variable is missing sinatra/sinatra#1187 (comment)
…sions-section Modify 'Using Sessions' section in README.ja.md to follow #1187
In the readme and intro documentation, we describe how to set a session secret manually with this code block:
We don't mention anywhere that the value should really be pulled in from an environment variable (or possibly config file not checked into the codebase, secret store, etc).
We also don't mention how to securely generate the value.
While ideally all developers would know that this secret shouldn't be checked into code, and should be generated with a CSPRNG, frameworks have an opportunity to promote good security practices. This will simultaneously educate developers and prevent vulnerabilities.
I'd suggest that we:
The text was updated successfully, but these errors were encountered: