Hacker News new | comments | show | ask | jobs | submit login
Reminder: secret_token.rb is named so for a reason (biggestfool.tumblr.com)
53 points by Ryoku 1815 days ago | hide | past | web | favorite | 55 comments

Wow. Please, please tell me that these are just hobby projects which have this happening. I can understand a beginner who doesn't understand git ignore doing this, but if there are people building products with this ignorance, that is troubling. I can see why a lot of greybeards hate frameworks, because someone who builds web apps with a much more bare bones framework, (Sinatra, Webapp2, Express, etc) most likely understands the fundamentals of encryption/hashing simply because of the fact that lighter frameworks require understanding the fundamentals in general.

This isn't to say that a developer for one of these frameworks couldn't easily overlook adding the files with secret_tokens in them to the .gitignore.

I could see lots of people doing it, only because Rails auto-generates the secret_token.rb file -- it's easy to just not think about it, forget it exists, put your whole source tree in the repo -- remember to keep database passwords and such out, but not ever even think about secret_token.rb, it just ends up in there.

Rails does the right thing by putting the secret token in it's own file that's even _called_ secret_token.rb (it could have just jammed it in the middle of config/application.rb or something instead, where it would be even easier to miss and/or not realize it should be kept private). So I don't know it's people who don't 'understand' it -- whether you understand it or not, the file is named "secret_token", if you actually look at a file listing and think about "should this be kept secret?", the answer is obviously yes even if you know nothing.

But... there's still a lot going on, and it's something easy to forget about, since you ordinarily _never_ need to think about the secret_token.

A file named "secret_token.rb" looks to me like "ruby code to operate on secret tokens", just like a file called "sha256.rb" would be expected to compute hashes, not contain them.

Should have been called "secret_token.yml". Should live in the config, or even better, a "secret_config" top level directory, not a subdirectory.

yeah, that might be an improvement, that perhaps should be considered since it's clearly a developer usability problem.

But I think it's not unreasonable to have expected it was clear that ./config/initializers/secret_token.rb was a file to initialize a secret token, that included a secret token in it.

> I can see why a lot of greybeards hate frameworks, because someone who builds web apps with a much more bare bones framework, (Sinatra, Webapp2, Express, etc) most likely understands the fundamentals of encryption/hashing simply because of the fact that lighter frameworks require understanding the fundamentals in general.

Usually what ends up happening is people build less secure systems because they don't understand those basics. Giving people less tools don't equate in them building better solutions on their own.

I consider this in the same realm as storing passwords to plain text. People do it out of ignorance until they're learn the hard way not to (or some kind soul saves them from that disaster).

How is this not considered a framework bug? "Secret tokens" are project-specific configuration more or less by definition. Putting them in something that lives in a source directory is simply asking for this kind of mistake.

Rails deployments aren't leaking their ssh keys or database content because that is stored separately. To paraphrase the title: these things are stored separately for a reason.

Get this thing out of the source, guys.

database.yml is also placed in config-directory.

secret_token.rb is placed where it is, because it is a initializer.


How is "because it is a initializer" a response to the point? The fact that it is implemented as Ruby code has nothing to do with whether or not it should be stored in a source code directory. Clearly it should not. Yet it is. That's a framework bug.

It'd be nice if github would suggest adding secret_token.rb to .gitignore when it's uploaded.

No thanks. The last thing I want is my version control host getting opinionated about my application domain.

Care to elaborate on why?

Github's tagline is currently "Build software better, together." Wouldn't this help people create better software?

I'm not saying they should automatically add secret_token.rb to gitignore, just that they could let you know you might not want to do that.

I don't think the answer is having GitHub do anything about it. The word has to be spread, yes. But not that way. Developers need to know about the importance of all their files and their security at development, else just think of what will happen when GitHub is not around or when they use another form of Git, etc. Problems need to be solved from the root and that means teaching developers to be more security aware, not making tools that will make said awareness easier to forget.

But wouldn't this be teaching developers? They upload the file and Github explains to them that it should be kept secret, and the developer has the opportunity to revoke the file. That sounds like the ultimate way of 'spreading the word', and if Github does disappear, they will have made people more aware. Not to mention it won't affect people who have been doing this all along.

Out of the 3000 repositories which I estimate to be affected by this issue (using Google and eliminating some common techniques used to circumvent the problem), I estimate 1600 of them are not on Github. Even if Github does its best to remove the issue completely, I don't believe it will have a huge impact.

I believe that a better idea is to fix this in Rails. Why is a secret key loaded from the configuration directory? I agree with ajross's comment (http://news.ycombinator.com/item?id=4970347).

This isn't to say that Github should do nothing to control the problem, but more must be done than just that.

Warning half of the project owners/maintainers that this is a problem won't have a huge impact?

Well yes, it could be teaching developers. But you would be teaching a single solution for a single problem. I think it would be better to entice solutions that target the bigger issue on security awareness. All this new tools that make it so much easier to develop complex applications have huge benefits, but I believe they are also pushing new developers away from understanding the concepts behind what they are doing. As someone who started as a designer and grew on my own into development, I've seen this issue first hand.

`rails new foo` generates a `.gitignore` file. That's where this belongs.

Not entirely, because you do need the file to startup your application. Which makes it a concern that should be checked in imo.

Just not publicly viewable

"Checked in but not viewable" is called a private repo.

If it's a public repo, don't check it in. I don't think Github should try to create a manifest of all "dangerous" files.

Really, best practice is to not check in sensitive values to your repository, ever, and instead use environment variables or symlinks to shared files via Capistrano to set these values in your application.

What if they just gave you a onetime warning instead?

I like this game: What if that annoyed the pants off some people?

I think beering was following the old adage:

you can annoy some of the people all the time, or you can annoy all the people some of the time. You can't however annoy all the people all the time.

Then they should surely add it.

People so easily annoyed by trivial (yet potentially helpful) things should be annoyed as much as possible by the rest of us.

You're kidding right?

Maybe not so intrusive, but they could add it to https://github.com/github/gitignore/blob/master/Ruby.gitigno... . Not sure how many people use that repo tough.

Version control being hard-coded with an exception for a particular framework of a particular language... I see the benefits, but I am deeply wary of it. What if the filename changes in the future? Does GitHub somehow have to detect versions?

I'm not sure if you're joking. Ruby on Rails projects aren't the only ones that have files that shouldn't be made public on GitHub.

GitHub will already generate a .gitignore file when you create a repository on its website. It would be nice if the .gitignore file was based on the type of project being created. And it would be nice if it gave a warning when files that are in the default .gitignore were being pushed to the repo.

If the filename changes in the future, who cares? It defaults to the current situation where no warning is given, but potentially improves security in many cases. And it's not a big deal to add another file to a list.

GitHub will already generate a .gitignore file when you create a repository on its website. It would be nice if the .gitignore file was based on the type of project being created.

Right, but how does it know that? There is no "Create Ruby on Rails project" command in git. How will it know what to include? Will it have to scan and somehow detect that it's an RoR project? And check the version of it?

Much simpler to leave this stuff to a RoR-specific tool. Maybe the .gitignore should be a default file when creating an RoR project.

I'm not sure if you're joking. Github is Git as a service... it's not in the business of software best practices.

Are you suggesting that Github starts tracking all major frameworks, all versions of said frameworks, and the files that should maybe not be version controlled within each of those frameworks/versions?

Or rails could suggest additions to .gitignore (and equivalents for svn).

Or,since we're proposing changes to Rails* how about the Rails people fix it properly, and put the configuration somewhere outside the source tree?

*(which is much more sensible than proposing changes to git/github in response to a Rails default configuration problem)

Would be even better if secret_token.rb's data was kept in the database.

Note that this was published back in May 2012, so it's not entirely recent (which is OK, just thought I would note it). However, this seems to have been public by February 2011 (http://stackoverflow.com/questions/5132152/when-you-have-sec...). I don't think the issue is entirely widespread, and a different key is likely used for production.

Yes, it is an old issue, the problem is that it's still there. Developers keep doing it for production, it is common knowledge for people involved in security, but not for developers, which is worrying. Take a look at this results http://www.lmgtfy.com/?q=inurl:secret_token+filetype:rb#

I have no problem with old issues or vulnerabilities being posted, of course, especially when they are very widespread such as in this case.

Note that not all of those results are necessarily vulnerable, for example, https://github.com/hotsh/rstat.us/blob/master/config/initial... loads the secret key from the environment, and https://github.com/GreenplumChorus/chorus/blob/master/config... loads it from an ignored file (like the article). I would estimate the real number of projects to be somewhere less than 3000, with about 1400 being on Github. This also assumes that these are all actually production keys.

Just to reiterate, I do believe that this is a legitimate problem even now, but I just wanted to note the age of the article and to refute the claim that this is the first mention of the issue.

What is the advantage to hashing a user id and storing it in the cookie over simply generating a random session code and storing it in a db table against the user's id and then checking every request? Is the overhead of an extra db read the only reason people don't do this? (Honest question, not trying to be smart)

Well, in order to protect the hashes in said cookies you would end up doing something similar to prevent malicious users from just spoofing them. If you use id/hash tables the way you propose the hash is acting just like an id and is then vulnerable to the same issues. The problem is not that the id is there, but that you need a method to make it hard to spoof.

No, you have mosunderstood me. I'm NOT storing a hash in the cookie. Instead im storing a random string. Because this string is random, there is no way that a malicious user can guess what the session code will be for a particular user id.

> Is the overhead of an extra db read the only reason people don't do this?

Yes, and using secret_token.rb is also way faster.

that would couple session to db. Play Framework, for example, is able to provide support for sessions using encrypted cookies, without having to provide adapters to all sorts of potential databases.

As hgimenez said, the best way is to not store your secrets in your source tree at all (12factor.net style). Keep them in the environment. Here's a great example:


Is that a good example? It doesn't warn if the env isn't set.

No, it doesn't warn, it raises an error and prevents the application from booting: https://github.com/democrats/voter-registration/commit/2fa87...

Why don't more people keep configuration / api keys / etc in the database?

1. Your configuration is backed up along with your data.

2. You can share configuration with multiple applications easily.

3. Use postgresql's LISTEN/NOTIFY to tell your applications about new configuration changes in real-time.

4. Your configuration is as secret as your data.

Where do you store the configuration for where and how to access the configuration database?

That's the only thing I keep as an env var (as DATABASE_URL: ie "postgres://monkey:pass@localhost/tanga_dev")

If you're vulnerable to a sql injection or something similar, though, then you've potentially made all of that data web accessible.

If you are vulnerable to sql injection, you are completely screwed anyways.

that's probably true.

We use the Figaro gem to setup ENV variables per project without messing with your system Path.

It also pushes your ENV vars to Heroku with one command. Pretty neat and simple.

In case you want to check it out https://github.com/laserlemon/figaro

Why doesn't rails add this to the .gitignore generated from `rails new myapp`? And maybe include a rake task to generate a new secret token. That's why I've been doing ever since I found out about this.

Because that doesnt solve the problem properly. Perforce users are still vulnerable, and Mercurial users, and (assuming any still exist) CVS users.

Secrets (keys, passwords, tokens, etc) don't belong in the source tree. If you put them there by default, one day you (or one of your users) is going to "forget" and be in a world of hurt.

I would argue this is even worse for Django projects. Django secret keys are in the settings file by default, which definitely needs to be put under revision control.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact