Live data from Hacker News

A Better Way to Manage the Rails Secret Token

daniel.fone.net.nz

31–40 of 60 posts

Re: A Better Way to Manage the Rails Secret Token

#31
post #6

> if Rails.env.development? or Rails.env.test? I hate code like this that is explicitly aware of the environment. The code says what it will do in an environment, rather than the environment saying what the code should do in it.

I had the same feeling. Inspired by this post, I just moved my secret token config into production.rb, test.rb, and development.rb, and deleted secret_token.rb.

Re: A Better Way to Manage the Rails Secret Token

#32
Your environment is not secure. The solution for this type of problem (keeping secrets out of source control) is to create a deployment-specific configuration file that is not kept in source control. It can be created out of a generic version that is kept in source control. Then, OS-level permissions are applied so the file is only readable by the processes that need access.

Re: A Better Way to Manage the Rails Secret Token

#33
post #5

I wish Rails supported two secrets the way Rack::Cookie does by always signing with the first, but accepting either. That way you can rotate the secret without signing everyone out.

I'm surprised that it doesn't? gorilla/sessions[1] does the same; and you can eventually remove your old keys provided you keep your expiry times sane.

[1]: http://www.gorillatoolkit.org/pkg/sessions#NewCookieStore

Re: A Better Way to Manage the Rails Secret Token

#34
I don't understand why a secret token is even necessary. This seems like bad design. As a matter of principle, the server should never trust the client. If authentication is necessary, it should be done on every request. If that is the case, what purpose does the token serve?

The entire principle behind HTTP - what enabled it to conquer and dominate the internet, is its statelessness. Storing and trusting things in cookies is a fundamental security design flaw.

Re: A Better Way to Manage the Rails Secret Token

#35
post #32

Your environment is not secure. The solution for this type of problem (keeping secrets out of source control) is to create a deployment-specific configuration file that is not kept in source control. It can be created out of a generic version that is kept in source control. Then, OS-level permissions are applied so the file is only readable by the processes that need access.

How is the environment any less secure than memory? If someone can read or mutate your environment, you should assume your app is already compromised and OS-level permissions aren't going to do anything.

Re: A Better Way to Manage the Rails Secret Token

#36

> Knowing the secret token allows an attacker to trivially impersonate any user in the application. Worse. Knowing the secret token allows an attacker to trivially execute code in your application. Don't ever let your secret token become public knowledge, and if it does, you need to change it straight away.

Doesn't Rails use randomly generated session IDs? Also, how does it allow an attacker to trivially execute code?

Ruby (and rails) has atrociously insecure deserialization that you need to explicitly disable.

Re: A Better Way to Manage the Rails Secret Token

#37
post #28

Earlier quoted context omitted.

> If you're in a shared environment The common wisdom seems to be that you can forget about security in a shared environment regardless. The "secret key in environment variable" technique is mostly useful at protecting against malicious employees since it's easy to limit access to the production server but not so easy to limit access to configuration files which are in a Git repository.

While I generally agree, there's a lot of shared environment out there that people seem to think is secure. I also would posit that its probably easier to get the calling environment through some flaw in bad programming vs getting a file off the filesystem. I would also posit that not having strong controls on your source tree is probably not a good thing as well...

The only secure shared environments I would trust are jailed environments or virtualized OSes, and even then only if I could control the hardware. Even then there have been vulnerabilities which allow virtualized OSes to access the host system (and "sideways" into other OSes), meaning even something like EC2 is potentially vulnerable.

Don't trust your environment.

Re: A Better Way to Manage the Rails Secret Token

#38
A generic solution to this problem that I don't see mentioned is to have different configuration files for all of ones deployment environements (dev, test, integration....) and have an encrypted config file for production. All the config files go on source control so there are complete records of all changes. Then the key to decrypt the production configuration file is known to the build maintainer and also known by a dedicated build machine (maintained by the build manager). Doing things this way one can be as secure as one likes while at the same time, builds can be fully automated; builds can be machine independent (if you have a dynamic server environment or ever worry about losing a server), and builds have a complete change history in source control.

Re: A Better Way to Manage the Rails Secret Token

#39

I'm not sure I understand what dotenv does (or why you would need it to do it).

It loads environment variables from a .env file when starting your app so that you don't have to do $ SECRET_TOKEN=abcdef SOME_OTHER_VAR=hello rails s or pollute your .profile with a bunch of app-specific variables. You don't need it to do it; it just makes it easier.

Couldn't you just read the file directly? e.g.

    secret_token = File.read('secret_token_dont_check_in')
I fail to see how loading the file into the environment and then into the variable is anything but worse.

Re: A Better Way to Manage the Rails Secret Token

#40
post #39

Earlier quoted context omitted.

It loads environment variables from a .env file when starting your app so that you don't have to do $ SECRET_TOKEN=abcdef SOME_OTHER_VAR=hello rails s or pollute your .profile with a bunch of app-specific variables. You don't need it to do it; it just makes it easier.

Couldn't you just read the file directly? e.g. secret_token = File.read('secret_token_dont_check_in') I fail to see how loading the file into the environment and then into the variable is anything but worse.

The original issue is people checking their secret token files into their VCS repository and publishing that. Getting the secret token from the ENV means it probably won't be checked into the repo.
Post reply on HN