Anti-CSRF code giving unexpected results.

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
impulse()
Forum Regular
Posts: 748
Joined: Wed Aug 09, 2006 8:36 am
Location: Staffordshire, UK
Contact:

Anti-CSRF code giving unexpected results.

Post by impulse() »

I've been polishing up my security with forms today and I've come across a chapter which shows me how to avoid CSRF attacks. I've learned to use the following code to avoid these attacks but I'm getting unexpected results. Please can somebody point out why on each form submittion the results of the 2 variables never match:

Code: Select all

session_start();

$_SESSION['token'] = md5(uniqid(rand(), TRUE));

echo "<form method = 'post' action = 'uni.php'>";
echo "<input type = 'hidden' name = 'check' value = '$_SESSION[token]'>";
echo "<input type = 'text' name = 'one'>";
echo "<input type = 'submit' value = 'Submit'>";
echo "</form>";

if (isset($_POST['one'])) {
  if ($_SESSION['token'] == $_POST['check']) {
    echo "Match";
  }
}

echo $_POST['check'];
echo "<br>";
echo $_SESSION['token'];
$_POST['check'] and $_SESSION['token'] never match.

Regards, Stephen
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

You're setting a new $_SESSION['token'] with each request, regardless of wether the form is displayed and/or the form values are processed.
This might be the result of a misconception on how php works. Try

Code: Select all

<?php session_start(); ?>
<html>
	<head><title>To illustrate why it does not works</title>
	<body>
<?php
$_SESSION['token'] = md5(uniqid(rand(), TRUE));
echo '<div>setting token to: ', $_SESSION['token'], "</div>\n";
echo '<div>_POST[check]: ', isset($_POST['check']) ? $_POST['check']:'-not set-', "</div>\n";

echo "<form method = 'post' action = '#'>";
echo "<input type = 'hidden' name = 'check' value = '$_SESSION[token]'>";
echo "<input type = 'text' name = 'one'>";
echo "<input type = 'submit' value = 'Submit'>";
echo "</form>";

if (isset($_POST['one'])) {
	if ($_SESSION['token'] == $_POST['check']) {
		echo "Match";
	}
	else {
		echo 'no match';
	}
}
else {
	echo '<div>_POST[one] not set</div>';
}
?>
	</body>
</html>
Post Reply