Protection against CSRF

Monday, 20 August 2007

It’s quite difficult to protect against CSRF because you are performing actions on the attackers behalf, there are a couple of things you can do to help protect against it and I shall explain a couple of methods here.

Form tokens

Form tokens can be used to make it more difficult for an attacker to perform CSRF, an explanation on form tokens is available on a previous post. Using one will not make your site 100% secure against CSRF but it will help. Make sure a form token has a short expiry date, only valid for the user in question and is not sent using GET.

Random page names

When a user signs up to your service they can each be assigned a random URL which they use to perform any action. The random URL should only be available per session and should only be created when their username and password has been supplied.

Authentication

Asking for a username and password should always be done for sensitive operations, if authentication is required it makes it much more difficult for an attacker to manipulate a user’s actions without a valid password.

Frame breaker

They are very old school but can be very effective in protecting against iframe attacks.

if (top != self) {
top.location.href = 'http://yoururl/';
}

Damage limitation

Amazon understand this very well and have designed their delivery system this way. For example if an attacker did manage to perform CSRF on a Amazon user to buy a book for instance, the attacker could only deliver to the user’s assigned addresses. Even changing a delivery address requires credit card confirmation. This is good system design and provides good damage limitation.

The entry 'Protection against CSRF' was posted
on August 20th, 2007 at 4:05 pm
and last modified on August 20th, 2007 at 9:04 pm, and is filed under php, Security.
You can follow any responses to this entry through the RSS 2.0 feed.
Both comments and pings are currently closed.

What you call is authorization is actually authentication. These are often confused. CSRF is very effective at bypassing authorization checks, because an authorized user is sending the request.

The way Amazon references addresses makes CSRF practically impossible if you want to send the item to one of the user’s existing addresses. An exploit that does this has never existed to my knowledge, although it could be done with XSS. The CSRF vulnerability I discovered only worked on new addresses, and it required multiple forged requests. This particular exploit has been addressed by requiring re-authentication prior to adding a new address, a step that did not previously exist.

Ah I was planning an article as well, only I have 20% ready yet I’ve wrote about it before, but this will be a big article on CSRF and probably will be my last since it will mess everything up, and break the interwebs as we know it lol

Why a request and user unique form token, if properly used, does not provide 100% protection against CSRF?

What I am thinking of is:
1. When you generate the form, you add a hidden field with a random generated string.
2. You put that string into $_SESSION as well.
3. When the form is submitted you try to match the token value from the form with the one in $_SESSION
4. You only allow the form to be processed if the tokens match
5. Whether they match or not you never reuse the same token again – you generate it when you generate the form.

I might be making a complete fool out of myself right now, but I seriously try to think of a way to bypass this protection and I can’t.

I shall be creating a CSRF demo today which will include protection against all forms of iframe attacks (even with security=restricted). The demos will include form/url tokens and a combined demo which includes all techniques.

#7 Shahar: An attacker opens the form on the victims side (e.g. with xss), parses out the token (which is valid, cause the form has just been opened, the token was generated, saved in that $_SESSION and placed in that hidden field) and voila. Just imagine the attacker being a person who is sitting right in front of the victims PC. All you need is XSS and CSRF.

@Gareth:I shall be creating a CSRF demo today which will include protection against all forms of iframe attacks (even with security=restricted).
Looking forward to it?
The M$ page on “security=restricted” says that you still have access to the DOM of the restricted frame. Did you play with the DOM for it?

Just curious, how are you generating the javascript code to create nonce?

One more thing. Pdp had suggested using cookie value as the nonce in his essay. Even if we are paranoid about not allowing cookie value to be cached in the browser (and other similar issues), wouldn’t a simple mutated form of cookie value be an equally good nonce?

Cookies could be used here. You could execute javascript and then assign the cookie that would work and that’s how my comment spam plugin works. But I wanted a method without cookies, I like a challenge 😉

In fact if anyone wishes to expand my javascript/php generation class let me know and I’ll include the update on my blog with credits.

I find the whole security=restricted thing very interesting because the feature is also a security hole and to protect it you create a catch 22 situation e.g. You need javascript to execute the token, you need to stop javascript to prevent the frame breaker 😀

I find the whole security=restricted thing very interesting…
Same here.
There’s one more thing that I’d like to ask. Considering that the src inside the restricted frame is executed as “a site in IE’s ‘restriced zone'”, which means that javascript is disabled (unless it breaks out of the window, of course), can you think some attack other than Phishing the end user.

It’s hard for me to provide you advice without knowing the details of your system but I’ll have a go…

I would say enforce a password which would solve any CSRF problem. So for example if you are accept a site request on your OpenID provider site do not allow a user to save the password. Make them enter the password on each request. The only way an attacker could exploit this is to either send the valid password or ride the user’s session.

Let me know if that helps or please provide me with a brief description on how your site works and I’ll let you know the possible attack vectors and prevention.