On my website, I have a poll. It’s cookie based poll. If a user votes, I create a cookie with the current poll, so he can’t vote until a new poll is created. I know that the users can delete the cookies and vote again, but that is not the problem here.
I have a ajax.php page that handles the ajax post. Here is the code:
if(isset($_COOKIE['poll_id']) && $_COOKIE['poll_id'] == $poll_id)
{
// print message that it is already voted, show the results...
}
else
{
// update the database and create a cookie
}
This code works OK if the the voting is made on button click. But, I started a javascript in Firebug that is doing this:
for(var i=0;i<100;i++) {
jQuery.post('ajax.php', {
//post parameters
});
}
And I get 100 votes. If i run the script again, it fails, because a cookie is created, but it seems that if I make a 100 simultaneous requests, the check fails, because I guess the system doesn’t have the time to create the cookie in time, so all the updates goes through.
Any suggestions on how to solve this?
This is where
XSRFcomes to play. In your site you should first create a random (properly salted and enoughly secure) string and store it in session. In all your pages you should be getting this session value and passing it with form submits. When examining user input you should be checking this value as part of the page request.Now if in the poll page you are sending this, and in ajax.php you are examining this then you will find that value and know that this is a safe request. When someone tries something smart over firebug/jquery etc, they will not be able to access/send this value, and your pages can ignore such requests.
Of course, my explanation is an oversimplification for better/easier understanding. But do read more about it, that will help solve your scenario as well as make your code more robust.
Adding a simple pseudo code example:
Assume first your random XSRF string is already set in session.
Now when someone tries it with firebug: