LWN.net Logo

Cross-site request forgery

Cross-site request forgery

Posted Oct 18, 2007 1:10 UTC (Thu) by jwb (guest, #15467)
Parent article: Cross-site request forgery

The real problem underlying XSRF is that the self-styled "developers" behind most web hacks don't respect the difference between the GET and POST request methods. A GET should not have side effects! If I can vote in a poll on your site using nothing other than a GET, that is an HTTP protocol violation. Quoting from RFC 2616 (which is almost 10 years old):

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property...

The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI...

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.


(Log in to post comments)

Cross-site request forgery

Posted Oct 18, 2007 2:56 UTC (Thu) by elanthis (guest, #6227) [Link]

Even if the app only modifies data in response to a POST, it is still very trivial for a site
to include a hidden form with automatic submission thanks to JavaScript.

The hidden magic numbers in form submissions is one approach to solving this I never thought
of.

I've just relied on the HTTP referer header: sans a bug in the user's browser, sites and
scripts cannot forge this header.  Someone could trivially write their own utility or program
which performs HTTP requests with a forged referer (curl and wget both support setting this to
arbitrary values), but then they wouldn't have the proper authentication cookie.

Not the most robust solution nor all that ideal in theory, but it's Good Enough(tm) in
practice.

Cross-site request forgery

Posted Oct 18, 2007 3:01 UTC (Thu) by jwb (guest, #15467) [Link]

I agree that you need further measures to protect against malicious webmasters, but they are a
small part of the problem.  The larger part of the problem is that anybody can put <img
src="whatever"> into a forum post (including this one) which causes a simple GET request.  If
your application has side effects on GET requests, then it is vulnerable to this very simple
attack.

Cross-site request forgery

Posted Oct 18, 2007 3:04 UTC (Thu) by jwb (guest, #15467) [Link]

It should be noted that certain forum software is rather more permissive about the sorts of things which can be posted by anonymous users, while other software can be very restrictive.

Cross-site request forgery

Posted Oct 18, 2007 3:19 UTC (Thu) by tetromino (subscriber, #33846) [Link]

You forgot to add a <marquee>.

Cross-site request forgery

Posted Oct 18, 2007 5:27 UTC (Thu) by mitchskin (subscriber, #32405) [Link]

lol, the medium is indeed the message.

Cross-site request forgery

Posted Oct 18, 2007 7:32 UTC (Thu) by Los__D (guest, #15263) [Link]

MY EYES, MY EYES!!! :D

Cross-site request forgery

Posted Oct 25, 2007 18:07 UTC (Thu) by devinjones (guest, #11272) [Link]

Thank goodness for firebug.

Cross-site request forgery

Posted Oct 18, 2007 10:44 UTC (Thu) by epa (subscriber, #39769) [Link]

A hidden form that automatically sends POST requests to some other site without user
intervention?  Do you have an example?  I'm just surprised that this is allowed by
Javascript's security model (as tightened up by recent browsers).

Of course I agree strongly with the grandparent; don't use GET requests for stateful
operations.  That is just asking for trouble.  I once worked in a web development shop where
the policy was that clickable links were somehow cooler than form submit buttons, so the user
management page had a 'delete' link for each user.  A customer was using a web accelerator
program that prefetches links (a perfectly allowable thing to do, provided it just GETs) and
deleted all users from the site.

Hidden POST forms

Posted Oct 19, 2007 0:53 UTC (Fri) by jamesh (guest, #1159) [Link]

It is trivial to create such a page. An outline of such an attack is:

  1. Include an iframe on your page, possibly hidden. Something like "<iframe name="foo" style="display: none"></iframe>
  2. Add a form element on the page with target="foo" as an attribute. This will cause the post to be loaded into the hidden iframe.
  3. Set the action attribute of the form to the site you want to attack, and the method to "post".
  4. Include all the form data you want as hidden form fields.
  5. Add an onload handler to the page that calls the submit() method on the form.

It worked pretty well in the browsers I tried, and doesn't give the user any indication that the form post occurred. So it isn't enough to just put all your unsafe operations into POST requests.

"Referer" header checking and nonces as hidden form fields will stop this attack dead in its tracks though, so they are worth investigating.

Cross-site request forgery

Posted Oct 26, 2007 15:12 UTC (Fri) by anton (guest, #25547) [Link]

[...] it is still very trivial for a site to include a hidden form with automatic submission thanks to JavaScript.
Not a problem for me, because I have disabled Javascript. Maybe just like some web designers show their lack of competence with messages like "Turn on JavaScript", other webmasters could show their security competence by welcoming users that have JavaScript enabled with "Turn off Javascript".

Cross-site request forgery

Posted Oct 19, 2007 9:34 UTC (Fri) by ekj (guest, #1524) [Link]

Sure they can have side-effect, the quote you include says as much.

What it says is that "the side-effects of N > 0 identical requests is the same as for a single
request."

In other words, for a GET-request it should make no difference if you visit the link 1 time,
or 200 times, the side-effects should be identical. There is allowed to be a difference
between visiting the link 1+ times, and visiting 0 times.

That's NOT the same as saying there should be no side-effects.

An example: Voting for a story on Digg. If you vote yes for a certain story once, or 100
times, the result is the same: your vote is registered as a yes.

Another example: Adding a certain book to your amazon wishlist. Whether you do the relevant
GET-request once or 10 times, the side-effect is the same: that book will appear on your
wishlist. (once, not 10 times!)

So no, respecting the difference between GET and POST will do precisely nothing at all to
combat this particular vulnerability, though it would have -other- advantages.

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds