mirror of
https://github.com/sinatra/sinatra
synced 2023-03-27 23:18:01 -04:00
Fixes #1187 Improve Session Secret documentation to encourage better security
This commit is contained in:
parent
9f4100a769
commit
5e8544bd35
1 changed files with 74 additions and 5 deletions
77
README.md
77
README.md
|
@ -75,6 +75,8 @@ pick up if available.
|
||||||
* [Filters](#filters)
|
* [Filters](#filters)
|
||||||
* [Helpers](#helpers)
|
* [Helpers](#helpers)
|
||||||
* [Using Sessions](#using-sessions)
|
* [Using Sessions](#using-sessions)
|
||||||
|
* [Session Secret Security](#session-secret-security)
|
||||||
|
* [Session Config](#session-config)
|
||||||
* [Choosing Your Own Session Middleware](#choosing-your-own-session-middleware)
|
* [Choosing Your Own Session Middleware](#choosing-your-own-session-middleware)
|
||||||
* [Halting](#halting)
|
* [Halting](#halting)
|
||||||
* [Passing](#passing)
|
* [Passing](#passing)
|
||||||
|
@ -1378,15 +1380,82 @@ get '/:value' do
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Session Secret Security
|
||||||
|
|
||||||
To improve security, the session data in the cookie is signed with a session
|
To improve security, the session data in the cookie is signed with a session
|
||||||
secret. A random secret is generated for you by Sinatra. However, since this
|
secret using `HMAC-SHA1`. This session secret should optimally be a
|
||||||
secret will change with every start of your application, you might want to
|
cryptographically secure random value of an appropriate length which for `HMAC-SHA1`
|
||||||
set the secret yourself, so all your application instances share it:
|
is greater than or equal to 64 bytes (512 bits, 128 hex characters). You would be
|
||||||
|
advised not to use a secret that is less than 32 bytes of randomness
|
||||||
|
(256 bits, 64 hex characters). It is therefore **very important** that you don't
|
||||||
|
just make the secret up, but instead use a secure random number generator to
|
||||||
|
create it. Humans are extremely bad at generating random values.
|
||||||
|
|
||||||
|
By default, a 32 byte secure random session secret is generated for you by Sinatra,
|
||||||
|
but it will change with every restart of your application. If you have multiple
|
||||||
|
instances of your application, and you let Sinatra generate the key, each
|
||||||
|
instance would then have a different session key which is probably not what
|
||||||
|
you want.
|
||||||
|
|
||||||
|
For better security and usability its [recommended](https://12factor.net/config)
|
||||||
|
that you generate a secure random secret and store it in an environment variable
|
||||||
|
on each host running your application so that all of your application
|
||||||
|
instances will share the same secret. You should periodically rotate this
|
||||||
|
session secret to a new value. Here are some examples of how you might create
|
||||||
|
a 64 byte secret and set it.
|
||||||
|
|
||||||
|
**Session Secret Generation**
|
||||||
|
|
||||||
|
```text
|
||||||
|
|
||||||
|
$ ruby -e "require 'securerandom'; puts SecureRandom.hex(64)"
|
||||||
|
99ae8af...snip...ec0f262ac
|
||||||
|
```
|
||||||
|
|
||||||
|
**Session Secret Generation (Bonus Points)**
|
||||||
|
|
||||||
|
Use the [sysrandom gem](https://github.com/cryptosphere/sysrandom) to prefer
|
||||||
|
use of system RNG facilities to generate random values instead of
|
||||||
|
userspace `OpenSSL` which MRI Ruby currently defaults to.
|
||||||
|
|
||||||
|
```text
|
||||||
|
|
||||||
|
$ gem install sysrandom
|
||||||
|
Building native extensions. This could take a while...
|
||||||
|
Successfully installed sysrandom-1.x
|
||||||
|
1 gem installed
|
||||||
|
|
||||||
|
$ ruby -e "require 'sysrandom/securerandom'; puts SecureRandom.hex(64)"
|
||||||
|
99ae8af...snip...ec0f262ac
|
||||||
|
```
|
||||||
|
|
||||||
|
**Session Secret Environment Variable**
|
||||||
|
|
||||||
|
Set a `SESSION_SECRET` environment variable for Sinatra to the value you
|
||||||
|
generated. Make this value persistent across reboots of your host. Since the
|
||||||
|
method for doing this will vary across systems this is for illustrative
|
||||||
|
purposes only.
|
||||||
|
|
||||||
|
```text
|
||||||
|
# vi ~/.bashrc
|
||||||
|
export SESSION_SECRET=99ae8af...snip...ec0f262ac
|
||||||
|
```
|
||||||
|
|
||||||
|
**Session Secret App Config**
|
||||||
|
|
||||||
|
Setup your app config to fail-safe to a secure random secret
|
||||||
|
if the `SESSION_SECRET` environment variable is not available.
|
||||||
|
|
||||||
|
For bonus points use the [sysrandom gem](https://github.com/cryptosphere/sysrandom) here as well.
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
set :session_secret, 'super secret'
|
require 'securerandom'
|
||||||
|
# -or- require 'sysrandom/securerandom'
|
||||||
|
set :session_secret, ENV.fetch('SESSION_SECRET') { SecureRandom.hex(64) }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Session Config
|
||||||
|
|
||||||
If you want to configure it further, you may also store a hash with options in
|
If you want to configure it further, you may also store a hash with options in
|
||||||
the `sessions` setting:
|
the `sessions` setting:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue