CodeIgniter Forums

Full Version: Trouble with CSRF again (cookies?) lol
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hey there,

I just ran into a problem (again) related to CI throwing CSRF "action is not allowed" errors whenever a user tries to login to our app, but only on certain browsers and only in production.  I've been all over Google and think I even posted on this subject awhile back on this forum. 

Before I forget, here are some factors that could potentially be involved, though I wouldn't understand how or why:
  • our dev server is not public-facing
  • our production server has SSL (HTTPS) and on our dev server we use HTTP
But my best guess is that it's cookie-related.  I say this because:
  • A co-worker said he was able to get around it by going to the "create account" link and then clicking "cancel" to go back to the login screen, and THEN logging in.
  • I had a similar workaround, going into the address bar and pressing Enter to reload the page, then logging in a second time.
  • The rare scraps of info I could get off the web pointed to cookie settings, and not just CSRF settings.
  • The fact that I don't get the error on some browsers suggests it's a browser setting, like how they handle cookies.
  • And last time I checked, session data is still passed to between web clients and servers via cookies.
But unfortunately, this is sort of a non-answer.  It's cookie-related, okay, but what can be done about it?  FYI I've stuck with the default CI cookie settings (and maybe that's my problem?  lol idk).  For the purpose of the demo today that triggered this massive research effort, I disabled the CSRF protection and it worked fine.  But is that really the way to go?  All controllers that access password-protected content make sure the user is logged in first, but that wouldn't stop a CSRF attack (for obvious reasons).  It's gotten to the point where I'm considering researching another library to handle CSRF protection (and if that's the best practice, I'd appreciate any recommendations lol).

Thanks guys!
(08-15-2018, 01:49 PM)mfox Wrote: [ -> ]Hey there,

I just ran into a problem (again) related to CI throwing CSRF "action is not allowed" errors whenever a user tries to login to our app, but only on certain browsers and only in production.  I've been all over Google and think I even posted on this subject awhile back on this forum. 

Before I forget, here are some factors that could potentially be involved, though I wouldn't understand how or why:
  • our dev server is not public-facing
  • our production server has SSL (HTTPS) and on our dev server we use HTTP
But my best guess is that it's cookie-related.  I say this because:
  • A co-worker said he was able to get around it by going to the "create account" link and then clicking "cancel" to go back to the login screen, and THEN logging in.
  • I had a similar workaround, going into the address bar and pressing Enter to reload the page, then logging in a second time.
  • The rare scraps of info I could get off the web pointed to cookie settings, and not just CSRF settings.
  • The fact that I don't get the error on some browsers suggests it's a browser setting, like how they handle cookies.
  • And last time I checked, session data is still passed to between web clients and servers via cookies.
But unfortunately, this is sort of a non-answer.  It's cookie-related, okay, but what can be done about it?  FYI I've stuck with the default CI cookie settings (and maybe that's my problem?  lol idk).  For the purpose of the demo today that triggered this massive research effort, I disabled the CSRF protection and it worked fine.  But is that really the way to go?  All controllers that access password-protected content make sure the user is logged in first, but that wouldn't stop a CSRF attack (for obvious reasons).  It's gotten to the point where I'm considering researching another library to handle CSRF protection (and if that's the best practice, I'd appreciate any recommendations lol).

Thanks guys!

The first thing I always check with this kind of problem, is are you actually setting the csrf cookie name and token in the form? If you fail to do this and it might be that your cookie is not Secure, which is why this is not working.

Just a couple of thought to check.

C
Are you talking about the place in the documentation where it tells you to do this?

PHP Code:
$csrf = array(
 
       'name' => $this->security->get_csrf_token_name(),
 
       'hash' => $this->security->get_csrf_hash()
);

...

<
input type="hidden" name="<?=$csrf['name'];?>" value="<?=$csrf['hash'];?>" /> 

I know we are doing this on all our forms, and until I set $config['csrf_protection'] to FALSE I know I've seen hashes in the hidden input element... I will try re-enabling it late tonight and double-check, but as far as I know that was not the issue...

And in case it would help, here's the rest of my settings
PHP Code:
$config['csrf_protection'] = FALSE;
$config['csrf_token_name'] = 'my_csrf_token_name';
$config['csrf_cookie_name'] = 'csrf';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = FALSE;
$config['csrf_exclude_uris'] = array();
...
$config['cookie_prefix']    = '';
$config['cookie_domain']    = '';
$config['cookie_path']        = '/';
$config['cookie_secure']    = FALSE;
$config['cookie_httponly']     = FALSE

A couple things to point out:
  • As you can see, the cookie settings are all still the defaults; I didn't see anything in the documentation suggesting the need to change them, and they worked in development.  In production, our IT guys have set up an automatic redirect to HTTPS, so "cookie_secure" didn't seem necessary.  Could that be it?  Like maybe you type in "ourapp.com" and it defaults to HTTP, creates a token, then redirects and the token is invalid?  One thing I'm going to test tonight is if I get the error when explicitly typing https:// (to try to rule that out).  If that's the case, maybe just setting "cookie_secure" would fix it...
  • In the actual CSRF settings, I have "csrf_regenerate" set to FALSE.  This is because of that comment in the docs about how leaving it at TRUE can cause problems with the back button and all that.
  • Also, we do have our own token name (similar to the one I posted above in length and characters used).  One guy on Stack Overflow said his name was getting changed by CI because he had dots in it, but I ruled this one out (I think). Smile
Thanks again & have an awesome weekend!