top | item 22243816

(no title)

atom_enger | 6 years ago

I remember reading this when I was the sole Infrastructure Engineer for Reverb.com. I knew we were being attacked and I knew we had issues but I didn't have any idea where to start. This article sparked my interested in Cyber Security and helped me find a bug in the website that allowed me to set the CEO's credit card as a primary card on my account in production. That was an amazing day.

All I had to do was modify a post parameter in flight and the backend would accept it. Turns out this is what is known as an "unscoped find". More info here: https://brakemanscanner.org/docs/warning_types/unscoped_find...

Thanks to the author of the article for inspiring me to dig in the rails codebase and find vulnerable patterns that I could exploit. Thankfully I was able to pivot into a cyber security focused career and I credit this article for starting me down that path.

Rails has a few things going for it that other languages and frameworks don't but it still lets you shoot yourself in the foot if you're not careful. I ended up writing a blog article about preventing XSS in rails as a direct inspiration from the OPs article: https://product.reverb.com/stay-safe-while-using-html-safe-i...

Just because this article is old doesn't mean it's not useful. Thanks for posting!

discuss

order

Polylactic_acid|6 years ago

The unscoped find issue is fairly easily solved by using devise's current_user in combination with something like cancancan. Let them send anything as a param but have the controller blow up if the user doesn't have permission to access it.

I suspect an insane number of websites are validated only by the frontend and can be exploited like this.

atom_enger|6 years ago

You'd suspect right :) I've had a huge number of bounties from this as a result of finding the pattern first on Reverb.

greenie_beans|6 years ago

Can't this be solved with scoping via the pundit gem, as well?

mytailorisrich|6 years ago

It should be said that an "unscoped find" is a generic and serious design flaw, which isn't specific to Rails.

tptacek|6 years ago

In practice, XSS is largely mooted by the rise of front-end frameworks like React, Vue, and Angular, which are the modern norm for delivering UI (I don't think we have a single client that uses serverside-templated-HTML anymore), and the front-end framework approach is better than the Rails/Django approach; I'm very unlikely to find XSS in a simple React app, but not at all unlikely to find it in a Rails app, because people always dip out of the XSS protection to do programmatic tags.

adrianmsmith|6 years ago

I think making the mistake of "unscoped find" that "atom_enger" was referring to is just as easy a mistake to make when writing a REST backend (to support a SPA front-end framework) as when using a traditional non-SPA web framework.

It's tempting, when writing a REST backend, to respond to e.g. "PUT /message/:id" by just executing "UPDATE ... WHERE message_id=?" from the parameter, without checking that that message belonged to the user whose credentials have been used to access the call.

That's possible with a non-SPA web framework, and it's also possible when writing REST backends.

seisvelas|6 years ago

> I'm very unlikely to find XSS in a simple React app

I do offensive security. A lot of developers are ignorant of when/how React apps tend to be XSS vulnerable. Since it has a reputation as being 'safe' from XSS, devs often assume it's just something they don't have to worry about.

This has led to a small renaissance of XSS bug bounties on sites like hackerone, where you see a lot of specialists who just go around finding obvious, common XSS vulns in eg Angular apps.

greenie_beans|6 years ago

Thanks for sharing this. I'm new-ish to web dev and have considered a similar pivot. Also a customer on Reverb so that's cool to hear your story and read that write up you linked.

peteforde|6 years ago

Don't get me wrong: I'm really glad that you caught the bug in your code before anyone lost an eye.

However, a critical summary of your situation could be "improperly used an advanced method that exists for the specific purpose of marking a string as having been certified safe, potentially allowing an XSS that would have otherwise been successfully filtered out by Rails' extensive anti-XSS mechanisms".

I was super upset when one of the drives in my RAID 0 set went, but it was still my bad for not learning that RAID 0 isn't mirroring. (Hint: the 0 is the amount of information you can recover in case of failure.)

My point is just that you can't really claim that Rails dropped the ball here. If there are footguns installed, it's because you installed them (and didn't read the manual for html_safe).