【问题标题】: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 的主题。

标签: php jquery ajax csrf


【解决方案1】:

这就是您所需要的。此代码来自 Stackoverflow.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();

【讨论】:

    猜你喜欢
    • 2017-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    • 2015-07-08
    • 2017-01-10
    • 2016-12-26
    • 2014-06-02
    相关资源
    最近更新 更多