我正在使用 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 ,在某些情况下,如果我在浏览器中打开另一个选项卡以执行其他操作,这会导致问题。考虑这种情况:
- 我打开了
add.php
页面来添加一个新项目。 - 我填写了所有必填数据,但没有提交表格。
- 现在我决定在浏览器的另一个选项卡中打开
edit.php
页面来编辑现有项目。 - 然后又回到填写好的
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/