I have a php page that submits form to itself.
I wanted to add a check where I can possibly stop basic cross site forgery.
my code:
<?php
session_start();
(...) //some code
$secret = substr(md5(uniqid(rand(), true)), 1, 2);
$_SESSION["secret"] = $secret;
$auth = $secret;
?>
(...)
<form id="form" name="form" action="<?php echo htmlentities($_SERVER[PHP_SELF]); ?>" method="post">
(...)
<input type="hidden" name="id" value="<? echo $auth; ?>" />
(...)
<?php
(...)
//as a debug I just tried to display
echo $_POST["id"];
echo "=";
echo $_SESSION["secret"];
(...)
?>
<div>
</body>
</html>
But both id and secret never returns the same value.
Why is that? What am I missing?
UPDATE
So, I tried an answer here by Samuel Cook, as also suggested by the comment of Jon Stirling:
if(!isset($_SESSION["secret"])){
$secret = substr(md5(uniqid(rand(), true)), 1, 2);
$_SESSION["secret"] = $secret;
$auth = $secret;
}
But now if there is no $_SESSION["secret"]
The page returns:
<input type="hidden" name="id" value="" />
I understand why, its because secret is only being set if the session variable is present.
Any suggestions?
UPDATE
Moved the check before generating a new session key and is only checking if there is a post of id. works well now thanks.
At the point when you debug code executes, the secret has changed:
As long as you do your check for a match at the beginning of the script (before generating the next secret) it will be fine.