Thursday, February 8th, 2007

CSRF Protection Idea

Category: Security

Joe Walker has an idea for CSRF protection. Will it work?

There are several ways to forge a request in a CSRF attack: iframe, script tag, image tag, scripted etc. As far as I know XHR is not one of these, because cross-domain rules kick in before the request is sent and not when the reply is read.

Both iframe and XHR will allow you to construct POST requests, the other attack mechanisms are restricted to GET only. With the iframe method, you use some DOM scripting to create a form that points to an iframe. This implies that only form-formatted data can be sent over an iframe POST request.

So in the Ajax world, it might be possible to have a CSRF-safe application that works simply by insisting on POST, and denying anything that is application/x-www-form-urlencoded. Clearly this technique won’t work for non Ajax requests because it requires the browser to use XHR.

Posted by Dion Almaer at 10:00 am

3.1 rating from 28 votes


Comments feed TrackBack URI

I do this already (deny all GET, and the server tries to read in arguments as JSON) and never realized the latent security benefits of that. Excellent!

Comment by Reinier Zwitserloot — February 8, 2007

Forms can be submitted with the ENCTYPE parameter set to a value other than “application/x-www-form-urlencoded”. Most notably, you can set it to “multipart/form-data”, not sure if you can do others. Wouldn’t that break your safeguard? Or maybe it is possible to have custom encoding type that forms can’t emulate…
Also, I believe it is always good practice to insist on POST for all requests that have side effects.

Comment by Ajax 2.0 Developer — February 8, 2007

On IE and probably others, you can also use a plaintext enctype.

Comment by Ryan Breen — February 8, 2007

I’m sorry but WTF???

Ok, it rejects one form of submission but not the other? How the hell is that any more secure? Oh noes! I was about to hack this web app with a GET, but they want a POST….I guess I’ll go to another easier to hack site.

I’m sorry, but this just doesn’t prevent anyone who knows what they are doing…nor will it help developers who actually know how to program and filter out the bad requests.

Most of my web apps SPECIFICALLY allow for any request. Sometimes its easier to bookmark something if I use one as opposed to the other. is it just that the majority of the ‘web programmers’ out there have absolutely no real programming skills (I say after beating my head against a wall a week ago trying to explain to a friend how to prevent SQL Injection and not being able to get them to understand no matter how simplified I made it…luckily, they had a recent backup….)

Comment by clif — February 8, 2007

@Ajax 2.0 Developer: The idea was speculative – we have other CSRF protection in DWR. I’d not thought about ENCTYPE, but yes we would need to ensure that the format was not one that could be emulated from a form post.


Comment by Joe Walker — February 8, 2007

Bear in mind that just because a pure post can send whatever headers it likes, that doesn’t mean that a browser can do it in this case. I don’t know what the restrictions are on real-world browsers or if they’ll let you specify any kind of ENCTYPE and send it along blindly.

You don’t have to defend against pure posts from random hosts, but from a browser that’s been hijacked, and that somewhat limits their avenues of attack.

Comment by Dan Coulter — February 8, 2007

Joe – Couldn’t we set a header on the XHR requests that identifies that it came from our site/XHR. I believe that you can set headers with XHR, but that you can’t set headers with form submissions. Wouldn’t that make it possible to do what you are suggesting?
clif – I think you might misunderstand what is CSRF. It is not general site-hacking, you might want to read the wikipedia entry. And in addition it not wise to allow any type of request (GET or POST), on requests with side-effects, GET requests should be only used for idempotent requests.

Comment by Ajax 2.0 Developer — February 8, 2007

Isn’t a bigger problem the fact that this makes your application unusable without Javascript enabled? Maybe that is just assumed in this discussion…

Comment by Mark Guinn — February 8, 2007

I think we’re missing the link to Joe’s blog post about this:

Sorry I’m late to this thread, but this is one of the security mechanisms used by ASP.NET AJAX. On all our async web service calls, we use the content-type “application/json”, so IFRAMEs and form POSTs are rejected long before they get to your web service.

This is also something I enforce in my PHP for Microsoft AJAX Library project.

Joe, go for it! I consider it a best practice for AJAX frameworks.

Comment by Steve Marx — February 9, 2007

Leave a comment

You must be logged in to post a comment.