CodeIgniter Forums
CSRF token expired when page is left open - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: CodeIgniter 4 (https://forum.codeigniter.com/forumdisplay.php?fid=28)
+--- Forum: CodeIgniter 4 Support (https://forum.codeigniter.com/forumdisplay.php?fid=30)
+--- Thread: CSRF token expired when page is left open (/showthread.php?tid=89114)



CSRF token expired when page is left open - gabriel_fucci - 01-09-2024

Hello!

When a user enters a page that has a form, if he spends a lot of time with that page open and tries reload the page, it will throw a security exception. In the app/Config/Security.php file there is an expiration set at the default 7200(2 hours). Is there any solution other than increasing these seconds so that when this time passes, and the user re-enters the page, reload the page from the beginning so as not to throws a security exception???


RE: CSRF token expired when page is left open - ozornick - 01-09-2024

Disable regenerate tokens https://codeigniter4.github.io/userguide/libraries/security.html#token-regeneration


RE: CSRF token expired when page is left open - gabriel_fucci - 01-10-2024

(01-09-2024, 11:40 PM)ozornick Wrote: Disable regenerate tokens https://codeigniter4.github.io/userguide/libraries/security.html#token-regeneration
It's already disabled. The problem is the expiration after 2 hours. Some users forget the page open and then go back to try submit the form. If i enable the redirect config in security class, does it prevent exception from being throw??


RE: CSRF token expired when page is left open - ozornick - 01-10-2024

I don't remember, but it will refresh the page and may reset the entered data. Tried.


RE: CSRF token expired when page is left open - Valkhan - 01-17-2024

I'm facing the same issue with CI 4.4.0, I've turned on an error monitoring and this is bloating my reports with unhandled errors.

Well, I took some time to understand how the framework validates the CSRF token and I was shocked that despite having an "expires" config, if does not check the expiration of the token while validatin the CSRF token:

The verify method:
/**
* CSRF Verify
*
* @return $this
*
* @throws SecurityException
*/
public function verify(RequestInterface $request)
{
// Protects POST, PUT, DELETE, PATCH
$method = strtoupper($request->getMethod());
$methodsToProtect = ['POST', 'PUT', 'DELETE', 'PATCH'];
if (! in_array($method, $methodsToProtect, true)) {
return $this;
}

$postedToken = $this->getPostedToken($request);

try {
$token = ($postedToken !== null && $this->tokenRandomize)
? $this->derandomize($postedToken) : $postedToken;
} catch (InvalidArgumentException $e) {
$token = null;
}

// Do the tokens match?
if (! isset($token, $this->hash) || ! hash_equals($this->hash, $token)) {
throw SecurityException::forDisallowedAction();
}

$this->removeTokenInRequest($request);

if ($this->regenerate) {
$this->generateHash();
}

log_message('info', 'CSRF token verified.');

return $this;
}

As we can see, the postedToken received by the request is checked only if it's equals to the current hash.

I tried using regenerate = true and tokenRandomize = true, but to no avail, i've set the expires to 10s and the hash didn't get regenerated after multiple page refresh;

I'm not certain if CSRF is fully functional at this point after testing this behavior, now i'm worried.


What I was trying to achieve is to instead of throwing an error (exception) I would handle the error by returning a 403 failed response and that would solve the issue of expired tokens bloatin my error monitor.

It would be nice to have an entry point to handle errors caught on filters, but I do not have knowledge if that feature exists.

After some testing, the only fix I found was to enable csrfProtection = session because when the session expires the hash wil be regenrated, and then my solution worked.


RE: CSRF token expired when page is left open - kenjis - 01-17-2024

Quote:If you use Session, be sure to use Session based CSRF protection. Cookie based CSRF protection will not prevent Same-site attacks. See GHSA-5hm8-vh6r-2cjq for details.
https://www.codeigniter.com/user_guide/libraries/security.html#csrf-protection-methods



RE: CSRF token expired when page is left open - kenjis - 01-17-2024

(01-17-2024, 09:44 AM)Valkhan Wrote: What I was trying to achieve is to instead of throwing an error (exception) I would handle the error by returning a 403 failed response and that would solve the issue of expired tokens bloatin my error monitor.

It would be nice to have an entry point to handle errors caught on filters, but I do not have knowledge if that feature exists.

You can create your own CSRF filter based on the framework CSRF filter:
https://github.com/codeigniter4/CodeIgniter4/blob/0788018f2c764b65afc531afd0a2b7f4780e0b42/system/Filters/CSRF.php#L55-L63
and see https://www.codeigniter.com/user_guide/incoming/filters.html#creating-a-filter