← Back to context

Comment by mg

6 months ago

What is the upside of

    <button action="/users/354" method="DELETE"></button>

over

    <button action="/users/delete?id=354"></button>

?

A GET request to `/users/delete?id=354` is dangerous. In particular, it is more vulnerable to a CSRF attack, since a form on another domain can just make a request to that endpoint, using the user's cookies.

It's possible to protect against this using various techniques, but they all add some complexity.

Also, the former is more semantically correct in terms of HTTP and REST.

Everybody has already pointed out the problem with GETTING a deletable resource, but I figured I would add this (and maybe someone will remember extra specifics).

About 2007 or so there was a case where a site was using GET to delete user accounts, of course you had to be logged in to the site to do it so what was the harm the devs thought, however a popular extension made by Google for Chrome started prefetching GET requests for the users - so coming in to the account page where you could theoretically delete your account ended up deleting the account.

It was pretty funny, because I wasn't involved in either side of the fight that ensued.

I would provide more detail than that, but I'm finding it difficult to search for it, I guess Google has screwed up a lot of other stuff since then.

on edit: my memory must be playing tricks on me, I think it had to be more around 2010, 2011 that this happened, at first I was thinking it happened before I started working in Thomson Reuters but now I think it must have happened within the first couple years there.

HTTP/1.1 spec, section 9.1.1 Safe Methods:

> 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.

See the "GET scenario" section of https://owasp.org/www-community/attacks/csrf to learn why ignoring the HTTP spec can be dangerous.

Or this blog post: https://knasmueller.net/why-using-http-get-for-delete-action...

What HTTP method would you expect the second example to use? `GET /users/delete?id=354`?

The first has the advantage of being a little clearer at the HTTP level with `DELETE /users/354`.

  • GET because that is also the default for all other elements I think. form, a, img, iframe, video...

    Ok, but what is the advantage to be "clear at the http level"?

    • That means I can make you delete things by embedding that delete URL as the source of an image on a page you visit.

      GET is defined to be safe by HTTP. There have been decades of software development that have happened with the understanding that GETs can take place without user approval. To abuse GET for unsafe actions like deleting things is a huge problem.

      This has already happened before in big ways. 37Signals built a bunch of things this way and then the Google Web Accelerator came along, prefetching links, and their customers suffered data loss.

      When they were told they were abusing HTTP, they ignored it and tried to detect GWA instead of fixing their bug. Same thing happened again, more things deleted because GET was misused.

      GET is safe by definition. Don’t abuse it for unsafe actions.

      3 replies →

    • Well, its correct, so its likely to be optimized correctly, to aid in debugging, to make testing easier and clearer, and generally just to be correct.

      Correctness is very rarely a bad goal to have.

      Also, of course, different methods have different rules, which you know as an SE. For example, PUT, UPDATE and DELETE have very different semantics in terms of repeatability of requests, for example.

implied idempotence

  • I'd say deleting a user is pretty idempotent: deleting twice is the same as deleting once, as long as you aren't reusing IDs or something silly like that. It's more that GET requests shouldn't have major side effects in the first place.