简体   繁体   中英

Session variable changes value when form is submitted.

I am trying to add CSRF tokens to my forms. The problem is when I add it in the file I echo out the session token and it matches the token in the input named 'token'. But when I submit the page and use Token::check it returns false and if I echo out the token value from the input and the session again I see that the session value has changed but the input value has stayed the same.

<?php
class Token{
public static function generate(){
    return $_SESSION['token'] =    base64_encode(openssl_random_pseudo_bytes(32)); 
}

public static function check($token){
    if(isset($_SESSION['token']) && $token == $_SESSION['token']){
        unset($_SESSION['token']);
        return true;
    }else{
        return false;
    }
}
}
?>

Here is the php to control the form.

$token = $_POST['token'];
if(Token::check($token)){ //Continue with more code }

Below is a the part of the form that deals with the tokens:

<input type="hidden" name="user_id_update" value="<?php echo $user_info[0][0]->id; ?>"/>
                            <input type="hidden" name="time_update" value="<?php echo $time; ?>"/>
                            <input type="hidden" name="token" value="<?php echo Token::generate(); ?>"
                            <hr />

                            <div class="form-group">
                                <input type="submit" id="submit_update" value="Update" class="btn btn-success"/>
                            </div>

If anybody can shed some light on this I'd really appreciate it as I've been searching online for hours now and can't find an answer. Thanks.

After some digging through the code. I found that the order that these files were added into the website meant that the code to generate the token was above the controllers for the form. As such when the form was posted it created a new session variable each time and therefore the posted data was not the same as the data stored in the session variable. Changing around the order in which these files were included solved the problem. Hope this can help someone out in the future.

Same problem was with me also. After spending lots of time and debugging, I came to a strange solution. The problem was with meta tag. Let me tell you how I resolved my problem.

Filename: Token.php

<?php
    class Token
    {
        public static function generate()
        {
            return $_SESSION['token'] = md5(time() . uniqid());
        }

        public static function check($token)
        {
            if (isset($_SESSION['token']) && $token == $_SESSION['token']) {
                unset($_SESSION['token']);
                return true;
            } else {
                return false;
            }
        }
    }
?>

Filename: myscript.php

<?php require_once 'header.php'; ?>

<?php
     if ($_SERVER['REQUEST_METHOD'] == 'POST') {

         if(Token::check($_POST['token'])) {
              echo 'valid token';

              // code...
         } else {
              echo 'invalid token';
         }

     }
?>

<form action="" method="post">
    <!-- other fields -->
    <input type="hidden" name="token" value="<?php echo Token::generate();?>">
    <input type="submit" value="Submit">
</form>

<?php require_once 'footer.php'; ?>

Filename: header.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="author" content="Ishtiyaq Husain">
    <link rel="shortcut icon" href="#" />

    <!-- other css files -->
</head>

These are values I was getting:

First Page Load:

// print old token value from session
echo $_SESSION['token']; //no value
// generate new token
echo Token::generate();  // e72a2f53a25f364e8a2e62e556f7e417
// print new token value from session
echo $_SESSION['token']; // e72a2f53a25f364e8a2e62e556f7e417

After Page Refresh:

// print old token value from session
echo $_SESSION['token']; // a63e674d55e9248c25a48856649bf590 //expected value -> e72a2f53a25f364e8a2e62e556f7e417
// generate new token
echo Token::generate();  // 237063c2f7892242c79bfabcd48bcdc8
// print new token value from session
echo $_SESSION['token']; // 237063c2f7892242c79bfabcd48bcdc8

At the time of token check it gets a new token value in $_SESSION['token']. Thats why it doesn't matches with the value from hidden input box. After debugging I found that if we remove this line from header.php, it works. Is there any valid explanation for that?

<link rel="shortcut icon" href="#" />

or Use a valid URL for icon like:

<link rel="shortcut icon" href="http://ishtiyaq.com/images/iLogo.png" />

Result was:

First Page Load:

// print old token value from session
echo $_SESSION['token']; //no value
// generate new token
echo Token::generate();  // 36e48f2307da7054c67822147878e0c6
// print new token value from session
echo $_SESSION['token']; // 36e48f2307da7054c67822147878e0c6

After Page Refresh:

// print old token value from session
echo $_SESSION['token']; // 36e48f2307da7054c67822147878e0c6 //as expected
// generate new token
echo Token::generate(); // 734eaeeb862d4d0d52eea1a292f007ec
// print new token value from session
echo $_SESSION['token']; // 734eaeeb862d4d0d52eea1a292f007ec

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM