4 ms·
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 fr
by 100k 18y ago
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.
- tptacek 18y agoRails is no more vulnerable to XSS than any other web stack; I pay for my dev team by looking at apps all day, and they all have this problem. You're right that taking positive action to neutralize metacharacters is a weak design. There is a setting in Rails, IIRC, that automatically h() filters outputs, but it should be the default. Just as importantly, though, even if h() is the default, you still have to audit all the places where you deliberately allow HTML output, and every app has to do that somewhere. I'm not disagreeing with you, but I am saying that there's a major difference between mass-assignment, which is a problem Rails seems to have blundered into, and XSS, which is endemic to web apps.
- 100k 18y agoThat is not true. Django and web2py both escape HTML output when variables are displayed, broadly neutralizing this attack by default. Developers in those frameworks must explicitly say that they want to display HTML in order to have it displayed. Presumably, they have thought about this and also taken action to remove bad HTML from this output. When you have to make a choice to display it, it makes you think about this. There is no setting in Rails to automatically escape HTML. There is Erubis, which is a replacement for Erb that can do it, and there are some XSS plugins that escape input on input or output. I'm saying escaping HTML on output should be the default for the framework.
- litewulf 18y agoI would actually say Django has a very poor HTML escaping facility. (Though, better than Rails, for what that's worth.) I feel like I've used template languages that actually understand XML (or HTML) and thus have context sensitive escapes. It was probably written in something gross like Java, so URLs were output verbatim in links, while say instances of "/search?q=" + someVariable would url escape someVariable in links, and html escaped in tag contents.
- tptacek 18y agoI don't think you read my comment carefully. The difference between XSS "susceptability" between Django and Rails is one setting (safeERB, sanitize, etc). Yes, it's a difference. I don't think it's a particularly meaningful one, because Django autoescape doesn't actually stop XSS attacks, just the stupid ones. There's a big religious debate inside the Rails community about autoescaping, which ran aground on the point that autoescape doesn't actually stop XSS. I agree with Rails, but concede that reasonable people could think otherwise. It's hard to see how reasonable, well-informed people could think that mass-assignment was a good default feature.
- simonw 18y agoCan you give an example of an XSS attack that isn't prevented by auto-escaping (other than the UTF-7 one)?
- tptacek 18y agoAll the attacks that occur in the outputs that you can't auto-escape, because they need to contain HTML by design. It's not the "escape" that's the problem, it's the "auto".
- simonw 18y agoGotcha, the HTML sanitization problem. Django doesn't even attempt to solve that, which is probably a bad idea since it inevitably means people will use the various insecure libraries that are out there on the 'net. The trouble is it's /really hard/ to do right - I'd be uncomfortable shipping a sanitizer with Django because I'd worry that some weird undocumented IE parsing error would allow nasty code to slip through and result in a 0-day exploit against the entire framework.
- simonw 18y agoI'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/ 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.
- mtw 18y agowhite_list is a better option, imho
- 100k 18y agoYup. 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.