RESTful Programming and CSRF
By Daniel Miessler on March 29th, 2008: Tagged as CSRF | Information Security | Programming | Web Security

[ Edit: Disregard this post. It was written by an evil, stupid man impersonating me. No, not really. It's just wrong. The focus of REST is HTTP verbs, not actions within URLs. I knew that, but mentally pooped myself while writing this. ]
I just realized something while on the Twitter site. Shouldn’t sites built using REST principles be more susceptible to CSRF attacks? I’ve only studied REST concepts for a few minutes when building a little sample Rails app, so I could be totally off here, but follow me for a second.
REST
The concept here is for URLs to both indicate functionality to users, as well as provide that functionality. So a URL like:http://acme.com/products/cart/display
…would display the contents of your cart. Nice, right?
And a URl like:
http://acme.com/account/delete
…would nuke your account. Again, as you would expect from reading the URL.
CSRF
Cross Site Request Forgery (Sea Surf) works by getting people to follow links, via a number of methods such as embedding links in IMG tags or just plain getting them to click them via social engineering.The trick is that if you can get someone’s browser (or them) to follow a URL, while they’re logged into a given site, the “action” associated with that URL will be executed using their credentials. By credentials I usually mean a valid cookie. When your browser sends requests (even for images) to remote websites, and you happen to have a cookie for that site on your system, that cookie will be sent with ALL requests to that site. It’s kind of scary, really.
I did a proof of concept on this over at DSLR recently, where just by visiting a page I could log you out of your account there. I did that via the IMG tag trick. An image on the page pointed to the logout URL, so if you had a cookie for DSLR and loaded the fake image (which the browse does for you without your knowledge), you were logged out.
How It Would Work
So that’s the thing — RESTful URLs are associated with actions, and CSRF is based on getting you to visit URLs that have actions associated with them. Imagine a CSRF campaign against ACME company where tons of links are emailed out to ACME users with the following URLs in them:http://somesite.com/product/1234/purchase http://somecause.com/campaign/donate http://favoritesite.com/account/terminate
Remember that if any of the people following those links have valid cookies for those sites, they could automatically have those things happen. And if the attacker uses the IMG trick like I demonstrated, the user wouldn’t even know anything took place because it would have been their browser that performed the action, not them.
Anyway, just a thought. Maybe something to think about when working with RESTful designs.:
--

Actions are still actions regardless of whether they are performed via RESTful URLs or not.
Your example: http://somesite.com/product/1234/purchase
is no easier/harder to abuse with CSRF than something like:
http://somesite.com/cgi-bin/purchase.cgi?product=1234
When dealing with CSRF, you just need to remember that any major actions need to be verified by making the user re-login (or equivalent). Use of timeouts can also be helpful: “Hey, this user last visited 5 days ago and now the first page he/she is hitting is a checkout page?”
Comment by Joe Schmoe — 3/29/2008 @ 7:25 pm
Your examples don’t look like REST to me.
My understanding as as follows:
http://acme.com/products/cart/display isn’t RESTful but http://acme.com/products/cart/ with a action of GET is
http://acme.com/account/delete isn’t RESTful but http://acme.com/account/ with an action of DELETE is
Your other examples seem wrong too
You wouldn’t have http://somesite.com/product/1234/purchase You’d have http://somesite.com/basket/ and to purchase a product you’d access it with POST and the product id
http://somecause.com/campaign/donate is the same deal, you’d do a POST on http://somecause.com/campaign/ to update it with a new donation
Any RESTful URL should be completely harmless when accessed via GET.
Comment by Andrew Ingram — 3/29/2008 @ 8:16 pm
RESTful URIs are associated with resources, not actions. URIs specifying actions are not RESTful. For RESTful web applications, HTTP verbs — GET, PUT, POST, DELETE — provide the actions.
Comment by Steve Vinoski — 3/30/2008 @ 1:27 am
Ah, yes, I remember this now. Well, as I said, I wasn’t claiming expertise, and I did in fact get a crucial piece wrong in this flash of “insight”. The URLs were right, up until the action piece - the point of REST is to have the HTTP verb be the action. Not for the URL to indicate the action.
Right.
Thanks for the reminder, guys. That’ll teach me to make 5 minute posts on a whim.
Comment by Daniel Miessler — 3/30/2008 @ 2:26 am
It’s a dirty little secret of rails apps that many of them are susceptible to csrf attacks. However, if you designed your rails app correctly (i.e. GET actions only show data, to delete you have to post with DELETE) it makes it a little more difficult, because you need a POST to change any data.
There was a twitter ‘virus’ a few months that we discovered and destroyed that essentially created a form which created a tweet and POSTed the form automatically with javascript.
My colleague Rick Olson wrote CSRF_killer plugin which automatically puts some hidden form variables into all of your forms, and effectively squashes any such attacks.
Comment by court3nay — 3/30/2008 @ 2:27 am