2
votes

Can someone look at my two functions below and suggest what I can do? I have created two functions that basically creates a unique key and this is echoed in a hidden field in a form and then straight after I check if the form has been submitted the second function checks to see if the key in the hidden field matches the key in the session.

The problem I am having is now and again it just redirects me to to the forbidden page suggesting the keys don't match although I have not edited the form key deliberately using my Firefox web dev tools to test.

I am not sure if it's a cache issue or not, can anyone see if there is something that I am missing out or could improve on? It only happens now and again, for example if I submit the form a few times it may then just go to the forbidden page which suggests the key in hidden field did not match the key in the session, although I see nothing wrong with my two functions.

Here is my first function, this creates a unique key and this is echoed out in a hidden field in the form. I also have a time limit on how long a user has to submit the form but I have commented that out as of now because it seems to happen more often when enabled.

function GenerateFormTokenHash($token)
{
    $token = $_SESSION['token'] = md5(uniqid(mt_rand(), true));
    //$token_time = $_SESSION['token_time'] = time();
    return htmlspecialchars($token);
    //return $token_time;
}

To use the function above i simply echo GenerateFormTokenHash($token); in a hidden called token.

The function below is used straight after i check if the form has been submitted.

# Form Token Hash Validator
function IsValidFormTokenHash()
{
    /*global $websiteaddress;
        $token_age = time() - $_SESSION['token_time'];
        if($token_age >= 300) {
            echo 'Session Expired';
            echo 'This form has now expired. ';
            echo 'Please click here to go back to the form.';
            $_SESSION = array();
            setcookie(session_name(), '', time()-42000, '/');
            # Destroy the session
            session_destroy();
            # Generate new seesion id
            session_regenerate_id(true);
            exit;
        }*/
    if(isset($_POST['token']) && $_POST['token'] != $_SESSION['token'] || !isset($_POST['token']) || !isset($_SESSION['token']))
    {
                $_SESSION = array();
                setcookie(session_name(), '', time()-42000, '/');
                # Destroy the session
                session_destroy();
                # Generate new seesion id
                session_regenerate_id(true);
        redirect("/error/forbidden.php");
        exit;
    }
}

Again that function is in my functions.php file so after i check if form has been submitted i simply call the function as follows:

if(isset($_POST['submit'])) {
    IsValidFormTokenHash();
}

So I am basically trying to work out why sometimes now and then it just thinks the session key and key in hidden field does not match, maybe a cache issue or something I can do to ensure it works properly?

1

1 Answers

3
votes

Probably what you need is to put parenthesis around your if check parts, they are probably getting evaluated in another way than your logic needs:

if( (isset($_POST['token']) && $_POST['token'] != $_SESSION['token']) //<-- added parenthesis around those
  || !isset($_POST['token'])
  || !isset($_SESSION['token']))