Skip to content

Instantly share code, notes, and snippets.

@jessieay
Last active September 20, 2016 22:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jessieay/25ac100206b9a40a191494fb4fc82d56 to your computer and use it in GitHub Desktop.
Save jessieay/25ac100206b9a40a191494fb4fc82d56 to your computer and use it in GitHub Desktop.
A GitHub lesson, and a Rails lesson (for Heroku and Cloud Foundry)

Lessons learned are enumerated at the bottom for those who want the tl;dr

Background:

Lately, I've noticed that the Rails app I am working on does this funny little thing where it logs everyone out every time we deploy. Sorry, ppl!

Investigation

I wanted to fix this, and so I went looking into our auth system. Turns out, we store the user's id in a session var and find the user based on that value. WHAT? You might say. Well..it is totally OK because my friend Rails encrypts all session vars.

To prevent session hash tampering, a digest is calculated from the session with a server-side secret (secrets.secret_token) and inserted into the end of the cookie.

(source: http://guides.rubyonrails.org/security.html#session-storage)

Nice! So now I have a lead on why my session variables are not valid after each deploy -- the secret that is being used to create a digest must be changing!

I looked into my app's config/secrets.yml setup and found this:

production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

Uh oh! I am setting my secret_key_base on prod with an ENV var that I never defined. Yikes!! But if that value is nil, wouldn't my session values be the same? Something seemed off.

I ssh-d into my app and inspected ENV['SECRET_KEY_BASE']....and it was present! A nice random string. But as far as I can tell, I don't have SECRET_KEY_BASE set anywhere. WHAT!?

I am deploying my app with Cloud Foundry, so I went in and searched for secret in the repo:

https://github.com/cloudfoundry/ruby-buildpack/search?utf8=%E2%9C%93&q=secret

Nothing!

I then saw that the ruby buildpack for cloud foundry is forked from Heroku. So I searched that:

https://github.com/heroku/heroku-buildpack-ruby/search?utf8=%E2%9C%93&q=secret

BINGO! https://github.com/heroku/heroku-buildpack-ruby/commit/41dd02b147674e6bb793e9ddb3df47601eae0655#diff-dddde8f81c4082ecb9e7ad850e11dfbdR30

Lessons learned

  1. The Heroku buildpack, which is the base of the Cloud Foundry buildpack, sets ENV["SECRET_KEY_BASE"] to SecureRandom.hex(64) if it is not already set in your codebase. Since this buildpack is used for each deploy and I never had ENV["SECRET_KEY_BASE"] set, it was setting a new value on each deploy, effectively logging out all of my users (because their session vars were no longer valid).
  2. GitHub search does not always return all results when searching the code of a fork. The word secret does not show up when I search the Cloud Foundry buildpack, but it shows up in 5 different files when searching the heroku buildpack (both on GitHub). Is this because there are no instances of secret in the fork that are unique to the fork? Or perhaps it just hasn't been indexed? I am not sure. All I know is that from now on I will be sure to search parent repos when looking for something in a fork on GitHub.

UPDATE:

Thanks to Laila Winner for pointing out that when you search a fork, it defauls to searching issues rather than the code itself. If you run this search of a forked repo and select code on the lefthand side of the page on GitHub, it will display a message indicating that " forked repositories are not currently searchable."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment