0

Generally we know that a random token added to each request is a good solution against CSRF. But how exactely is it work? The web server generates token, sends it to client in hidden form, than this token is added to request and webserver validates it (for me it is reasonable). the second approach could be that client generate the token and sends it to web server. But how webserver know about the token, is it correct if it was not generated by webserver.

1

The token is always generated by the server, never the client. You are correct that if the client generated the token, then the server could not verify that it was valid. This is why every single CSRF mitigation scheme includes a token generated by the server. So, since the server created the token, it always knows what the token value should be, and can validate that the client sent the correct token.

0

You can generate a random token once and store in a cookie, then submit it with every form as a hidden input so you can check in the server.

0

If a script has multiple forms to handle as most of the MVC code has to nowadays the cookie that contains the CSRF token will be same for all hence defeating the purpose of CSRF token as each CSRF token needs to be form specific.

0

CSRF tokens are a little bit more complicated than that. These are tokens that prevent people from posting forms to your website that cause unintended effects to your users. I'll give you an example of what happens with and without

On your website, you have a form that allows people who are signed in to post a message to the main chat channel.

<form action="postmessage/" method="post>
    <textarea name="message"></textarea>
    <input type="submit" value="Send!" />
</form>

When this form is submitted, it'll go to "postmessage/". That page will take the contents of the text area, and post it to the feed alongside the users id.

Now, imagine we go to a site that isn't trustworthy. On that site, the following code exists

<form action="fakesite.fake/postmessage/" method="post" id="secretform">
    <input type="hidden" name="message" value="Go to betterfakesite.fake its much better than this site">
</form>
<a href="membersarea/" id="fakelink">Go to Members Area">
<script>
    document.getElementById("fakelink").onclick = function(e) {
        e.preventDefault();
        document.getElementById("secretform").submit();
</script>

Since there's no CSRF protection, when a person clicks that link they'll be sent to your site and immediately post a message telling them to go somewhere else.

Now, lets try again with a CSRF token

<form action="postmessage/" method="post>
    <input type="hidden" name="_csrf" value="GENERATEDBYSERVER">
    <textarea name="message"></textarea>
    <input type="submit" value="Send!" />
</form>

When you visit this page, a token is generated for the form. This token should be stored in the users session on the server side. When a person submits the form, they'll also send along the token, which the server can then check against the tokens it has in the users session. If it's not there, reject the message. If it is, accept it and delete the token.

Now when you go to the malicious page and click the link, you'll be redirected to your site, but no post would have been made. The CSRF token protected you.

A token is only as secure as you make it. When generating a token, always store it under the users session. In PHP it's the $_SESSION variable, and other language equivalents. What this ensures is that one person can't generate a ton of these tokens, then use them against other people.

JavaScript by default prevents cross site requests, the malicious page can't try to ajax a copy of the page to pull a token. They can't script their server to do it either, as the tokens are unique to user session.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.