GET should not Change State

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

GET should not Change State

Post by Ambush Commander »

Some reference URLs:

* http://www.cs.tut.fi/~jkorpela/forms/methods.html
* http://en.wikipedia.org/wiki/HyperText_ ... st_methods
* http://www.w3.org/Protocols/rfc2616/rfc ... tml#sec9.5

The question? Is using GETs for actions that change state something only dogmatic purists would object to, or a perfectly reasonable practice in the web design world? I know that the spec says that GET shouldn't change anything, but so many websites (including this one) include a logout link. Changes link, uses GET. This is probably for aesthetic reasons: a text logout looks nicer than a button.

I'd like to get some input before I submit a proposal to wikitech-l to switch URLs that change state to POST.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

If you logout you don't really change the site or content.. Only _your_ status...

I think the rfc (and other articles) more pleed for a principal where you always get the same resource if you perform a GET request. If you want to modify a resource, you should use a POST. This way, if you bookmark something and surf back to that site (GET) you always recieve the "same" resource...

From a security POV using GET (links to delete.php?id=xxxx etc) makes it easier to perform a CSRF attack. For example someone evil that includes a <img src="http://example.com/delete.php?id=xxx"/> into his own website..
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

The same logic, then, could apply to logout links. At the least, it would be a major annoyance, constantly being logged out.
User avatar
neophyte
DevNet Resident
Posts: 1537
Joined: Tue Jan 20, 2004 4:58 pm
Location: Minnesota

Post by neophyte »

You peeked my interest here's another xss/csrf article.

http://shiflett.org/articles/foiling-cross-site-attacks
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

You mean piqued?

Shiflett's article does go over CSRF attacks. Actually, I think it's quite obvious that submitting posts should be POST.

The question, then, is whether or not it is worth defending against CSRF attacks with trivial actions, such as logout, by making it a POST action.

Wikipedia actually commits this problem with several actions, which include logout, add to watchlist and remove from watchlist. However, another action that uses GET, rollback, has a token associated with it, and can't be forged with a simple <img> hack.

We will focus on logout. Is the possible user inconvenience worth sacrificing some aesthetic niceness?
User avatar
neophyte
DevNet Resident
Posts: 1537
Joined: Tue Jan 20, 2004 4:58 pm
Location: Minnesota

Post by neophyte »

After a little self-education, Yes I meant piqued. (Thanks :wink:)
We will focus on logout. Is the possible user inconvenience worth sacrificing some aesthetic niceness?
I'd say it's a matter of weighing the risks. Take logout for example. What harm could be done if upon visiting another website someoone gets logged out of the preceeding site? I'd say go for it.
Roja
Tutorials Group
Posts: 2692
Joined: Sun Jan 04, 2004 10:30 pm

Post by Roja »

Ambush Commander wrote:We will focus on logout. Is the possible user inconvenience worth sacrificing some aesthetic niceness?
I'd say you chose a particularly bad area to focus on. As others mentioned, it merely causes inconvenience, not a true change in value (only status).

Lets picture an online email checker (ala gmail). Deleting a mail is a much more pressing concern. Its hard to undo, it causes a substantial change, and if done (repeatedly) by an attacker, it can cause substantial damage.

That is a worthwhile example of a change that should be handled by post. However, and this is important to the discussion, many well-known sites (including google itself) do actively change value and status using only get links.

Like neophyte said, its a balance between risk, and usability. If its *one* small item, sure, the user probably wouldn't mind a post form. If however, every single item in your webapp has to be a post form, it may cripple its usability.

Frankly, its one to take with a grain of salt imho. Plenty of sites don't follow the rule, and for a good reason - html doesn't give a strong alternative.
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

Is using GETs for actions that change state something only dogmatic purists would object to, or a perfectly reasonable practice in the web design world?
Its objectionable by dogmatic purists...;) Once you attach an action to a URI, and one which does not require any user input, its most likely going to wind up as a GET request via <a href>. Now that doesn't hold true in all cases, and there is an alternative using POST. But when the number of those actions grows substantially, using GET is almost a given.

I think it has become something of a purist view that GET in such cases is plain wrong. Maybe they should all gang together and complain to Google? :) Maybe giving a larger scale example than this forum (how many action requests are even possible via GET on a forum anyhow?) you could look at a much more action based application like a PHP game. In a PHP game there can conceivably be a 100+ actions which effect a change in state, or result in a database write, but which require absolutely no user input from a form. From my experience its fairly common to present such actions as lists of hyperlinks.

On the CSRF front - what works for forms will work for GET requests. You can generate a unique single use token and append that to all generated URIs. Once a GET request is received with a valid token you then re-issue a new token for the next request. Pretty much similar to form tokenising for your usual run of the mill CSRF.
AGISB
Forum Contributor
Posts: 422
Joined: Fri Jul 09, 2004 1:23 am

Post by AGISB »

As you can use any image as POST submit button simply create a text link image and use it to get the appearance and the POST
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Actually, there are browser styling caveats that prevent this from happening without some javascript. Trust me, I've tried.
In a PHP game there can conceivably be a 100+ actions which effect a change in state, or result in a database write, but which require absolutely no user input from a form. From my experience its fairly common to present such actions as lists of hyperlinks.
Hmm... a dashboard of buttons versus a list of links...
On the CSRF front - what works for forms will work for GET requests. You can generate a unique single use token and append that to all generated URIs. Once a GET request is received with a valid token you then re-issue a new token for the next request. Pretty much similar to form tokenising for your usual run of the mill CSRF.
That would work fairly well. The only thing I can say against it is it would require writing to some sort of static media (SESSION/database) even when this sort of action shouldn't be necessary.
Post Reply