关于防止跨站点请求伪造


About Preventing Cross-Site Request Forgeries?

我在互联网上找到了这几行代码,目的是防止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语句中的内容。