0

I have read many articles about CSRF, almost all of them have the same solution which is hidden tokens, so i wrote a code to prevent CSRF and i tried hacking my own page afterwards but it didn't work, i would like to know if my code is CSRF bulletproof, and if there is anyway around it.

i have four pages that has forms in them so in each page i would write the following:

            if (isset($_POST['submit'])){

            // Check for CSRF token
            if ($_SESSION['token'] === $_POST['token']){

                // write to db

            }else{
                 // CSRF attack has been detected
                 die("CSRF :<br>1: $_SESSION[token]  <br> 2: $_POST[token]");

            }

        }else{
            // assign CSRF prevention token
            $form_token = md5((rand(1,89412) * 256 / 4).$date.time());
            $_SESSION['token'] = $form_token;
        }
        ?>
        <form action='' method='post'>
        <input type='hidden' name='token' value='<?echo $form_token;?>'>

would this method be enough to stop attackers from using CSRF on my website ?

Thanks alot.

  • This prevents from posting "blind" or automated form submits ... it's just one part of preventing attacks. Your session (id) also has to be safe so it could not be hijacked - same for session cookies. – djot Sep 08 '13 at 00:28
  • does that mean my website is still vulnerable to CSRF ? if so, how can i prevent it. – user2585384 Sep 08 '13 at 00:33
  • Well, I am not a security expert ... but if I manage to hijack your/users session id, the form token is useless. – djot Sep 08 '13 at 00:34
  • Thank you Djot for your quick reply, Is there anything else i can do to secure my sessions rather than using https at all times ? – user2585384 Sep 08 '13 at 00:37
  • Regenerate the session, when user logs in/out, gets higher privileges, etc. (http://php.net/manual/en/function.session-regenerate-id.php). Best of all do not use standard sessions, which might be vulnerable in shared hosting (http://php.net/manual/en/function.session-set-save-handler.php). Try to hash + salt data whereever applicable (passwords, etc...) – djot Sep 08 '13 at 00:41
  • Thanks @djot, your contribution was very helpful. – user2585384 Sep 08 '13 at 00:54
  • @user123 Well, I have the same problems ... and it's unfortunately not a one liner ... I have all those 3 parts ... encrypted sessions in a database, I regenerate my session id, I have encrypted cookies (or no data in them), hashed and salted passwords (and other relevant data), I never trust user input and, yeah, tokens in web forms ... but I feel unsafe anyway. (If the server gets hacked you're lost anyway) – djot Sep 08 '13 at 00:56

1 Answers1

0

I'll show you my code for CSRF prevention:

config.php
Configuration file should be auto-loaded in every page using require or include functions.
Best practice would be to write a configuration class (I'll just write down functions in order to simplify my code).

session_start();

if(empty($_SESSION['CSRF'])){
        $_SESSION['CSRF'] = secureRandomToken();
    }

post.php
This is just an example. In every "post" page you should check if CSRF token is set. Please submit your forms with POST method! I'd also recommend you to take a look at Slim Framework or Laravel Lumen, they provide an excellent routing system which is gonna let you to accept POST requests only on your "post.php" page very easily (they also will automatically add a CSRF token in every form).

if (!empty($_POST['CSRF'])) {
    if (!hash_equals($_SESSION['CSRF'], $_POST['CSRF'])) {
        die('CSRF detected.');
    }
}else{
    die('CSRF detected.');
}

view.php
Now you just have to put an hidden input with your CSRF session value in it.

<input type="hidden" name="CSRF" value="<?= $_SESSION['CSRF'] ?>">

I hope that this quick explanation may help you :)

Michele Riva
  • 552
  • 9
  • 24