Php 一个令牌与多个令牌以防止CSRF攻击
我正在使用Codeigniter,我想防止可能发生的CSRF攻击尝试。为了实现这一点,我向我想要保护的每个表单添加了一个带有随机标记的隐藏输入标记,同时我将该标记保存在会话中,以便在开始处理该表单数据时进行比较Php 一个令牌与多个令牌以防止CSRF攻击,php,codeigniter,security,csrf,Php,Codeigniter,Security,Csrf,我正在使用Codeigniter,我想防止可能发生的CSRF攻击尝试。为了实现这一点,我向我想要保护的每个表单添加了一个带有随机标记的隐藏输入标记,同时我将该标记保存在会话中,以便在开始处理该表单数据时进行比较 // set a token to prevent CSRF attacks $csrf_token = md5(uniqid(rand(), true)); $this->session->set_userdata("csrf_token", $csrf_tok
// 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>
// 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!!");
}
这很有效。但正如您所看到的,我为每个包含表单的页面生成了一个随机标记,在某些情况下,如果我打开浏览器中的另一个选项卡以执行其他操作,就会导致问题。考虑这种情况:
add.php
页面添加了一个新项目李>
edit.php
页面来编辑现有项目add.php
页面,并尝试提交数据此时,我将得到一个错误,因为当我打开
add.php
页面时,存储在会话中的令牌的值已被更改,并在我打开edit.php
页面时被另一个令牌替换。那么我如何解决这个问题呢?当每个用户成功登录时,我是否应该为他生成一个令牌,然后在他可能处理的所有页面中使用该令牌?这种方法有任何风险或缺点吗?我浏览了你的帖子,没有发现不使用基本codeigniter CSRF保护的原因?看起来您正在重新发明轮子,并产生标准实现中不存在的问题
更不用说你试图在每一张表单上打印你的代币,这违反了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;
为了解决这个问题,您可以创建一个具有唯一密钥的令牌字符串,并将密钥/令牌对存储在会话中(作为CodeIgniter中的userdata) 考虑到这种情况,您将需要以下步骤:
元素$csrf\u key=“令牌”。mt_rand(0,mt_getrandmax());
$csrf_token=hash(“sha512”,mt_rand(0,mt_getrandmax());
//在会话中存储密钥/令牌对
$this->session->set_userdata($csrf_key,$csrf_token);
添加隐藏的input
s:
不要使用rand()
-出于安全目的,它不够随机。@SilverlightFox您建议使用什么替代方法?是否有任何理由在没有任何理由的情况下否决此答案?至少要说明原因。我看不出有什么理由重新发明轮子。谷歌搜索显示最糟糕的问题是IE8/9,codeigniter 2+解决了大部分问题。@DavidDuncan别担心,我对你的答案投了赞成票。