GET should not Change State
Moderator: General Moderators
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
GET should not Change State
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.
* 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.
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..
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..
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
You peeked my interest here's another xss/csrf article.
http://shiflett.org/articles/foiling-cross-site-attacks
http://shiflett.org/articles/foiling-cross-site-attacks
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
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?
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?
After a little self-education, Yes I meant piqued. (Thanks
)
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.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).Ambush Commander wrote:We will focus on logout. Is the possible user inconvenience worth sacrificing some aesthetic niceness?
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.
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
Its objectionable by dogmatic purists...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 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?
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.
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
Actually, there are browser styling caveats that prevent this from happening without some javascript. Trust me, I've tried.
Hmm... a dashboard of buttons versus a list of links...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.
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.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.