views:

121

answers:

8

I know you should use POST whenever data will be modified on a public website. There are several reasons including the fact that search engines will follow all the links and modify the data.

My question is do you think it is OK to use GET behind authenticated pages in something like an admin interface?

One example would be a list of products with a delete link on each row. Since the only way to get to the page is if you are logged in, is there any harm in just using a link with the product ID in the query string?

Elaboration for comments:

I personally don't have any issues or difficulties in implementing the deletes with POST. I have just seen several examples of code in ASP.NET and ASP.NET MVC for "admin like" pages that use GET instead of POST. I am curious about peoples' opinion on the matter.

+3  A: 

It is still bad practice to use GET for destructive operations - even if it is hidden behind authentication - as it makes it possible (easier?) for someone with knowledge of that URL to exploit it (for example, using XSS). And of course, it is a bad design/coding practice as well, especially if you are trying to create a RESTful service.

There are probably many other reasons as well...

Justin Ethier
Someone could just as easily XSS script a post action to delete.
Nissan Fan
Agreed. Don't do it. And while it's true that XSS isn't really an issue, XSRF is, @Nissan Fan.
Pointy
XSS (and CSRF) are not dependent on the request method.
BalusC
@BalusC well CSRF doesn't "depend" on the request method, but for some attack vectors the only available method is "GET" (`<img>` tags for example). (And yes I realize that you know that :-)
Pointy
I think I should stress that at the end of the day there will always be a zero day exploit and an attack vector, while developing defensively is a great in practice GETs are a core fact of life in web-based applications. I'd rather not take them off the table for my toolset. While it's fair to want to eliminate them for destructive actions, at the same time this person may be using ASP.NET which makes multiple FORM actions a nightmare.
Nissan Fan
there was a story about google crawling web pages and causing the deletion of every record in the companies database because it got to a page that generated GET requests to delete records in the database, it walked every delete link and deleted everything from their catalog. Needless to say that is one example of an extremely bad practice.
fuzzy lollipop
Here it is: http://thedailywtf.com/Articles/The_Spider_of_Doom.aspx - Apparently their "authentication system" had some issues as well.
Justin Ethier
@Fuzzy Unauthenticated access will certainly create that situation.
Nissan Fan
A: 

GET and POST are very, very similar except for the fact that GETs have a limit on the length of the HTTP action because they are all URL based.

Since you won't be providing access to people who haven't authenticated I don't believe using gets is problematic.

Nissan Fan
GET is NOT similar to POST at all. GET is for retrieving data idempotently, POST is for submitting data to non-idempotently change the state of the server. This means calling GET more than once is the same as calling it once. http://en.wikipedia.org/wiki/Idempotence
fuzzy lollipop
http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods
sibidiba
+1  A: 

I do this on pages where I know someone is logged in and I can verify the users right to delete something based on other data which I keep in my session. I would suggest adding a confirmation step: "are you sure you want to delete this thingy?"

Ray
In which case you'll have to answer that method the confirmation page uses.
Julian Reschke
I meant to suggest a javascript confirm() box the would allow or abort the GET depending on the user's response.
Ray
What's the point of that? If you involve javascript anyway why not make it a POST in the first place then?
Julian Reschke
A link issues a GET by default. Adding a confirm() to the onclick handler has no effect on that - you just return true or false, depending on what the user decided, and the GET happens or not. To POST, you would need to call form.submit() from the link script. And it woud be necessary do add something to the form elements to tell the server-side code what to do with the submission. This is more work than just using the GET request that the link wants to do anyway.
Ray
+2  A: 

GET ought to be used to retrieve data idempotently and POST ought to be used to update data non-idempotently. That's all. It's certainly not a "best practice" to interchange the methods.

As to XSS and CSRF risks, to prevent the one just HTML-escape any user-controlled input during (re)displaying and to prevent the other just make use of request based tokens and/or captchas.

BalusC
+2  A: 

Yes.

Code may rely (correctly) on GET not being destructive. That code could run in the browser, and thus will be authenticated (link prefetching comes to mind).

Julian Reschke
+1 Someone with a link pre-fetcher could easily wipe out an entire table just by logging into the admin page.
Frank Schmitt
+3  A: 

Some people learned some time ago that it's a very bad idea.

Google launched a new app to "speed up browsing" (Google Web Accelerator) that prefetched the linked pages in the browser (no attacks, no third party...), and when someone logged to such protected pages, well the app looked at all those links and said: "Hey, I'll prefetch those ones also because that way I have the page ready when the user requests it"

They have changed the behavior, but anyone can do anything similar any day.

AlfonsoML
+3  A: 

The temptation of using GETs is that you can create a bunch of delete links without creating dozens of forms per page, or resorting to JavaScript. Yet for various reasons that have already been mentioned, the web depends on GETs not being destructive.

The best practice, if generating one tiny form per delete link in on server is impractical, is to use a GET link to load up a confirmation page from the server which has a POST form that performs the delete. Then do some progressive enhancement:

<a href="/controller/delete/1" onclick="$.post(this.href); return false;">Delete</a>

If the server gets a GET to /controller/delete/x then serve up a confirmation page with a POST form. If the server gets a POST (or maybe a DELETE) request then do the deletion.

Frank Schmitt
+2  A: 

It would be a bad practice to delete data based on a GET request. Technically, you can do it, but you'll be out of sync with most well written websites. You are basically creating a new set of rules for your user interface if your use GET requets for deletes. I consider the URLs of your website part of the user interface. If you sent somebody a link like http://www.fakesite.site/posts/delete?ID=1, they would expect to be displayed a page asking if they want to delete post with ID #1, not perform the actual delete.

Jim
In particular, you'll be out of sync with the spec.
Julian Reschke