我目前正在使用Codeigniter,并希望在config.php中启用:
$config['cookie_secure'] = TRUE;
我也在使用:
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = '***';
$config['csrf_cookie_name'] = '***';
$config['csrf_expire'] = 7200;
该连接仅为https。但当我使用cookie_secure选项时,CSRF不再工作,并给出以下信息:
The action you have requested is not allowed.
由于此措施,Codeigniter无法将CSRF存储在cookie中。我该如何解决?我喜欢同时使用这两种安全措施。
<---编辑--->
<form action="<?php echo base_url().'login/'; ?>" method="post">
<?php echo form_hidden($this->security->get_csrf_token_name(), $this->security->get_csrf_hash()); ?>
当cookie_secure
设置为true且csrf_protection
设置为true时,我遇到了相同的问题。
我首先注意到的是CSRF cookie没有设置。
查看/system/core/Security.php
中的csrf_set_cookie()
函数,您将看到:
/**
* Set Cross Site Request Forgery Protection Cookie
*
* @return object
*/
public function csrf_set_cookie()
{
$expire = time() + $this->_csrf_expire;
$secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;
if ($secure_cookie && (empty($_SERVER['HTTPS']) OR strtolower($_SERVER['HTTPS']) === 'off'))
{
return FALSE;
}
setcookie($this->_csrf_cookie_name, $this->_csrf_hash, $expire, config_item('cookie_path'), config_item('cookie_domain'), $secure_cookie);
log_message('debug', "CRSF cookie Set");
return $this;
}
不过,和大多数人一样,我使用负载均衡器进行SSL终止。各个服务器不知道流量是通过HTTPS的,因为流量是通过内部网络上的端口80发送到每个服务器的。这就是HTTP_X_FORWARDED_PROTO
的作用。
我最终覆盖了/application/core/MY_Security.php
中的csrf_set_cookie()
来修复这个问题:
/**
* Set Cross Site Request Forgery Protection Cookie
*
* @return object
*/
public function csrf_set_cookie()
{
$expire = time() + $this->_csrf_expire;
$secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;
if (
$secure_cookie &&
(empty($_SERVER['HTTPS']) OR strtolower($_SERVER['HTTPS']) === 'off') &&
(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] != 'https')
) {
return FALSE;
}
setcookie($this->_csrf_cookie_name, $this->_csrf_hash, $expire, config_item('cookie_path'), config_item('cookie_domain'), $secure_cookie);
log_message('debug', "CRSF cookie Set");
return $this;
}
看起来这可能会处理这个问题,请确保代码中有form_open()
。根据代码点火器表单助手上的文档
创建具有基本URL的打开表单标记。。。
这也应该在没有form_hidden()
的情况下自动添加csrf。
如果你想解决这个CODEIGNITER BUG,你可以设置如下:
$config['sess_cookie_name'] = 'ci_projectname_session';
$config['cookie_prefix'] = 'ci_projectname_';
如上所述,cookie前缀和cookie名称的开头必须相同。