0

我读过很多关于 CSRF 的文章,几乎所有文章都有相同的解决方案,即隐藏令牌,所以我写了一个代码来防止 CSRF,然后我尝试破解我自己的页面,但它没有用,我想知道是否我的代码是 CSRF 防弹的,如果有的话。

我有四个页面,其中包含表格,因此在每个页面中我会写以下内容:

            if (isset($_POST['submit'])){

            // Check for CSRF token
            if ($_SESSION['token'] === $_POST['token']){

                // write to db

            }else{
                 // CSRF attack has been detected
                 die("CSRF :<br>1: $_SESSION[token]  <br> 2: $_POST[token]");

            }

        }else{
            // assign CSRF prevention token
            $form_token = md5((rand(1,89412) * 256 / 4).$date.time());
            $_SESSION['token'] = $form_token;
        }
        ?>
        <form action='' method='post'>
        <input type='hidden' name='token' value='<?echo $form_token;?>'>

这种方法是否足以阻止攻击者在我的网站上使用 CSRF?

非常感谢。

4

1 回答 1

0

我将向您展示我的 CSRF 预防代码:

config.php
配置文件应该在每个页面使用requireinclude功能时自动加载。
最佳实践是编写一个配置类(我只是写下函数以简化我的代码)。

session_start();

if(empty($_SESSION['CSRF'])){
        $_SESSION['CSRF'] = secureRandomToken();
    }

post.php
这只是一个例子。在每个“发布”页面中,您应该检查是否设置了 CSRF 令牌。请用方法提交您的表格POST!我还建议你看看Slim FrameworkLaravel Lumen,它们提供了一个优秀的路由系统,它可以让你很容易地只在你的“post.php”页面上接受 POST 请求(它们也会自动添加一个各种形式的 CSRF 令牌)。

if (!empty($_POST['CSRF'])) {
    if (!hash_equals($_SESSION['CSRF'], $_POST['CSRF'])) {
        die('CSRF detected.');
    }
}else{
    die('CSRF detected.');
}

view.php
现在您只需在其中放置一个带有 CSRF 会话值的隐藏输入。

<input type="hidden" name="CSRF" value="<?= $_SESSION['CSRF'] ?>">

我希望这个快速的解释可以帮助你:)

于 2017-02-15T09:23:11.743 回答