Search code examples
phpcsrf

Quick CSRF Token


So I have found a tutorial supplied on my last thread about generating a CSRF token ... Now how should I implement it?

I've tried making it generate a new token per form request (however trying to do multiple form requests makes it invalid so that's off the list) and from reading other threads making one session token per user login is the way to go.

So what is the best way? Should I make it so when a user logs in, it will just automatically assign a

   $_SESSION['CSRFToken']

And make it assign a hashed/256 bit value? And then make that session token be assigned to every form. I guess I just don't understand how CSRF works and how to actually do something about it. Basically it just sounds like I should make each user login have a session called a Security Token that appears in every form.

Thanks for all the help!


Solution

  • You have the basic idea down. In essence, the purpose of a CSRF token is to ensure a page cannot, say, include an iFrame which triggers something within your application. As a basic example:

    <iframe src="http://example/delete.php?accept=true"></iframe>

    Generally, generating one CSRF token per session is OK, but you may want to generate a unique token for each request, and checking that. Doing so will increase the security of your application but is not needed.

    A quick reference can be found here: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29

    Update:

    You wouldn't do it through $_REQUEST per se, you'd create something like this on the form generation page

    $form_session_key = bin2hex(random_bytes(32)); // For more options see http://stackoverflow.com/a/31683058/453273
    !isset($_SESSION['CSRF_CONTENTS']) ? $_SESSION['CSRF_CONTENTS'] = array() : 0;
    $_SESSION['CSRF_CONTENTS'][] = $form_session_key;
    
    //SNIP
    
    <form action="process.php" method="POST">
        <input type="text" style="display: none" id="CSRF" contents="<?php echo $form_session_key; ?>" />
    </form>
    

    On your processing page

    !in_array($_POST['CSRF'], $_SESSION['CSRF_CONTENTS']) ? exit : 0;
    

    The above snippet exits if the CSRF key is not within the CSRF_CONTENTS array, which is generated upon page load.