A: 

According to the same origin policy of most browser side scripting languages; HTTP Header's are off limits. Flash has the most insecure rules and only a few headers are off limits (most notably the Referer as it directly relates to CSRF), but flash allows you to declare custom header names so I would avoid relying on headers for secuirty. Due to flash's insecure nature some CSRF exploits can only be written in flash, most notably "cross site file upload". There are applications that only check to make sure that the Referer and the domain/ip are the same. Motorola does this for some of their products and this is secure, but not a "hardened" approach.

For most APIs the referer doesn't apply. A web browser isn't accessing the API, so an attacker can't force the browser into making a request on his behalf. The rules can change if this is a JavaScript API. But in general you shouldn't have to worry about CSRF unless a browser has an authenticated connection to the API. Also, make sure that your API calls require authentication, sometimes CSRF can be a problem even if guests can access the resource, but this may not apply in this situation.

Rook
To answer a couple of your comments -- This is not an javascript/XHR API and yes it does implement it's own authentication. As you point out CSRF doesn't apply since the API isn't being used by a browser in the first place. I'm mainly interested in a way to disable CSRF checking for just the API and to leave it intact for the remainder of the site.
T. Stone
Ah, sorry I don't know django. I like the python web services, especially the soap client/server.
Rook
If you can't find an answer to the django problem it shouldn't be difficult to port your api to python web services.
Rook
+3  A: 

How about just splitting off a view(s) for your desktop client and decorating them with csrf_exempt? http://docs.djangoproject.com/en/1.1/ref/contrib/csrf/#ref-contrib-csrf

Brian Luft
That is exactly the setup but `csrf_exempt` doesn't seem to make a difference. It still gives a 403 with that decorator. +1 because according to the doc this should be working, even though it's not.
T. Stone
A: 

Since Django 1.1, the CSRF code will automatically allow AJAX requests to pass through, since browsers seem to do proper security checks. Here is the original commit and the documentation.

Alex Morega