I've been using CodeIgniter version 2.1.4 with Ion Auth for quite some time and everything was working great. Yesterday, I updated Ion Auth to the latest version and now I get a CSRF error whenever I try to "edit" any user profile.
"This form post did not pass our security checks."
I get this error after modifying the controllers/auth.php
file so that the various Ion Auth views are loaded into my own template. After all, what good is this if I cannot integrate it into my site design. However, I also get this error in an older version of Safari even when the auth.php
controller is not modified at all.
This is my simple modification to the auth.php
controller file.
Replaced this line:
$view_html = $this->load->view($view, $this->viewdata, $render);
With this line:
$view_html = $this->template->load('default', $view, $this->viewdata, $render);
Yes, my load
function (in the Template.php
file located in /libraries/
) has been working just fine since the beginning (many months ago). Even with the new version of Ion Auth, my template loading function is working... however, I just keep getting the security error as described above.
After doing some research, the cause of the error is Ion Auth's CSRF security routine. These two functions are called throughout the auth.php
controller and display the error above whenever the _valid_csrf_nonce()
function returns false
.
function _get_csrf_nonce()
{
$this->load->helper('string');
$key = random_string('alnum', 8);
$value = random_string('alnum', 20);
$this->session->set_flashdata('csrfkey', $key);
$this->session->set_flashdata('csrfvalue', $value);
return array($key => $value);
}
function _valid_csrf_nonce()
{
if ($this->input->post($this->session->flashdata('csrfkey')) !== FALSE &&
$this->input->post($this->session->flashdata('csrfkey')) == $this->session->flashdata('csrfvalue'))
{
return TRUE; // <-- no error
}
else
{
return FALSE; // <-- error
}
}
As a temporary (or permanent?) workaround, I've enabled the "CSRF Protection" option on line 298 in the CodeIgniter config/config.php
file.
$config['csrf_protection'] = TRUE; // enabled CSRF protection
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
Then I suppressed the CSRF protection in Ion Auth by always returning true
from the function.
function _valid_csrf_nonce()
{
return TRUE;
}
However, I really want to understand the root cause here. Why am I getting all these CSRF errors simply by using older browsers or by trying to put the Ion Auth views within my own templates? Everything is on the same server using the same domain.
(edit: yes, the CI session
library is being auto-loaded and apparently working fine. I can stay logged in, after all.)
I never did get to the root cause, however I have a theory that might explain some of this:
The Ion Auth CSRF Protection depends on flashdata
, where flashdata
only survives "the next" call to the server. My custom template loader might be calling the server twice since it first calls my loader function where the page is constructed, and then calls CodeIgniter's view function.
However, this theory does not really explain why an unmodified version of Ion Auth still fails in Safari. Feel free to post another answer if you can add anything substantial or conclusive to this.
As per a personal response from Ben Edmunds, the developer of Ion Auth...
"We added CSRF protection to the Ion Auth examples before CI built them into the framework so you might be best just removing them from the Ion Auth example controller and views if you’re using a newer version of CI with that built in."
Since I'm already using the latest version of CodeIgniter (2.1.4), I've decided to go this route.
The temporary workaround from my OP is now permanent:
I've enabled the "CSRF Protection" option on line 298 in the CodeIgniter config/config.php file.
$config['csrf_protection'] = TRUE; // enabled CSRF protection
Then I suppressed the CSRF protection in Ion Auth by always returning true
from this function.
function _valid_csrf_nonce()
{
return TRUE; // effectively disables Ion Auth's CSRF protection
}
And finally, the developer commenting on using CodeIgniter's CSRF protection instead:
"Cool, that's really a better solution anyway since it's integrated throughout your application."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With