我在互联网上找到了这几行代码,目的是防止CSRF使用一次性令牌。由于隐藏值可以很容易地从源代码中读取,我试图找出是什么使这段代码防止跨站点请求伪造?任何想法?
**form.php**
<?php
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
?>
<form action="process.php" method="post">
<input type="hidden" name="token" value="<?php echo $token; ?>" />
<p>
Symbol: <input type="text" name="symbol" /><br />
Shares: <input type="text" name="shares" /><br />
<input type="submit" value="Buy" />
</p>
</form>
**process.php**
<?php
if ($_POST['token'] == $_SESSION['token'])
{
/* Valid Token */
}
?>
为每个响应生成令牌,攻击者通常无法访问被攻击页面的内容。
CSRF的思想是用户不能做他不打算做的操作。
例如,一个用户可以作为管理员登录一个wordpress网站,而他的登录是有效的,他将浏览到其他一些包含恶意代码的网站,这些恶意代码在用户的wordpress网站上发布更改密码。
因为登录是有效的(会话存在),请求通过了用户验证,但失败了,因为它缺少特定操作的令牌(每次查看表单时生成)。
令牌是为每个会话唯一生成的,并存储到全局会话变量中。当攻击者通过iframe或他们使用的任何形式的攻击访问站点时,生成的令牌[希望]与存储在DB中的令牌不匹配(在这种情况下,发布到process.php)。由于令牌不匹配,攻击者将无法访问process.php中if语句中的内容。