Tuesday, April 24, 2012

"match" in Rails and CSRF


Related:
CSRF afterparty & MUST READ rules
Playing With Referer & Origin + disqus.com and yfrog.com Vulnerability)


Sometimes developers use GET for state-changing requests by purpose. This determines low-skilled developer. In this post I want to describe another vector of attack - GET Accessible Actions(GAA) - when framework abstractions + bad practices make "Good Guys' apps" insecure.

There is a thing I found exploring DSL's and engines' internals - many frameworks do "dirty work" for developer - they merge GET(stored in URL string)+POST(stored in Body) params into one unified hash. IMO it's cool and awesome to use - "params" for Rails and $_REQUEST for PHP.

But! As I found out it often confuses mechanism of handling GET requests from others(POST-like - PUT/DELETE/etc).
Same "state-changing" code is accessible via GET either, it is GAA, opening the easiest to use hole: <img src=URL/create_message?message[body]=SPAM>

Playing With Referer & Origin


(related: CSRF afterparty & MUST READ rules )


If you read owasp you should know that Referer has never been a good protection. If user submits form from https:// URL than referer header is omitted due to security reasons - it's known fact. But having https page is a big deal for hacker - very uncomfortable for massive attacks(rapidly banned/reported, expensive certificates).

I found a way(in fact two ways) to omit this header from any page - it is the trick with about:blank.

Monday, April 2, 2012

CSRF examples


Remark: Post is published on April 2(but was expected yesterday) coz Berlin haz no free wifi cause I'm not joking and I figured out that Sunday is the worst day for urgent updates. Well, who cares the date, enjoy:

TL;DR:

I'm trying hard to prove my point that statement "CSRF is only the developers' problem" is not true. I provided some examples and I want you to check them out. I really appreciate any viewpoint at this problem. Thank you for your attention in advance!

Friday, March 30, 2012

CSRF Is A Vulnerability In All Browsers

Navigation:
#1 CSRF Is A Vulnerability In All Browsers - You MUST Deny It ASAP.
#2 top secret(will be published on April 1)
#3 Another Rails Issue(April 2-3)
#4 The Webkit Hole(April 2-4)

It took me a long time to understand the point behind CSR (cross-site requests) and CRSF fully enough to find them EXTREMELY malicious.
Following points should be made before any explanation.
  • It is well known attack(yep, just like mass assignment). It's known but not well. You won't find any mention of CSRF in books for beginners a la "PHP in 24 hours" or "HTML/CSS for dummy". Underestimated kind of attack.
  • It is neither bug in OS nor in browser nor in the servers' adjustments. Linux/Mac/Windows, Chrome/Firefox/IE - it just doesn't matter! This is just an expected behavior. And it works like it supposed to. Funny, isn't it? Known since 2001 but not fixed yet. Interested? Keep reading.
  • HTTPS? Would not help. SSL has nothing to do with this attack.
  • Short sessions? Sounds nice, but there are always a few ways to ask/force user to sign in and than script can attack. We are human, it's not so difficult to cheat on us. And, short sessions are rare, most sites with a "remember me" button do not rely on short sessions.
  • Special plugins/extensions to be secure(e.g. https://www.requestpolicy.com/). Who uses them?! O_o Almost nobody.
  • Protection on server-side. Rails 3 framework has it out-of-box - using authenticity_token helps. By the way Rails is the most secure framework I've ever seen.(sic!) Mass assignment is "vulnerability" in the documentation and developers are in charge; but not in rails. At the same time to have protection with other langs/platforms(PHP, Java, Asp.net) you have to write ~10-50 additional lines of code. IMO(and *these cases* prove it) 90% of developers just don't care and don't spend time on that. That's a huge hole, easy to find and easy to use.

Sunday, March 4, 2012

Hacking rails/rails repo

So I commited in rails/rails repo

I simply added a <input value=USER_ID name=public_key[user_id]> field to Public key update form, where USER_ID = 4223 (from https://api.github.com/users/rails).

Backend didn't whitelist accessible attributes and had something like this:
@key = PublicKey.find(params[:id])
@key.update_attributes(params[:public_key]) #Oh no! We passed public_key[user_id] of our victim!

Now our victim (Rails) has our public key associated with their account. You can read/write in any public/private repo on github.

Thoughts on this from 2014: 
it was one of my first hacks and I didn't know how to behave. I was angry because nobody wanted to take me and mass-assignment issue seriously. After I did the commit this vulnerability was fixed on github within 1 hour and in rails within 5 hours. This was really effective, many people learned about the bug and fixed it in their apps, but I still regret about this irresponsible disclosure.