【问题标题】:PHP - How to use csrf token in multiple forms on the same pagePHP - 如何在同一页面上以多种形式使用 csrf 令牌
【发布时间】:2020-08-31 01:52:57
【问题描述】:

我在同一页面上有 2 个表单。我想以两种形式使用 csrf 令牌。当我尝试使用它时,它会在提交表单时重新生成 csrf 令牌。

我该如何解决这个问题?

<?php

function csrf_token() {
    return bin2hex(random_bytes(35));
}

function create_csrf_token() {
    $token = csrf_token();
    $_SESSION['csrf_token'] = $token;
    $_SESSION['csrf_token_time'] = time();
    return $token;
}

function csrf_token_tag() {
    $token = create_csrf_token();
    return '<input type="hidden" name="csrf_token" value="' . $token . '">';
}

$csrf_token = csrf_token_tag();
?>

<form action="" method="post">
    ...
    <?= $csrf_token; ?>
</form>

<form action="" method="post">
    ...
    <?= $csrf_token; ?>
</form>

【问题讨论】:

  • 您需要对它进行限定,即:$_SESSION['tokens']['formName']['csrf_token'] 等,请参阅this
  • “重新生成 csrf 令牌”的代码或检查 csrf 的代码在哪里?

标签: php forms security session


【解决方案1】:

当您刷新页面时,函数created_csrf_token 会再次被触发,从而更改 CSRF 令牌。

正如 Lawrence 所评论的,您可以确定它的范围。例如

<?php

function csrf_token() {
    return bin2hex(random_bytes(35));
}

function create_csrf_token() {
    if (isset($_SESSION['csrf_token'])) {
        return $_SESSION['csrf_token'];
    }
    $token = csrf_token();
    $_SESSION['csrf_token'] = $token;
    $_SESSION['csrf_token_time'] = time();
    return $token;
}

function csrf_token_tag() {
    $token = create_csrf_token();
    return '<input type="hidden" name="csrf_token" value="' . $token . '">';
}

$csrf_token = csrf_token_tag();
?>

<form action="" method="post">
    ...
    <?= $csrf_token; ?>
</form>

<form action="" method="post">
    ...
    <?= $csrf_token; ?>
</form>

将 isset 添加到 create_csrf_token 将检查是否设置了 CSRF 令牌,并返回现有的,而不是创建一个新的。

您可能想要添加一些逻辑,以在大约 5 分钟后创建一个新的 CSRF 令牌。

【讨论】:

  • 感谢您的帮助!重新生成令牌的任何提示?
  • 当然,将日期存储为 $_SESSION['time'] = strtotime(date("Y-m-d h:i:s", strtotime("now"))) 之类的东西,然后在像 if (strtotime("-5 minutes") &gt; $_SESSION['time']) 这样的 isset 中/之前进行比较,重新生成 CSRF
  • 再次感谢!我做了类似的事情:if (!isset($_SESSION['csrf_token']) || strtotime('-5 minutes') &gt; $_SESSION['csrf_token_time']) // generate a new token 如果此条件不成立,则返回相同的令牌。
  • 我看不出它是如何工作的;会议从未开始。
  • @FunkFortyNiner 它有效!我们会在 5 分钟后重新生成令牌,或者如果没有 CSRF 令牌
猜你喜欢
  • 2021-02-01
  • 2016-02-25
  • 2019-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 2021-06-19
  • 1970-01-01
相关资源
最近更新 更多