

Is your Rails application safe? - jon_dahl
http://railspikes.com/2008/9/22/is-your-rails-application-safe-from-mass-assignment

======
tptacek
This is one of the _major_ security design flaws in Rails, and this is a good
article on the problem. What's worse is that the correct design is "folk
wisdom" in the community (for instance, a 37Signals dev is never going to make
this mistake), but the best-known Rails sample code is all vulnerable.

Every other web stack has this problem in one form or another; for instance,
in J2EE, which is either the first or second best-secured web stack out there,
you can bypass the best-known best-documented access controls by changing your
HTTP verb from "GET" to "SUPERGET", "GETX", or "GIMME".

But Rails kind of went out of its way to win this particular vulnerability,
and so now it's something you have to audit for on every project.

~~~
100k
The other security design flaw of Rails that drives me nuts is that it is
vulnerable to XSS attacks by default because it takes positive action to strip
HTML from user input.

I believe that security should be the default, automatic choice, and you
should have to take an affirmative step to disable that when you need to.

Rails does get a lot right with automatic cross-site request forgery
protection and nearly automatic SQL injection protection but the lack of
automatic HTML stripping and the default accessible attributes thing makes me
sad.

~~~
simonw
I'm very skeptical about the value of stripping HTML from user input - what if
your site is a forum where people discuss HTML? Or a site where people might
want to talk about the <head> conference? <http://www.headconference.com/>

Stripping HTML on input also means you lose the ability to audit attempted
attacks against your site.

A much smarter strategy in my opinion is to escape everything on output. That
way it doesn't matter what people submit to your site - unless you explicitly
say "this is safe to display unescaped" in your templates harmful characters
will be neutralised.

~~~
100k
Yup. I am suggesting escaping HTML on output (of user input) by default --
making h() the default, essentially.

(Incidentally, the reason why this will probably never happen is that it would
break all of Rails' HTML helpers.)

There are several frameworks that do this already. Django even broke existing
apps to make such a change.

~~~
tptacek
This only stops the "hello world" attacks. Be careful not to give the
impression that Django "solved" cross-site scripting; they clearly haven't.

~~~
simonw
Any suggestions for other things we could be doing?

------
mhartl
Thanks go out to Eric for this article, which led (among other things) to
fixing some important bugs in Insoshi. You can find my companion post on
fixing Rails mass assignment problems here:

<http://news.ycombinator.com/item?id=311533>

------
MicahWedemeyer
I never even knew about attr_protected / attr_accessible until I saw them
being used in acts_as_authenticated.

Come to think of it, I learned a lot of good practices from AAA (and
restful_authentication). attr_protected, salted/hashed passwords, and several
other nifty tricks.

------
cosmo7
The problem isn't that rails is insecure (it is, but that isn't the point.)
The problem is that rails by definition attracts developers who don't really
like developing.

If the entire USP of your platform is that it cuts corners you'll see it put
to use by people who either don't care or don't know any better.

I'm not saying there aren't good rails developers, but in my experience they
are a minority.

------
lpgauth
Doesn't protect_from_forgery solves this? I'm pretty sure when I tried using
curl the other day I was getting a message error message because the form was
missing the secret.

~~~
100k
That's to protect against cross site request forgery. This is setting
sensitive attributes via post. If a post has the authentication token, it can
still set sensitive attributes.

