Rails' Insecure Defaults
blog.codeclimate.com
blog.codeclimate.com
Seriously? So they've added a whole more complexity to the session-layer just because people abused it to store "secret" data? Newsflash: If you don't want the client to be able to read the data, DON'T SEND IT TO THE CLIENT AT ALL. Way more secure than encrypting it.
...even if a user’s session does not contain sensitive data, it can still create risk. By decoding the session data, an attacker can gain useful information about the internals of the application that can be leveraged in an attack. For example, it may be possible to understand which authentication system is in use (Authlogic, Devise, etc.).
Signed cookies with app name as key should be good enough for all purposes.
Besides, this only adds security through obscurity and doesn't actually make it any more secure.
If certain data being user-visible is a feature rather than a side effect, the session was the wrong place for you to be putting it.
[1]: http://api.rubyonrails.org/classes/ActionDispatch/Cookies.ht...
But yes, the default Rails implementation does not store the session on the server but a key in a cookie. Although you can optionally do that, storing the actual session data in the rdbms, or other server-side places. But the default Rails implementation, yes, actually stores the session info itself in cookies.
One of the benefits of this is, when you've scaled out/load balanced your app servers to multiple instances, they don't need to share a session store somewhere, they each get the entire session via cookie. There are also other disadvantages, including with synchronization.
But also including that your session data is now visible to the client when it wasn't before. So, yeah, encrypting the data is one way to change the trade-off calcuation and make it work for more (but not all) apps/use cases, why not?
It actually doesn't increase the complexity much. If you're storing session data in cookies to begin with, you already needed to crypto sign them, to avoid tampering. If you're involving crypto in there anyway, and a secret key anyway, might as well (as a configurable option, sure; which is the default configuration, why not) tell the crypto library to encrypt+sign/decrypt+verify instead of just sign/verify, why not.
‽
(interrobang ftw)
I'd also like to see secret tokens extracted from source code to something like an ENV var. I know a lot of Rails dev shops have a "Rails template" They use to start new projects, so beyond the Github issues the article mentions, I wonder how many projects have to same copy/pasted secret token.
I also appreciate the warnings about off-site redirects and hrefs with untrusted input.
Worse is the number of apps with the token in public GitHub:
https://github.com/search?q=%27Application.config.secret_tok...
Similarly for binding on 0.0.0.0. If you're running Passenger or Unicorn, this shouldn't be a problem. I don't know about other projects like Thin. But insofar as this is something the core Rails team has control over, we're talking about just WEBrick again, right?
Edit: Sorry if anyone thought this was supposed to be sarcastic; it wasn't.
and now, Thin?
Just because you can drive a car on the wrong side of the road doesn't mean it is unsafe.
On a semi-related sidenote all the recent Rails exploits prompted a heated discussion on the Clojure devs (the developers developing Clojure itself) group / mailing-list about an insecure Clojure default value.
Some devs realized that using exploits similar to the Ruby ones in YAML deserialization rogue code could be run on the Clojure webapp server if certain functions were used... And the argument to force the benevolent dictator to act was precisely that the Ruby issue basically turned into a gigantic endless mess of compromised systems and patches.
In Lisps it's all too easy (which is good) to read data and to eval it by mistake (which is bad): Clojure by default ships with read-eval set to true which is maddening. These aren't safe defaults and several webapps are vulnerable. Sadly as I understand it that default behavior is so relied on upon by everything in the Clojure ecosystem that Rich Hickey decided not to change it to false.
Instead Clojure ships with insecure defaults and big fat warnings in the documentation saying: "You should not use this function, use the EDN functions instead". And it is recommended that everyone sets read-eval to false. Still as far as I understand it even when read-eval is set to false some functions do still have side effect (in Java land) and could potentially be used maliciously.
That's the big problem: I don't understand it all because it's super technical (Rich basically told people on the mailing list they weren't qualified enough to discuss about what the defaults should be). All I know is that I'm supposed to set read-eval to false and also not to use read-string etc. but instead use the EDN functions.
And then I guess "cross fingers" because "we promise you this way you'll be secure". I only half-buy it but whatever, I do still love Clojure as of now.
I think it's really sad that security seems to always be an afterthought. The very rare projects I know of which were conceived with security as the main reason are OpenBSD and it's OpenSSH implementation (which is also into Linux etc.) and esL4 (a 7000 lines microkernel from which hundreds (!) of bugs have been found and eliminated using a theorem proover).
I can't help but dream of the day were devs are going to take security seriously and ship with safe defaults.
Probably not for this decade but the situation is getting so messy that I'm certain something shall be done at some point.
And while some here are busy "getting real things done in PHP and Ruby" (which is great as long as you're not diminishing others), I want to thanks all the devs working on torny security issues and thinking about security from the start. Like all these Ph.Ds working on theorem provers etc.
If I had bothered to look at the actual YAML deserialization code it would have immediately looked unsafe. Unsafe code standing out is necessary but not sufficient. It should also be difficult for something to wrap that without you have a clue that it's going on.
As a more extreme example, this language/framework is designed to statically guarantee that you can't suffer from most web vulnerabilities - http://www.impredicative.com/ur/ - but if you want any complicated libraries, they need to be C (or linked through a C shim), which may not be the most desirable.
It's seL4 (secure embedded L4). I'm just pointing it out in case someone else is interested in "miceokernels that are formally verified", like a friend of mine who is obsessed with seL4. If you google "esL4" you'll get completely different results so I though I'd point that out :)