CSRF PHP 预防机制



我读过很多关于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?

多谢。

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

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

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

后.php
这只是一个例子。在每个"帖子"页面中,您应该检查是否设置了CSRF令牌。请使用POST方法提交您的表格!我还建议您查看Slim Framework或Laravel Lumen,它们提供了一个出色的路由系统,可让您非常轻松地仅在"post.php"页面上接受POST请求(它们还会自动添加每种形式的CSRF令牌)。

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

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

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

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

最新更新