views:

211

answers:

1

I'm interested in hearing what approaches people have taken when building a RESTful (or quasi-RESTful) API for their web applications.

A practical example:

Say you have a traditional browser-based web application which uses CSRF protection on all forms. A hidden input with a CSRF protection token is included in each form presented in the browser. Upon submission of the form, if this input does not match the server-side version of token, the form is considered invalid.

Now say you want to expose the web application as an API (perhaps using JSON instead of HTML). Traditionally when publishing an API, I've considered transactions to be unilateral (meaning the API consumer builds the request based on the published API instead of first requesting a form and then building a request using the returned form).

The "unilateral" approach breaks down when things like CSRF protection factor in. The CSRF protection token needs to be included in any POSTS/PUTS/DELETES sent by the API consumer.

I've been trying to think of how best to address this. Requesting a form each time an API call needs to be made seems very awkward (especially when dealing with asynchronous operations), but all other alternatives I've thought of on my own seem to defeat the CSRF protection (or at least punch holes in it), which is unacceptable.

Do any of you have insight into this?

Thanks.

(Not that it should matter too much, as the issue is conceptual and platform agnostic, but I'm dealing with a traditional LAMP stack and use Symfony 1.4 as my application framework. My goal is to publish a JSON-format web API allowing developers to make mobile/desktop apps that play nice with an existing web application.)

+1  A: 

REST goes quite well with authentication (i.e. Basic Authentication), so try using username of your user site's and password specific to an application bound to that user -- technique sometimes called API keys. Something that FriendFeed's API is doing see the documentation.

Few notes tough:

  • use digest authentication or SSL
  • having API key's per application can be a bit of an overhead, so most sites have single API key for all 3rd party applications
  • OAuth might be worth checking out
Zoran Regvart
Thanks for your response. As it stands today, the API will indeed use HTTP authentication, but my concern is that this alone cannot solve the CSRF problem (if the app doesn't require CSRF protection when credentials have been included, this could be exploited via other user agents that use HTTP auth...an authenticated RSS/ATOM feed, for example). I'll definitely look more closely at how an API key might help this issue, but at first glance I don't think it solves the core problem. Thanks again for your help.
Darryl H. Thomas
Think of it this way: CSRF is a problem if another (malicious) web site can reproduce/imitate the request as if it came from a valid source (in your case 3rd party application), if you use HTTP Authentication that came from the browser prompt that would be a problem (the browser will cache the authentication and repeat it in the Authorization header on subsequent requests); but 3rd party requests that came from AJAX/standalone clients have to place the Authorization header themselves in the request, and when doing so browser will not cache/repeat the header -- preventing malicious CSRF's.
Zoran Regvart
Yeah, I think we're on the same page. I'd hoped to avoid an API key due to the target audience, but this may indeed be the way to go. Still considering the "request a form for each request" approach, but I'm really not fond of that. Thanks again.
Darryl H. Thomas