View Issue Details
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0000466||HTML & PERL||Feature Request - Misc||public||2006-07-22 11:33||2008-05-30 22:45|
|Target Version||Fixed in Version|
|Summary||0000466: GET requests are confusing|
|Description||I wanted to change a vote on a particular anime, so I went to my votes, opened a second window with the anime, clicked the revoke link for the vote I wished to change, reloaded the other window and made the new vote. Due to stupidity on my end, the dropdown was still set to 1, so I tried to revoke the vote again. To do so, I reloaded the page where I had previously revoked the same vote. What I didn't notice was that by reloading the page, the revoke action had already been performed since the command to do so consists of a parameter in the URI. Being confused, I went back to the window with the anime and reloaded that as well, thereby unknowingly re-casting the wrong vote that I unknowingly revoked a second ago.|
This went on at least three times before I noticed the "vote.del=1" and "votea.rate=6" parts in the URI, hence I suggest to either display a notification ("Thank you, your vote has been recorded.", "Your vote for [title] was revoked!"), or better yet, to send a HTTP 302 header after revoking/adding a vote and sending the user back to the page where they revoked/cast the vote but without the appropriate parameter in the URI.
Here's an idea:
Instead of submitting the vote via GET, use POST. Additionally, include two hidden fields in the form that contain a timestamp and a checksum. The checksum is the md5sum of the timestamp + client's IP + secret. Upon handling the vote request, the script regenerates the checksum using the submitted timestamp and client IP. If the timestamp is smaller then the current time minus 1h or the submitted and regenerated checksums don't match, the request is discarded.
Well, I'm looking at it this way:
It takes three lines to add a method that generates the hash.
It takes two lines to get the current time, call the hash method and add the two hidden form fields.
It takes another two lines to check the submitted timestamp against the current time and verify the hash.
With roughly seven lines of code, you can make sure that users aren't tricked into casting votes in any way, you don't have to worry about how the form data is handled, and finally, if someone accidently re-posts the form or has an outdated copy of the page cached, the timestamp catches those cases.
|Tags||GET, POST, URI|
POST Requests are bad, because they usually break browsers' forward/back functionality.
Adding the hash is IMO unnecessary. It takes roughly seven lines to do that - but only a single line of code to send a 302 header and no content. Since useragents are supposed to not keep URLs with a 302 response in history, users won't accidently trigger the issue anymore.
||Reopened. This is a real issue, just not the one that elberet thinks it is.|
I added a 302 redirect, though it might indeed be worth some thought, whether we want to introduce some additional secret into the voting url to prevent 3rd parties from faking votes by making users click on specially prepared urls.
I don't think this is a real issue atm. But hey, it could happen :o)
On the other hand this would probably be something which would need to be addressed all over anidb. As you could atm make users, i.e. delete animes from their mylists if you can trick them into clicking a specially crafted link.
||Uh, that really wasn't the issue at all, that's just you being paranoid. The ISSUE is that reloading pages can result in actions being performed again when all the user wants to do is refresh the information on the page.|
The 302 redirects fix that ISSUE.
The question here is whether the remaining problems are important enough to warrant our attention.
a) request forgery by 3rd parties (making users click "mallicious" links)
b) web accelerators/spiders issuing requests
c) ... ?
|2006-07-22 11:33||DerIdiot||New Issue|
|2006-07-22 11:33||DerIdiot||Reporter||DerIdiot => Elberet|
|2006-07-22 11:33||DerIdiot||Additional Information Updated|
|2006-07-22 11:39||Elberet||Note Added: 0000905|
|2006-09-05 19:34||epoximator||Status||new => closed|
|2006-09-05 19:34||epoximator||Resolution||open => fixed|
|2006-09-05 20:11||pelican||Note Added: 0001023|
|2006-09-05 20:11||pelican||Status||closed => confirmed|
|2006-09-05 20:11||pelican||Status||confirmed => assigned|
|2006-09-05 20:11||pelican||Assigned To||=> pelican|
|2007-06-30 14:33||exp||Note Added: 0001326|
|2007-07-01 14:42||pelican||Note Added: 0001334|
|2007-07-01 16:27||exp||Note Added: 0001335|
|2007-12-06 08:06||epoximator||Resolution||fixed => open|
|2007-12-06 11:31||epoximator||Category||Feature Request - Interface => Feature Request - Misc|
|2008-02-10 22:08||ninjamask||Tag Attached: GET|
|2008-02-10 22:08||ninjamask||Tag Attached: POST|
|2008-02-10 22:08||ninjamask||Tag Attached: URI|
|2008-05-30 22:45||DerIdiot||Status||assigned => resolved|
|2008-05-30 22:45||DerIdiot||Resolution||open => fixed|