boxcore
3/15/2016 - 5:54 AM

Simple PHP CSRF form protection demo

Simple PHP CSRF form protection demo

<?php

function storeCsrfInSession($key, $value) {
    if (isset($_SESSION)) {
        $_SESSION[$key] = $value;
    }
}

function removeCsrfFromSession($key) {
    $_SESSION[$key] = ' ';
    unset($_SESSION[$key]);
}

function cleanPreviousCsrfs($name) {
    foreach($_SESSION as $key => $val) {
        if ( substr($key, 0, strlen($name)) == $name) {
            $_SESSION[$key] = ' ';
            unset($_SESSION[$key]);
        }
    }
}

function getCsrfFromSession($key) {
    if (isset($_SESSION[$key])) {
        return $_SESSION[$key];
    }
    else {
        return false;
    }
}

function generateCsrfToken($formName)
{
    if (function_exists('hash_algos') && in_array('sha512', hash_algos())) {
        $token = hash('sha512', mt_rand(0, mt_getrandmax()));
    } else {
        $token = ' ';
        for ($i = 0; $i < 128; ++$i) {
            $r = mt_rand(0, 35);
            if ($r < 26) {
                $c = chr(ord('a') + $r);
            } else {
                $c = chr(ord('0') + $r - 26);
            }
            $token .= $c;
        }
    }
    $key = $formName . '_' . mt_rand(0,mt_getrandmax());
    cleanPreviousCsrfs($formName);
    storeCsrfInSession($key, $token);
    return array('name' => $key, 'token' => $token);
}

function validateCsrfToken($formName, $tokenValue)
{
    $token = getCsrfFromSession($formName);
    if ($token === false) {
        return false;
    } elseif ($token === $tokenValue) {
        $result = true;
    } else {
        $result = false;
    }
    removeCsrfFromSession($formName);
    return $result;
}

session_start();

if (count($_POST) > 0) {
    $valid = validateCsrfToken($_POST['csrfName'], $_POST['csrfToken']);
    if ($valid) {
        echo '<h1>CONTINUE DUDE.</h1>';
        // Do stuff
    } else {
        echo '<h1>NO WAY DUDE!</h1>';
    }
} else {
    $csrf = $token=generateCsrfToken('myForm');
    ?>
    <form action="" method="POST">
        <input type="hidden" name="csrfName" value="<?php echo $csrf['name'] ?>">
        <input type="hidden" name="csrfToken" value="<?php echo $csrf['token'] ?>">
        <input type="email" name="email" placeholder="Email">
        <button type="submit">Submit</button>
    </form>
    <?php
}