Reputation: 1004
I am currently using Codeigniter and like to enable in the config.php:
$config['cookie_secure'] = TRUE;
I am also using:
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = '***';
$config['csrf_cookie_name'] = '***';
$config['csrf_expire'] = 7200;
The connection is https only. But when I am using the cookie_secure option, the CSRF is not working any more and gives this:
The action you have requested is not allowed.
Codeigniter cannot store the CSRF in an cookie because of this measure. How can I solve it? I like to use both security measures.
<--- EDIT --->
<form action="<?php echo base_url().'login/'; ?>" method="post">
<?php echo form_hidden($this->security->get_csrf_token_name(), $this->security->get_csrf_hash()); ?>
Upvotes: 0
Views: 1613
Reputation: 3116
If you want to solve this CODEIGNITER BUG, you can set like below:
$config['sess_cookie_name'] = 'ci_projectname_session';
...
...
$config['cookie_prefix'] = 'ci_projectname_';
As example above, cookie prefix and cookie name must begin as same.
Upvotes: 0
Reputation: 11
I was running into the same issue when I had both cookie_secure
set to true and csrf_protection
set to true.
What I first noticed was the CSRF cookie wasn't being set.
Looking at the csrf_set_cookie()
function in /system/core/Security.php
, you'll see:
/**
* 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;
}
Though, like most, I use a load balancer for SSL termination. The individual servers don't know the traffic is over HTTPS, since the traffic is sent to each server over port 80 on the internal network. This is what the HTTP_X_FORWARDED_PROTO
is for.
I ended up overwriting the csrf_set_cookie()
in my /application/core/MY_Security.php
to fix this:
/**
* 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;
}
Upvotes: 1
Reputation: 708
It looks like this may handle the problem, make sure you have form_open()
in your code. Per the documentation on codeigniter form helper,
Creates an opening form tag with a base URL...
This should also add the csrf automatically without form_hidden()
.
Upvotes: 0