It didn't help. Now I want people to take the issue seriously. This is a huge unsolved problem.
Developers have a tool which they don't know how to properly use. So they use it how they feel convenient. It leads to security breach. Reminds mass-assignment bug (sorry, i have to mention it every day to feel important)
How it works?
Attacker redefines RJS function(s), asks authorized user to visit specially crafted page and leaks data (which the user has access to) and his authenticity_token. Very similar to how JSONP works.
<script>
var bcx = {progress: {}};
var $ = function() {
return {prepend: function(data) {
window.data = data
}}
};
</script>
<script src="https://basecamp.com/2474985/progress.js"></script>
If it has any HTML form in it (especially when people use render_to_string), it also has user's authenticity_token automatically.
So RJS leaks 1) authenticity_token 2) a lot of private data. Thus the bug is as serious as XSS (can read responses + can craft proper requests). = must be fixed?
Some people are +1, some found it "useful in our projects" (=vulnerable), also DHH is against my proposal:
Not only are js.erb templates not deprecated, they are a great way to develop an application with Ajax responses where you can reuse your server-side templates. It's fine to explore ways to make this more secure by default, but the fundamental development style of returning JS as a response is both architecturally sound and an integral part of Rails. So that's not going anywhere.
What's left to do? Demonstrate with full disclosure: Gitlab, Redmine, Diaspora, Spree, Basecamp etc.
Gitlab: GITLABAPP/gitlab/gitlab-recipes/issues.js leaks authenticity_token, issues etc. Time to update.
— Egor Homakov (@homakov) November 30, 2013
Diaspora. Leaks CSRF token and private converstaions DIASPORA/conversations/CONV_ID.js Come on, you can't all be vulnerable?!
— Egor Homakov (@homakov) November 29, 2013
Redmine! We can leak REDMINE/boards/1/topics/quote/1.js iterate id to leak all comments. Sensible again, I guess? And token too, dig sources
— Egor Homakov (@homakov) November 29, 2013
Neeext, Spree! e.g. SPREEAPP/admin/products/new.js leaks admin's CSRF token and bunch of private info too. I'm necessary evil.
— Egor Homakov (@homakov) November 29, 2013
Even Rails creators get RJS wrong. https://t.co/8o2IUCyyFM leaks a lot of private data from your project. That's *sensible* huh?
— Egor Homakov (@homakov) November 29, 2013
And this is only a tiny part of vulnerable apps we have out there. Let's choose our next actions wisely:
- find a way to deny cross-site inclusion of JS templates, not breaking whole technique
- remove whole :js responder as an insecure technique
- don't not do anything about it
Is my app vulnerable?
If there are any .js.erb file under /app/views, most likely it is. Author of this article can perform a security audit for you, to make sure.