I saved this code in index.php and after filling i clicked Submit button, and then a verification page was shown to me !
My question is how did it detected that it was not from the original server ?
[i hope they do not use the referrer as it can be disabled easily]
My Fake Code
<html>
<form id="post-form" action="http://stackoverflow.com/questions/ask/submit" method="post">
<input id="title" name="title" type="text" maxlength="300" tabindex="100" class="ask-title-field" value="">
<textarea id="wmd-input" name="post-text" cols="92" rows="15" tabindex="101"></textarea>
<input id="tagnames" name="tagnames" type="text" size="60" value="" tabindex="103">
<input id="submit-button" type="submit" value="Post Your Question" tabindex="120">
</form>
</html>
Can anyone guide me creating such secure page [where if a user tries to post from a dull page, he will be asked for verification] ?
- Generate a token on the server.
- Put that token into a hidden input element.
- Save that token on the server in a list of generated forms.
- When a form submission comes in
- check whether the token was passed and is valid,
- remove the token from the list of generated forms.
I suspect that this is what <input id="fkey" type="hidden" value="..." name="fkey">
on the question submission form is for.
good idea, but it puts pressure on the DB too :(
You can create an anti-XSRF token without the element of having to remember them all on the server.
You can do this by putting the information you want to verify inside the token, typically including:
- user ID, so one user can't create a form that submits for another user
- an expiry timestamp, so that tokens don't last forever
then hash this information together with a secret key and spit it out in the hidden field. When the token comes back in, you can look at the information given, hash it with the key again and see if the hash matches the user's submission.
So for example, for user ID 18936 with expiry timestamp 1304861680 (Unix time for about now), you could create a token like:
18936.1304861680.2A956E39.11E859E44B9308B812257BEE660330D9D0566189
where 2A956E39 is some random salt, and the bit at the end is the hex-encoded HMAC-SHA1 hash of 18936.1304861680.2A956E39
using the not-very-good secret key secretkey
.
This achieves the anti-XSRF purpose, but sometimes the one-time-server-stored-token is also used to prevent a form double-submission. As-is, the hash method doesn't help with that bit. But in the specific case of creating a new entity, which is a common place double-submission-prevention is deployed, you can use the token as a unique value inserted into the DB as part of the new entity, and then refuse to create a new entity if there's already one with the token in it.