views:

154

answers:

2

I can not figure out why I am getting this session error...

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at C:\webserver\htdocs\project2\labs\form-submits\index.php:2) in C:\webserver\htdocs\project2\labs\form-submits\index.php on line 2

As far as I knew this happens only when there is some sort of output to the browser before the session_start() function is called, in this case there is nothing printed to screen before the call, not even any white space. Any ideas why I would still get the errors?

I posted the full source code of this demo so you can see exactly what I used to create the error.

<?php
session_start();

require('formkey.class.php');
$formKey = new formKey();

$error = 'No error';

//Is request?
if($_SERVER['REQUEST_METHOD'] == 'post')
{
    //Validate the form key
    if(!isset($_POST['form_key']) || !$formKey->validate())
    {
        //Form key is invalid, show an error
        $error = 'Form key error!';
    }
    else
    {
        //Do the rest of your validation here
        $error = 'No form key error!';
    }
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
    <title>Securing forms with form keys</title>
</head>
<body>
    <div><?php if($error) { echo($error); } ?>
    <form action="" method="post">
    <dl>
        <?php $formKey->outputKey(); ?>

        <dt><label for="username">Username:</label></dt>
        <dd><input type="text" name="username" id="username" /></dd>
        <dt><label for="username">Password:</label></dt>
        <dd><input type="password" name="password" id="password" /></dd>
        <dt></dt>
        <dd><input type="submit" value="Submit" /></dd>
    <dl>
    </form>
</body>
</html>

the class file

<?php
class formKey
{
    //Here we store the generated form key
    private $formKey;

    //Here we store the old form key 
    private $old_formKey;

    //The constructor stores the form key (if one excists) in our class variable
    function __construct()
    {
        //We need the previous key so we store it
        if(isset($_SESSION['form_key']))
        {
            $this->old_formKey = $_SESSION['form_key'];
        }
    }

    //Function to generate the form key
    private function generateKey()
    {
        $ip = $_SERVER['REMOTE_ADDR'];
        $uniqid = uniqid(mt_rand(), true);
        return md5($ip . $uniqid);
    }

    //Function to output the form key
    public function outputKey()
    {
        //Generate the key and store it inside the class
        $this->formKey = $this->generateKey();
        //Store the form key in the session
        $_SESSION['form_key'] = $this->formKey;

        //Output the form key
        echo "<input type='hidden' name='form_key' id='form_key' value='".$this->formKey."' />";
    }


    //Function that validated the form key POST data
    public function validate()
    {
        //We use the old formKey and not the new generated version
        if($_POST['form_key'] == $this->old_formKey)
        {
            //The key is valid, return true.
            return true;
        }
        else
        {
            //The key is invalid, return false.
            return false;
        }
    }
}
?>
A: 

you probably have some whitespace at the top of index.php.. right before the <? tag, could be a space... that would cause it.. php is very finicky about that... session_start has to be called before any output is emitted...

jspcal
That is what I thought at first but that is not the case either, this is a really weird issue
jasondavis
+1  A: 

I ran into this error once when the file had a BOM (byte order marker) at the beginning. Apparently that also caused headers to be sent. However, this may have been a php bug that has been since fixed. Worth taking a look at though..

EDIT: At this point, I am thinking that session_start() is throwing an error before it can get the cookie sent. An early error would get sent to the browser and prevent the cookie from being sent. However, in this case, you should see the earlier error on your screen. I know this is probably not the issue, but I can't think of what else could be causing the problem.

stealthdragon
+1 this was gonna be my answer too.
fireeyedboy
It seems to be every file on my whole server now. I think this must be server related as every file on my server just started doing this tonight
jasondavis
Well actually I think you might be on to something, I use chrome but I just tried some pages with firefox and in firefox I get 2 errors, the one I show here but befor that error is another error "Cannot send session cookie"
jasondavis
I only SEE the cookie error in firefox but that must be the problem, still strange how it all worked prior to just hours ago and I have made now changes on my computer, also sessions from other sites work fine
jasondavis
Yeah, that is strange that it would be browser dependent. However, certain browsers will display information differently depending on the http status code returned from the server. Anyways, if you fix the first error, you should be good to go.
stealthdragon
Yeah, im still stuck though, it just happened out of nowhere, maybe if I reboot my system hopefully
jasondavis
Just did a reboot and problem is still there, I am soo lost now
jasondavis
I will pick u since your answer or comments is basicly what the problem is and im gonna start a new question about this
jasondavis