Cross Site Request Forgery (CSRF) and GET & POST

The W3C advises when to use GET requests:

Use GET if:

  • The interaction is more like a question (i.e., it is a safe operation such as a query,read operation, or lookup).

Use POST if:

  • The interaction is more like an order, or
  • The interaction changes the state of the resource in a way that the user would perceive(e.g., a subscription to a service), or
  • The user be held accountable for the results of the interaction.

 

It is a widespread belief that choosing POST over GET requests for actions changing the state can prevent attacks known as session riding or Cross Site Reference (or Request) Forgery (CSRF). An attacker can prepare a special inconspicuous link, which points to an action that changes the state of the web application, and put it in an email or on a website. If the user is logged in to the web application and clicks on that link, the browser will automatically send the users session identifer, and the attacker can place an order, change the password et cetera in the name of the user. There are also forms of this attack where the URL of an image on a web site is this prepared link and thus the action will be executed automatically when the victim views the web site.

This class of attacks cannot be avoided by accepting only POST for some requests. Even POST requests can be sent automatically or by a click on a link. Include a security token in each request, as the security extensions against session riding do, to avoid these attacks. Another, better, plugin to include a security token in forms is the csrf_killer.

 

In order not to allow state changes in a GET request, you can use the verify method in the controller:

verify :method => :post, :only => [ :remove_tasklist ],
:redirect_to => { :action => :list }