This is in almost the same category as checking in your SSH private keys. I say almost because at least this one is somewhat understandable. From the perspective of of an app developer having everything in one place that you can deploy makes things easy. Hence it's included by default. Otherwise people would complain of losing the secret keys in between deploys (causing existing sessions to invalidate)[1].
Course none of that makes it acceptable (it's atrocious!). This is a perfect example of why code and config need to be kept separate[2]. If you have that as a mantra from the beginning then you don't have issues like this.
[1]: In reality you should change your secret token regularly. The best approach is to accept a rolling window of old ones so you can age them out. Then you can pick how far back you want to support (eg. how stale a client's cookie can be).
[edit] should be widely known. I would say it took me a couple hours to read the majority of the security doc at a shallow level) and I wouldn't have known about this unless i had just started upgrading a 2.3 app.
Taking a quick look on github, it seems most people are aware of this and have implemented some mechanism to avoid it, being .gitignore or using an env variable, and a SecureRandom or otherwise generated string for development.
I feel like this is knowledge that should be limited to people who can figure out to do it. I'm not sure it's valuable to widely and easily disseminate this information to the world.
Why is this information stored in a cookie the client has access to? Why doesn't ROR have a shared secret so the information can be stored on the server like, for example, PHP does?
For stateless load balancing without a central server. By having the data in a client cookie so that any web server can access it. Without it you need sticky sessions on your load balancer or a central data store requiring additional round trips for each request. A lot of frame works use the same principle (ex: Django uses it too).
The data stored in the cookie is cryptographically signed with the secret token so the server can verify if its been tampered with. It's a very solid approach but like anything involving crypto it's important to keep the secrets secret!
To clarify, the secret token should only be known to the server. The client doesn't have it. The client only has their own signed cookie data.
So you're telling me the official rails policy is: we think you (developers) are smart enough to build an app that works on a distributed cluster but aren't smart enough to work out how to use a central/replicated system for session storage.
At the very least cookie storage should be an opt-in for apps that need it, not a default with apparently not enough warnings about the security aspects
Course none of that makes it acceptable (it's atrocious!). This is a perfect example of why code and config need to be kept separate[2]. If you have that as a mantra from the beginning then you don't have issues like this.
[1]: In reality you should change your secret token regularly. The best approach is to accept a rolling window of old ones so you can age them out. Then you can pick how far back you want to support (eg. how stale a client's cookie can be).
[2]: http://12factor.net/config