Mohammad Saberi
Mohammad Saberi

Reputation: 13166

PHP session data changes in Internet Explorer

I've defined a session to storing token using PHP like below:

$_SESSION['token'] = sha1(uniqid(mt_rand(), true));

when I want to read this session, I have not any problem in Chrome or Firefox. But in IE, it changes to something else before regenerating. For example if I store its value in a hidden field of form and submit it like this:

<input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>" />

I will get this result in IE in the next page:

echo $_SESSION['token']; // shows 1b05fab5ec11f1d50713aea6e74f84727d29b4a3
echo $_POST['token']; // shows e8fac6d55b04d1752f37ecde953f7f08b112ccca

Whereas if I print $_SESSION['token'] immediately after creation or even in end of its creation page, it shows the content exactly and with no problem.

What is this problem for ?

Edit:
This is my form :

<form action="process/login.php" method="post">
   <input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>" />
   <label>Email: </label><input type="text" name="email" />
   <div class="space"></div>
   <label>Password: </label><input type="password" name="password" />
   <div class="space"></div>
   <input type="submit" value="Login" class="button" />
</form>

Upvotes: 6

Views: 1890

Answers (7)

Digant
Digant

Reputation: 398

Check the value of the sha1(uniqid(mt_rand(), true)). IE has problems with names that contain '-' or '_' - they cannot maintain a session! I've had this problem twice in the past, and it always takes me weeks to figure out, and I'm shocked IE hasn't fixed it.

Just make sure you don't have such characters!

Upvotes: 0

Mehran
Mehran

Reputation: 16831

I'm almost certain that you are assigning the $_SESSION['token'] twice. It might be the same line of code being executed twice or you've assigned the variable somewhere else too. In order to find the problem you need to define a function as a wrapper for assigning the session entry. Then call the function instead of assigning the variable directly. Here's the sample code:

function assign_token()
{
    $_SESSION['token'] = sha1(uniqid(mt_rand(), true));
}

But you need to make sure never assign the token directly anywhere within your code. And call this function instead. Once you've done this, if you have a debugger, all you need to do is to set a break point within this function and see how many times it is called and from where.

But in case you don't have a debugger installed, or even worse, in case the assignment happens not within a single request but in two, you need to modify your function like this:

function assign_token()
{
    file_put_contents('/tmp/assign_token.txt', time() ."\n". print_r(debug_backtrace(), true), FILE_APPEND);
    $_SESSION['token'] = sha1(uniqid(mt_rand(), true));
}

The line added will help you track each time the function is called. Even if it's called twice within two separate requests, you can identify them thanks to FILE_APPEND and time(). The first one appends to the file (obviously) so log entries won't overwrite each other and second one helps knowing if two entries of your log are made in the same request.

That's all I've got. At the end, you may want to style the log entries making them more readable.

Upvotes: 1

Marcin Twardowski
Marcin Twardowski

Reputation: 574

Correct me if i'm wrong but i've tested already code below in Chrome FF and IE 7 and it doesn't seems that there is any issue with IE.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form method="POST" action="/">
            <?php
            session_start();
            if(!$_SESSION['token']){
                $_SESSION['token'] = sha1(uniqid(mt_rand(), true));
            }
            ?>
            <input type="hidden" value="<?php echo $_SESSION['token']; ?>" name="token"/>
            <button type="submit" name="send">Send</button>
            <?php
            if(!empty($_POST)){
                var_dump($_POST);
                var_dump($_SESSION['token']);
            }
            ?>
        </form>

    </body>
</html>

If You have php version >= 5.4 try to set builtin server in php with this command ():

php -S localhost:88 -t /path/to/your/app

Assume that You are testing in your local computer. Mayby something is wrong with apache+php stack on your server.

Upvotes: 0

Dr. Collage
Dr. Collage

Reputation: 87

I would do something more along the lines of this:

md5(uniqid($_SERVER['REMOTE_ADDR'], true))

Assuring that the token will always be unique.

Upvotes: 0

CodeBird
CodeBird

Reputation: 3858

I would try changing the name of the input to something else, maybe IE is doing some weird stuff with the token name. Searched the net, but nothing mentions this, but just to be on safe side, and remove this option I would do it.

<input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>" />

to:

<input type="hidden" name="my_session_token" value="<?php echo $_SESSION['token']; ?>" />

And try changing $_SESSION['token'] to $_SESSION['my_session_token'] as stated above in a comment

Upvotes: 1

nl-x
nl-x

Reputation: 11832

Since PHP and session storage are server side and IE is obviously a client, the problem does not reside in your session code.

Sessions are usually kept track of by a cookie (session cookie) or though a POST/GET variable. By default in PHP this value is named PHPSESSID.

Probably, in your case either the session cookie or POST/GET variable that is linked to your server side session is not coming over okay in IE. In case of a cookie, it might have to do with cookie settings and whether or not cookies are allowed at all. In case of a POST/GET it could be that your HTML is malformed in a way that IE doesn't like, but other browser do understand.

Now once that value is lost in IE, PHP assigns that browser a new session on each request, and the session token is regenerated on each request. But your hidden field remembers the old token as well...

If you show us more code (you can edit your question), I can edit my answer to give you more details.

edit You can start by showing us the relevant php.ini settings lines that concern sessions and session cookies. And by double checking your IE cookie settings. In specific I would like to know if you have set a cookie_path, making cookies only available in the same directory.

Maybe you even have an IE security setting or add-on installed preventing cookies. So try checking your IE settings and disable all add-ons and test it again.

Also check if the first page (that sets the session) and the second page (that reads the session) have EXACTLY the same domain name.

So for example www.yourdomain.com in the first page, should not be yourdomain.com on the second page (without the www) or www.yourdomain.com. (with an extra dot at the end).

Upvotes: 4

Viswanath Polaki
Viswanath Polaki

Reputation: 1402

I think after your form submits you might be creating another token value.

use

if(!isset($_POST['token'])){
  $_SESSION['token'] = sha1(uniqid(mt_rand(), true));
}

Upvotes: 2

Related Questions