Friday, November 29, 2013

RJS leaking vulnerability in multiple Rails applications.

I wrote about this problem in May, without showcases, just a theoretical post

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.
  var bcx = {progress: {}};
  var $ = function() {
    return {prepend: function(data) { = data
<script src=""></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.

And this is only a tiny part of vulnerable apps we have out there. Let's choose our next actions wisely:
  1. find a way to deny cross-site inclusion of JS templates, not breaking whole technique
  2. remove whole :js responder as an insecure technique
  3. don't not do anything about it
Documentation is not an option. I wrote my RJS blog post in May, after half a year nobody still cares.

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.

Saturday, November 9, 2013

Use 404 or Lazy Tips to finding XSS

In my opinion usefulness of an XSS on a random website is next to nothing. What are you going to do with XSS on your local school website? Stil da kookies?
So either you should look for XSS on a major website or find tons of random XSSes in hope some of them will turn out to be any useful.

What is a Lazy technique? Only one GET request is required to check if there's XSS. Here are lazy techniques i have in mind:
  1. Developers don't spend much time on 404 pages. So there's >0% chance 404 page reflects unescaped input. The script above does simply GETs<img src=yolo onerror=alert(0)> and checks if the response body has the payload. Easy right?
  2. There are also 5xx errors, try playing with HPP (x[]=1&x[hash]=1) 
  3. Don't forget about 414 error (send super long payload). 
  4.<img src=x> for $(location.hash) might work too but you need to catch alert execution in runtime.
  5. please share other lazy tricks you know! 

So I took the first 1k of Alexa and apparently 10+ are vulnerable (wikia, rottentomatoes etc). The script is not perfect (if status code is 404 it doesn't check the body) — feel free to improve it. For 1kk output might be 10k+ of vulnerable websites having PR more than 1. PROFITZ.

Here you can take Alexa top 1 000 000 in CSV

And make some money. For (black) SEO purposes you can make the google bot visit<a href=//>GOOD</a> etc.
Also send some cheap human traffic on the XSSed pages and dump the page (with tokens in it) +  document.cookie to analyse / data mine it, hoping to find something useful.

So the recipe is simple: take that 1 million, create a lazy XSS pattern (consider more comprehensive patterns, ?redirect_to=..) then use the XSSed page for SEO / stealing cookies.

Completely hassle free way to find bugs. Oh, also check out the Sakurity Hustlers - Bug Hunters Top.

Wednesday, November 6, 2013

Stealing user session with open-redirect bug in Rails

Is open redirect bad for your website?
If we don't take into account "phishing", how can be open redirect dangerous? 
Mind reading because any redirect to 3rd party website will leak facebook access_tokens of your users. 
So innocent open redirect on logout will simply reveal access_token of current user when we set redirect_uri to Client/logout?to=3rdparty
That's really bad. Users won't be happy to see your client posting spam on behalf of their accounts. 

What about open redirect in Rails?
As I previously mentioned in my blog posts, Rails loves playing with arguments. You can send :back, or "location" or :location => "location" or ->{some proc} or :protocol=>"https", :host=>"" etc. So because of this line
redirect_to params[:to]
attacker has multiple ways to compromise the redirect.

1. params[:to][0] == '/' is not good protection, since // is a legit URL. (By the way if you use regexp avoid $^, luke)
2. XSS by sending ?to[protocol]=javascript:payload()//&to[status]=200
3. Discovered yesterday, we can see plain HTTP headers in response body by sending ?to[status]=1

Live demo on Songkick

Step 1, open with GET or POST params[protocol]=javascript&success_url[host]=%250Alocation=name//&success_url[status]=200

Step 2, user clicks on the XSS link and executes payload from window name

Step 3, payload parses broken HTTP response and leaks httpOnly session cookie[status]=1

Frankly, this bug is really common. I found it in more than 5 popular rails startups though I only started checking.
If you need careful security audit (or brutal pentest) of your app, visit