Question

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

Was it helpful?

Solution

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?

OTHER TIPS

GET is conventionally free of side-effects - 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.

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.

Another example..

http://example.com/admin/articles/delete/2

This will delete the article if you are logged in and have the right privileges. If your site accepts comments for example and a user submits that link as an image; like so:

<img src="http://example.com/admin/articles/delete/2" alt="This will delete your article."/>

Then when you yourself as the admin user come to browse through the comments on your site the browser will attempt to fetch that image by sending off a request to that URL. But because you are logged in whilst the browser is doing this the article will get deleted.

You may not even notice, without looking at the source code as most browsers wont show anything if it can't find an image.

Hope that makes sense.

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.

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.

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.

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&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 ] ... "

Apart from all the excellent reasons mentioned on here, GET requests could be logged by the recipient server, such as in the access.log. If you send across sensitive data such as passwords in the request, they'll get logged as plaintext.

Even if they are hashed/salted for secure DB storage, a breach (or someone looking over the IT guy's shoulder) could reveal them. Such data should go in the POST body.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top