Securing the Rails session secret
blog.phusion.nlSharing a few thoughts:
- having a per-machine key auto-generated will not work properly with PaaS (such as Heroku, DotCloud etc), especially if you have N machines behind a load-balancer. In that case they need to share the key, so using a Heroku production variable or similar will have to be used instead.
- I believe we (Rails users) should at least move away from having a hard-coded key in the source by default, and instead generate and deploy it by other ways (such as symlinking like database.yml or PaaS variables), since having it in the source put an onus on people having access to the source code (such as freelancers/contractors, or other team members without deploy access etc). This should be treated sensitively!
- in today's practice of having the key in the source code, some staging environments would currently also have the same key by default, and sometimes these are less secure or up-to-date compared to production environment, providing another attack vector maybe.
Agreed! We've already had and solved this problem with various config settings (i.e. database.yml). Why is there a big debate about this? The way I see it, the Rails community is already used to dealing with database.yml so it makes sense to extend this same pattern to other sensitive configurations.
I like the solution I stole from rstat.us: you have an off-repository location for the token If there's none:
* on production you crash,
* on dev, you autogenerate one and save it to a config file that's possibly dev-only,
* during automated tests you just autogenerate something and live with it.
Here's the nice replacement for secret_token.rb: https://github.com/hotsh/rstat.us/blob/master/config/initial...
We use Heroku and PaaS environment variables, with a default value if you're running in development/test mode, e.g.
if Rails.env.production? && ENV['SECRET_TOKEN'].blank? raise 'SECRET_TOKEN environment variable must be set!' end
secret_token = ENV['SECRET_TOKEN'] || 'safdasfjlkj...'
Make sure your session secret is a long random string (it might be tempting, if you're passing it in through the environment, to make it shorter or readable). It's an HMAC key that anyone who can get a session from your application can dictionary.
Oh yes. It's probably ridiculously long (I think 256 chars, letters numbers special etc) :)
"Users would still be logged out on every deploy, but I believe this is a minor problem for most people."
Would be an absolute pain for users of things such as Github who deploy several times a day.
I store the secret inside of my paste config file ... which is picked up by uwsgi and passed to my Pyramid app.
You are required to configure my app anyway, and I can store it inside of a config file that doesn't need to be made public or stored in version control.
"would be world-readable because it’s only used for deriving secret keys"
I don't like this.
Otherwise, not a bad exploration.
Please explain the security implications. If you make the key readable only by some users then it requires more deployment-time setup to get things right.
The security implications vary, but generally private keys should be readable only by the processes that need them, to whatever degree is practical, and entropy that is used to generate a key should be considered roughly equivalent to the key itself.
This is not to say that leaving a private key world-readable is necessarily a horrible idea; it can certainly ease deployment, and there are always tradeoffs. But it does mean that this key is only as secure as your most vulnerable user account - including unprivileged user accounts running riskier services (unless they are genuinely sandboxed).
Making it readable only by a certain group is going to be better, security-wise, and shouldn't be too much more difficult, and so may generally be a better idea, but my key objection was that it sounded like a statement of policy: "we're only deriving keys from this, so we don't need to be careful with it" - which is bad policy without considering the protection the needed by the specific keys. The article does talk about this some later on but not (IMO) clearly or generally enough.