跨站请求伪造攻击的表单安全性

Posted

技术标签:

【中文标题】跨站请求伪造攻击的表单安全性【英文标题】:Form security for cross site request forgery attacks 【发布时间】:2019-03-24 16:26:39 【问题描述】:

我正在尝试防止跨站点请求伪造攻击 (CRFS)。 下面是我在 login.php 上的令牌生成器代码。 这是否足够安全,可以根据会话令牌验证表单的 csrf 令牌?

if(empty($_SESSION['key']))
    $_SESSION['key'] = bin2hex(random_bytes(32));

$csrf = hash_hmac('sha256','secured:login',$_SESSION['key']);

这是我在 login.php 上的表单代码 -

<form action="<?php echo htmlspecialchars('log/logscript.php');?>" method="post" class="login_form">
    <input type="hidden" name="csrf" id="csrf" value="<?php echo $csrf;?>">
    <input type="submit" class="btn btn-login btn-block" name="submit" id="submit" value="Login">
</form>

这是我的 AJAX 代码 -

$(".login_form").submit(function(e) 
        e.preventDefault();
        var 
            sk = "<?php $csrf;?>",
            fk = $("#csrf").val(),
            t = $("#submit").val();
        $.ajax(
            url: "log/logscript.php",
            type: "post",
            data: 
                sk: sk,
                fk: fk,
                submit: t
            ,
            success: function(e) 
                $(".form-msg").html(e)
            
        );
    );

这是我在 log/logscript.php 上的代码 -

session_start();
if(isset($_POST['submit']))
    $x = $_POST['sk'];
    if(hash_equals($x,$_POST['fk']))
        echo 'success';
    else 
        echo 'failed';
    

【问题讨论】:

你的问题是什么? 是否足够安全,可以使用会话令牌验证表单的 csrf 令牌? 更新您的问题 还不够吗? 我投票决定将此问题作为离题结束,因为它要求进行代码审查(因此这太宽泛/基于意见)。它可能会被调整为the code review stackexchange 的主题。 【参考方案1】:

这就是您所需要的。此代码来自 ***.com。这是我在大多数项目中使用的。

<?php
 session_start();
 $token= md5(uniqid());
 $_SESSION['update_token']= $token;
 session_write_close();
?>
<html>
<body>
<form method="post" action="update.php">
 <input type="hidden" name="token" value="<?php echo $token; ?>" />
Do you really want to delete?
<input type="submit" value=" Yes " />
<input type="button" value=" No " onclick="history.go(-1);" />
</form>
</body>
</html>

 save.php

<?php
 session_start();
 $token = $_SESSION['update_token'];
 unset($_SESSION['update_token']);
 session_write_close();
 if ($token && $_POST['token']==$token) 
   // update the record
  else 
   // there is CSRF attack.
 
?>

此外,还要确保在登录用户通过身份验证后立即重新生成会话 ID。

//重新生成Session Id,保证Session Fixation Attack是不可能的……

session_regenerate_id();

【讨论】:

以上是关于跨站请求伪造攻击的表单安全性的主要内容,如果未能解决你的问题,请参考以下文章

CSRF跨站请求伪造的安全防护

安全测试之跨站请求伪造(CSRF)攻击

Web安全- 跨站请求伪造CSRF

Web安全之跨站请求伪造漏洞

web安全之CSRF(跨站域请求伪造)攻击详解应对和测试

安全牛学习笔记CSRF跨站请求伪造攻击漏洞的原理及解决办法