I was recently asked what is
secret key base used for in Rails applications and why not secure value of it (or even worse - the public one!) creates a security issue. That was a really good question, I remember how it was a serious threat years ago, especially before introducing
secrets.yml in Rails 4.1 - at that time by default
secret_token initializer was generated and the secret key was directly stored there. The result was that in many open source projects secret key was publicly available creating a great security risk. Let’s take a look how exposed secret key base could be exploited.
Anatomy of possible attack
current_user lookup in some application is performed like this:
1 2 3
user_id for storing id of the logged in user seems like an obvious choice. If I knew the
secret key base, I could try encrypting the following hash:
and send carefully crafted cookie pretending that I’m logged in as the user with id 10! The question is: how would I do it? Ok, maybe I have a
secret key base, but what exactly should be done with it? What are the necessary steps to generate such a cookie that will be successfully decrypted later by Rails application?
I was browsing through Rails source code and here’s what I’ve come up with:
1 2 3 4 5 6 7 8 9 10 11 12
This is basically how Rails handles encrypting the session data. The last thing we are missing is
session store key, which is not really a secret value, you can get one simply by using
And one of the headers will be in the following format:
_HackMe_session is our missing puzzle. Let’s try creating encrypted cookie based on our
malicious_hash and exposed
Assuming that there is some page requiring authentication which redirects to login page if user is not logged in, there are 2 possible scenarios: either user is authenticated and 200 HTTP code is returned or user is redirected with 302 status. To pretend that we are logged in we could perform the following request:
As a result you should see
HTTP/1.1 200 OK, which means you’ve successfully bypassed authentication :).
As you now know, having secure and securely stored
secret key base is an essential thing for the security of the app. Rails applications are now much more secure by default than it used to be and seems that accidentally exposing
secret key base is not likely to happen. Nevertheless, it is still a very important thing to be aware of.