views:

492

answers:

8

I have been working through Microsoft's ASP.NET MVC tutorials, ending up at this page

http://www.asp.net/learn/mvc/tutorial-32-cs.aspx

The following statement is made towards the bottom of this page:

In general, you don’t want to perform an HTTP GET operation when invoking an action that modifies the state of your web application. When performing a delete, you want to perform an HTTP POST, or better yet, an HTTP DELETE operation.

Is this true? Can anyone offer a more detailed explanation for the rationale behind this statement?

Edit

Wikipedia states the following:

Some methods (for example, HEAD, GET, OPTIONS and TRACE) are defined as safe, which means they are intended only for information retrieval and should not change the state of the server.

By contrast, methods such as POST, PUT and DELETE are intended for actions which may cause side effects either on the server

+15  A: 

GET is conventionally idempotent - in other words, it doesn't change the state. That means the results can be cached, bookmarks can be made safely etc.

From the HTTP 1.1 RFC 2616

Implementors should be aware that the software represents the user in their interactions over the Internet, and should be careful to allow the user to be aware of any actions they might take which may have an unexpected significance to themselves or others.

In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.

Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature. The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them.

Jon Skeet
+10  A: 

Apart from purist issues around being idempotent, there is a practical side: spiders/bots/crawlers etc will follow hyperlinks. If you have your "delete" action as a hyperlink that does a GET, then google can merrily delete all your data. See "The Spider of Doom".

With posts, this isn't a risk.

Marc Gravell
The spider of doom. thats funny...
MikeJ
That was a great link!
Aaron
+4  A: 

Please see my answer here. It applies equally to this question.

  • Prefetch: A lot of web browsers will use prefetching. Which means that it will load a page before you click on the link. Anticipating that you will click on that link later.
  • Bots: There are several bots that scan and index the internet for information. They will only issue GET requests. You don't want to delete something from a GET request for this reason.
  • Caching: GET HTTP requests are not supposed to change state and they should be idempotent. Idempotent means that issuing a request once, or issuing it multiple times gives the same result. I.e. there are no side effects. For this reason GET HTTP requests are tightly tied to caching.
  • HTTP standard says so: The HTTP standard says what each HTTP method is for. Several programs are built to use the HTTP standard, and they assume that you will use it the way you are supposed to. So you will have undefined behavior from a slew of random programs if you don't follow.
Brian R. Bondy
+3  A: 

About this topic (HTTP methods usage), I recommend reading this blog post: http://blog.codevader.com/2008/11/02/why-learning-http-does-matter/

This is actually the opposite problem: why do not use POST when no data is changed.

razenha
+18  A: 

Jon Skeet's answer is the canonical answer. But: Suppose you have a link:

href = "\myApp\DeleteImportantData.aspx?UserID=27"

and the google-bot comes along and indexes your page? What happens then?

chris
This expresses the rationale very concisely - hence I have marked it as the answer.
Richard Ev
This is called a Cross-Site Request Forgery vulnerability.
Gumbo
Not necessarily. Take a look at the link Marc Gravell posted (The Spider of Doom). I've read several articles describing exactly this type of issue, usually behind javascript validation, which the spiders ignore. Yes, it could be malicious, but most of the time it's just stupidity.
chris
+1  A: 

Another issue with GET is that the command goes to the browser's address bar. So if you refresh the page, you issue the command again, be it "delete last stuff", "submit the order" or similar.

PhiLho
It's not true. The same problem with POST. People use "POST-REDIRECT-GET" approach.
eu-ge-ne
I don't know for other browsers, but at least with Firefox, if I refresh a page (or go back to it) I reached after sending a POST request, at least it warns me and ask me if I want to resend the request. While with GET, you have no warning!
PhiLho
+4  A: 

In addition to spiders and requests having to be idempotent there's also a security issue with get requests. Someone can easily send your users an e-mail with

<img src="http://yoursite/Delete/Me" />

in the text and the browser will happily go along and try and access the resource. Using POST isn't a cure for such things (as you can put together a form post in javascript pretty easily) but it's a good start.

sighohwell
A: 

Let's say we have an internet banking application and we visit the transfer page. The logged in user chooses to transfer $10 to another account.

Clicking on the submit button redirects (as a GET request) to https://my.bank.com/users/transfer?amount=10&amp;destination=23lk3j2kj31lk2j3k2j

But the internet connection is slow and/or the server(s) is(are) busy so after hitting the submit button the new page is loading slow.

The user gets frustrated and starts hitting F5 (refresh page) furiously. Guess what will happen? More than one transfer will occur possibly emptying the user's account.


Now if the request is made as POST (or anything else than GET) the first F5 (refresh page) the user will make the browser will gently ask "are you sure you want to do that? It can have side effects [ bla bla bla ] ... "

Andrei Rinea