Reputation: 1184
I'm working right now on a web application which contains about 200 html forms, I'm asked to add CSRF Protection to the login and register forms only. I've enabled the CSRF Protection form the configuration file but I'll have to use the form helper library in all the 200 forms. It is obvious that it would be very exhausting to change the opening tags of the 200 forms from
<form action="user/foo" method="post" id="formId">
to
<?php echo form_open(base_url().'user/foo' array('id' => 'formId')); ?>
So, I'm wondering if there is a method which I can use to enable the csrf protection for only the register and login forms ? Thanks so much.
Upvotes: 1
Views: 4949
Reputation: 31
You can do this by editing the config.php
file :
$config['csrf_protection'] = FALSE;
if (isset($_SERVER["REQUEST_URI"])) {
if(stripos($_SERVER["REQUEST_URI"],'/login') !== FALSE || stripos($_SERVER["REQUEST_URI"],'/register') !== FALSE ) {
$config['csrf_protection'] = TRUE;
}
}
And in your view files, add this :
<input type="hidden" name="<?php echo $this->security->get_csrf_token_name(); ?>" value="<?php echo $this->security->get_csrf_hash();?>" />
Or simply use the form_open()
function to add the hidden CSRF token field automatically.
Upvotes: 3
Reputation: 2204
Yes you can, and you have two choices :
1- The easy way by just modifying "application/config.php" file like this :
$config['csrf_protection'] = FALSE;
if (isset($_SERVER["REQUEST_URI"]))
if(stripos($_SERVER["REQUEST_URI"],'/login') !== FALSE
|| stripos($_SERVER["REQUEST_URI"],'/register') !== FALSE
)
$config['csrf_protection'] = TRUE;
2- By overriding the Security Class and creating a Hook Class as follow :
2-1 application/core/My_Security.php :
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class MY_Security extends CI_Security
{
public function regenerate_csrf_hash()
{
// CSRF config
foreach (array('csrf_expire', 'csrf_token_name', 'csrf_cookie_name') as $key) {
if (false !== ($val = config_item($key))) {
$this->{'_' . $key} = $val;
}
}
// Append application specific cookie prefix
if (config_item('cookie_prefix')) {
$this->_csrf_cookie_name = config_item('cookie_prefix') . $this->_csrf_cookie_name;
}
// Set the CSRF hash
$this->_csrf_set_hash();
$this->csrf_set_cookie();
}
}
2-2 application/hooks/EnableOptions.php
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class EnableOptions {
private $ci;
public function __construct(){
$this->ci = &get_instance();
}
public function enableCSRF()
{
if ($this->ci->config->item('csrf_protection') === false) {
$uri = $this->ci->config->item('enable_csrf_for_uris_only');
$segment = $this->ci->uri->segment('1'); // 1 : for controller name
if (in_array($segment, $uri)) {
$this->ci->config->set_item('csrf_protection', true);
$this->ci->security->regenerate_csrf_hash();
}
}
}
}
2-3 application/config/hooks.php :
$hook['post_controller_constructor'][] = array(
'class' => 'EnableOptions',
'function' => 'enableCSRF',
'filename' => 'EnableOptions.php',
'filepath' => 'hooks',
'params' => array()
);
2-4 application/config/config.php : Enable the hooks by modifying "enable_hooks" to true,
$config['enable_hooks'] = TRUE;
and add an extra parameter for URIs,
$config['enable_csrf_for_uris_only'] = array('login', 'register');
That's it.
Upvotes: 2