Proposal: Dynamic secret_tokens

74 views
Skip to first unread message

Bert Goethals

unread,
Mar 28, 2014, 11:02:58 AM3/28/14
to rubyonra...@googlegroups.com
Hi all,

Security is always a hot topic, and in our company especially. 
We where looking into the secret tokens. And we think we can do a step better than an "secrets.yml" file.

The fact is that system administrators still have access to the secret token, and that is not always acceptable. 
Replacing the secret token each time an admin leaves, is not a viable solution. So we fought, how about a dynamic token?

Proposing to make the token "callable". Besides being a string, the token could be a proc or anything responding to call, receiving the request object.
This allows the implementer to dynamically change the token.

This can be useful to have a separate token per domain, very useful in multi tenant applications.

If there is intrest in this, I'm willing to develop it as well!

What do you think?

Mohamed Wael Khobalatte

unread,
Mar 28, 2014, 11:29:23 AM3/28/14
to rubyonra...@googlegroups.com
This sounds great and would also helpful in updating Rails (I know updating is a breeze for some apps, but not always). 


--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-co...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.



--
Mohamed Wael Khobalatte

Michael Koziarski

unread,
Mar 28, 2014, 7:46:39 PM3/28/14
to rubyonra...@googlegroups.com
If you wanted to attempt support for a dynamic secret, you could give it a go, but I feel I should correct one thing.

Systems administrators will *always* be able to read your secret, there is *no* avoiding this, they can fire up rails console and run:

irb(main):002:0> Rails.application.config.secret_key_base
=> "f1a4df910e88f985dd555dd4ad0210b4cc8e9ca8306ab8ae29164d4c8874b5yesthisisrandomnoisenotmysecret6ad01ac7762ede919f5f5c513bf866654d1355"

Even if we tried to put in mitigations for this risk, there's always GDB.  So if you want dynamic secrets for some reason, give it a go and see how the patch turns out, but don't do it to make your secret 'admin proof', that's not going to happen.


--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-co...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.



--
Cheers

Koz

Dmitri Moore

unread,
Mar 28, 2014, 8:02:48 PM3/28/14
to rubyonra...@googlegroups.com

I think Michael makes a very good point. We trust our admins with root access, so I can’t imagine why we’d go extra mile hiding an app secrets from them when they are so powerful with root already. If I had a sysadmin that I couldn’t trust handling this token properly, I would never hire him in the first place. As long as the secret accessibility is restricted to an appointed unix group (e.g. “deploy”) - that should work, shouldn’t it?

Rodrigo Rosenfeld Rosas

unread,
Mar 28, 2014, 8:22:54 PM3/28/14
to rubyonra...@googlegroups.com

Not exactly if you use environment variables with secret settings using deployment tools like Capistrano.

But I also don't see why a system admin shouldn't be trusted...

Rodrigo Rosenfeld Rosas

unread,
Mar 28, 2014, 8:52:54 PM3/28/14
to rubyonra...@googlegroups.com
Forget about using environment variables. Those are the easiest to checkout if you're root in a Linux server for instance. I could easily read it in a quick test.

I'm curious though to see how easy would it be to use GDB to attach to a running application after the deploy script has removed the file with the key after the application has booted...

Michael Koziarski

unread,
Mar 28, 2014, 10:16:49 PM3/28/14
to rubyonra...@googlegroups.com
On Sat, Mar 29, 2014 at 1:52 PM, Rodrigo Rosenfeld Rosas <rr.r...@gmail.com> wrote:
Forget about using environment variables. Those are the easiest to checkout if you're root in a Linux server for instance. I could easily read it in a quick test.

I'm curious though to see how easy would it be to use GDB to attach to a running application after the deploy script has removed the file with the key after the application has booted...

Rodrigo Rosenfeld Rosas

unread,
Mar 29, 2014, 4:43:48 AM3/29/14
to rubyonra...@googlegroups.com

That specific approach wouldn't really work in this case as you'd have to restart the process with the shim in place but you wouldn't be able to because you'd be missing one of Rails required initializer, which contains the secret.

Maybe the admin would be able to install the shim globally, but if you don't really trust your admin you could create some kind of checksum of your system of and refuse to deploy if it has changed. Softwares like Bacula are able to do things like that. Then you could diff with your known state to see what has changed so that you'd know whether the changes are safe or not. Bacula has such a feature for instance.

But since this requires a lot of work, it would be much simpler to not keep employees you don't trust. There's much worse things system admins could do if they want to.

In any case I don't find it trivial to steal the secret from a running process.

--

Bert Goethals

unread,
Mar 29, 2014, 9:24:05 AM3/29/14
to rubyonra...@googlegroups.com
Valid point. However, security is never a 100%.

I do think that N secret tokens is a "safer" situation than just one.
Also note, that any future tenants would be safe from "remembering" the base token.

I'll give this a shot this weekend.

richard schneeman

unread,
Mar 29, 2014, 9:48:51 AM3/29/14
to rubyonra...@googlegroups.com, rubyonra...@googlegroups.com
I would rather have the system accept multiple tokens at one time so you can rotate them on a production server. This is easily something you could set up via cron and if an attacker gets a token it would only be valid for hours instead of days/months.

Heroku would love to rotate your tokens for you but right now we can't. When you serve a page and then change a token then any forms that page submits will be invalid to the next server with the new token.

Richard Schneeman


Bert Goethals

unread,
Mar 29, 2014, 11:23:15 AM3/29/14
to rubyonra...@googlegroups.com
I've been looking into this and it is possible, however I don't think it is needed.
I'm going to describe how it's possible in rails 3 and 4; and why I don't think it's needed in rails 4.

Rails 3: 

In rails 3 action_dispatch uses the secret_token that is added to the request env. This is then used by other parts of the application. If you want to make this dynamic it's as easy as changing the value of "action_dispatch.secret_token" key in the request env early in the middleware stack.

Rails 4:

In Rails 4 there is quite a bit more going on. Action_dispatch is now using: secret_token, secret_key_base, key_generator, http_auth_salt, signed_cookie_salt, encrypted_cookie_salt, and encrypted_signed_cookie_salt. Just like in rails 3 these values are fixed for the entire application. The "bad" thing here is that the key_generator is initialised once with either the secret_token or secret_key_base. Even if we change these values later with middleware the generator will keep using the values it was initialised with.

It's perfectly possible to swap out the generator on a per request basis, just like swapping the secret_token in rails 3. I have no idea what the impact of that would be, but I think it would be minimal. An alternative would be to change the salts per request. I think this could even be better than switching out the generator entirely; and can be easily achieved with some middleware.

I hope this info is useful for others!

Maybe we can explain this in the action_dispatch docs?

Josh Susser

unread,
Mar 29, 2014, 3:51:19 PM3/29/14
to rubyonra...@googlegroups.com
I'm neutral on the feature of dynamic secret tokens, but I'll weigh in on your implementation choice. Please don't use the callable approach for it. That's appropriate in a more functional language, but in Ruby, we'd like things to be objects and use semantically meaningful message names. The problem with passing around procs is that you can't tell anything about them - they are just procs, and calling them looks like like calling any other proc. A simple duck-type for secret tokens will give you more flexibility and make it easier for others to understand and work with.

--
Reply all
Reply to author
Forward
0 new messages