php - 一个 token 与多个 token 以防止 CSRF 攻击

标签 php codeigniter security csrf

我正在使用 Codeigniter,我想防止可能发生的 CSRF 攻击尝试。为了实现这一点,我向每个我想要保护的表单添加了一个带有随机 token 的隐藏输入标签,同时我将这个 token 保存在一个 session 中,以便与开始处理此表单数据的时间进行比较。

  // set a token to prevent CSRF attacks
  $csrf_token = md5(uniqid(rand(), true));
  $this->session->set_userdata("csrf_token", $csrf_token);

表格看起来像这样:

<form action="path/to/handler/page" method="post">
    <input type="text" name="title">
    <input type="text" name="date">
    <textarea name="content"></textarea>
    <input type="hidden" name="csrf_token" value="<?php echo $this->session->userdata("csrf_token") ?>"> 
    <input type="submit" name="submit" value="Save"> 
</form>

在我处理提交数据的页面中,我检查 CSRF 攻击是这样的:

  // make sure there is no CSRF attack attempt
  $csrf_token = $this->session->userdata("csrf_token");
  if (empty($csrf_token) || $csrf_token !== $this->input->post("csrf_token")) {
    die("Some message here!!");
  }

而且效果很好。但是正如您所见,我为每个包含表单的页面生成一个随机 token ,在某些情况下,如果我在浏览器中打开另一个选项卡以执行其他操作,这会导致问题。考虑这种情况:

  1. 我打开了 add.php 页面来添加一个新项目。
  2. 我填写了所有必填数据,但没有提交表格。
  3. 现在我决定在浏览器的另一个选项卡中打开 edit.php 页面来编辑现有项目。
  4. 然后又回到填写好的add.php页面,尝试提交数据。

此时我会得到一个错误,因为当我打开 add.php 页面时存储在 session 中的 token 值已被更改并在我打开 edit.php 页面。那么我该如何解决这个问题呢?当每个用户成功登录时,我是否应该只为他生成一个 token ,然后在他可能处理的所有页面中使用这个 token ?这种方法有任何风险或缺点吗?

最佳答案

我扫描了您的帖子,没有看到不使用基本 codeigniter CSRF 保护的原因?看起来您正在重新发明轮子并制造其标准实现中不存在的问题。

更不用说您通过尝试将您的 token 打印到每个表单而违反了 DRY 原则。为什么不保持简单?

Codeigniter 内置了 CSRF 保护,可以在/application/config/config.php 中启用

$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_token_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;

关于php - 一个 token 与多个 token 以防止 CSRF 攻击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20587746/

相关文章:

PHP退出for循环的正确方法

php - PDO 微软访问

PHP面向对象的foreach循环

java - 如何在 Java 中启用启用 SecurityManager 的情况下创建 newInstance

php - ZF : How to add default prefix path to form elements so I don't have to set it everytime?

php - 查询经纬度范围内的记录

javascript - Codeigniter:动态更改语言 (AJAX)

javascript - Datatable contenteditable问题导致scrollX

php定时器只允许用户每两秒输入一次

javascript - 在远程加载的 javascript 中使用 document.write 写出内容——为什么是个坏主意?