Tuesday, March 11, 2008

CSRF in Pills

| Armando Romeo |
I decided to put down few frequently asked questions about CSRF vulnerabilities after my recent efforts into securing joomla from this kind of attack. There is still a big part of the web app field who still has no idea about how csrf work, and even if they try to fix it, they do not understand it fully failing to cover all the mount points of such fascinating
attacking vector.


I'm not going much into details on what CSRF is since there are many good resources online where read about it and opefully understand it.

So why writing a FAQ? Well because I have seen too many pen testers failing to understand the real power of it not giving to it the right importance and weight CSRF should have into their vulnerability assessment reports.

Let's start :

How does CSRF differ from XSS?
In the end they are both Cross-site!
Well, no. There are more differences than what the name says.
I never liked acronyms. I would call XSS a script injection attack since this is just how it works.

With CSRF there's no script injection, at least for a basic and standard attack. Moreover CSRF doesn't require scripting or HTML to be successful.
A link is enough in a simple scenario.
Another difference is in the final goal a hacker wants to achieve. XSS in most of the cases is used to steal cookies or deface. CSRF is much more powerful. Basically it enables a hacker into performing a privileged
action on behalf of the victim. With the same privilege level of the victim. This leads me to the next question.

How is CSRF dangerous?
Dangerous. In my opinion more dangerous than XSS in most of the cases.
With the worst kind of XSS a hacker can manage to steal a session cookie getting into the victim's account.
CSRF doesn't steal cookies (once again in a basic scenario in which only CSRF is involved) but still lets a hacker perform a privileged action.
The privilege level is the same of victim's.

In the CSRF I have found in Joomla (and other web applications) a hacker was able to create a NEW super admin account.
This means complete portal compromise, this time not limited to session cookie lifetime.
Moreover a CSRF in the file management page let a hacker upload any kind of file on server. Shell says nothing to you? Server compromise, yes.

So basically, think of what a privileged user (being it a standard member or an admin) can do on a site and you get the danger level.

How stealth is CSRF compared to other attacks?
Well probably it is the hardest to track.
Sometimes it can get nearly impossible since there's no injection and it leaves
no traces into any logs.
Let's take the Joomla sample that fits well in our discussion.
To get a superadmin account a hacker would require to have a superadmin (Bob) visits a forged link or visits a malicious web page, or in general triggers
an url in whatever elite and evil way you can think of.
Bob, after triggering the forged url, won't notice any suspicious activity going on under his nose.
However, the forged url added a new superadmin using Bob's open session (if it is actually open) on his own portal. This means that on Bob's server log, the action will be recorded as taken by Bob himself of course.
Stealthness level can be increased using more sophisticated techniques but in general CSRF is not an attack held directly towards the
victim website.

The image below can clarify this furthermore.


How can I prevent CSRF?
This is the most frequently asked question that a security response team makes when you report such a vulnerability.
Before I give any explanation I usually forward them to the literature available. Since successfully fixing a bug is not a task you can do without understanding its nature.

The most obvious and common answer you find in literature is to use tokens.
I personally wouldn't look at tokens as the ultimate csrf solution since a token can be stolen (I'm working on this, and I should come up soon with some proof of concept).

So basically tokens are random strings (usually obtained by hashing some random number) that are generated for every form in a web application and inserted into a hidden form field. The token value is also stored into the user session variables set and the two are compared upon data retrieval when the form is submitted. If they match, pass. Else block the user from
performing the action.

This works well of course. And works well (actually it is the only solution I'm aware of) for those actions performed through HTTP GET method (the token is passed in the querystring).  So it's a decent solution for most of the cases
if token stealing code is not took in place (Which is something that requires a much more complicated attacking model and sometimes
hardly successful).

A solution I always propose is the use of captchas. Those nice images, invented to keep spammers away can come in handy to ensure that the request is valid and performed by the intended privileged user.
Even here a "good" captcha
should be used since there is a good research in this field and spammers are getting smarter and smarter with OCR techniques

So it's enough for this introductory discussion about CSRF. My research on CSRF will not end here and I will decide to write more on the topic according to audience attention and interest.

Free Security Magazines