Welcome Guest, Not a member yet? Register   Sign In
CSRF $hash Smoked
#1

(This post was last modified: 08-20-2022, 02:57 PM by Gary.)

This one is bending my brain... so I'd be grateful for some pointers, if anyone has any, thanks.


My site [which is currently using v4.2.1] is pretty much 100% JavaScript driven (in terms of user navigation).

CSRF is enabled, done via after-Filter injections into the server's responses to the client.

This part has never given any problems.

The initial landing page is delivered as a response to a GET().  It has the initial CSRF token inserted into it when the page is created, using:
Code:
<input id="csrf_token();?>" type="hidden" value="<?=csrf_hash();?>">

Presenting this on the client-side:

<input id="google_sux" type="hidden" value="b6179651bb3e12655d06c1676acb1c709dc2797771e21b6f99cd45e3a95c2b53">

This works as one would expect- and is always present on the landing page.

The JavaScript on the client returns this value (and then updates it with the (new) one from the server when it receives a response)... which works perfectly.


HOWEVER, the problem is that the very first one is never the same as what's in CI's \system\Security\Security.php's $hash value, which always results in a $security->verify($request); exception.


I've inserted a watch in the CI's Security.php code, and found that this is always the case after a landing page re-display.

This is the response after a page refresh, and then any JavaScript navigation from the freshly displayed landing page:
Code:
postedToken: b6179651bb3e12655d06c1676acb1c709dc2797771e21b6f99cd45e3a95c2b53    // <- exactly as on the <input> tag on the landing page, still to have derandomize() applied
$token: 2bd5ef26cadc090ac4cb8484c3973723    // <- after derandomize() applied
$this->hash: d57c89d72a1b542fa573560fb7ad42c8    // <- this is what it's (obviously unsuccessfully) being compared against. Where does this come from?!?

And this is the very next navigation, done moments after the one above:
Code:
$postedToken: cb5dfab7ac9e1daefca65d3da035bcbc1e2173608685498159d50b321798fe74
$token: d57c89d72a1b542fa573560fb7ad42c8
$this->hash: d57c89d72a1b542fa573560fb7ad42c8

All subsequent navigation works the same as the second one.

I've checked $security with a simple var_dump()... there doesn't seem to be any differences, between the first call and the second (and subsequent).

I was destroying $_SESSION on a fresh landing-page display, but have experimented with not destroying it, as well as creating a fresh $_SESSION.

I believe the Filters run before the BaseController is instantiated, however, on the very first call to fetch the landing page, the BaseController runs in order to display the page, so by the first JavaScript navigation, the environment is set - and is exactly the same as any subsequent navigation?!!
Help!
Reply
#2

(08-20-2022, 02:04 PM)Gary Wrote: CSRF is enabled, done via after-Filter injections into the server's responses to the client.

Why after filter?
It is set in before.
See https://codeigniter4.github.io/CodeIgnit...protection
Reply
#3

(This post was last modified: 08-22-2022, 11:29 AM by Gary.)

(08-21-2022, 05:35 PM)kenjis Wrote:
(08-20-2022, 02:04 PM)Gary Wrote: CSRF is enabled, done via after-Filter injections into the server's responses to the client.

Why after filter?
It is set in before.
See https://codeigniter4.github.io/CodeIgnit...protection

In my set-up, the check IS done in a before-Filter (when the client's request is received), however the next "active" token is only generated when the server responds with a new page (which, as I understand it, is typically inserted into the page with something like <1nput type:"hidden" name:"<?: csrf_token() ?>" value:"<?: csrf_hash() ?>" />), however, because my site is JavaScript-driven, most of the time there is no new page being created/sent, which would have the new token included.  So instead, I have the new token being injected into the server's response (for these non-HTML page responses) by an after-Filter.  This filter only generates a new token when it's a JavaScript response being sent (I have also confirmed that this after-Filter isn't (accidentally) generating a (second) fresh token when there's an HTML-inserted <input..>. being sent).

So, as best I can tell, either way, there has been a new CSRF token generated and sent to the client... which, in my understanding, would mean that the last one generated (either for the HTML <input...> insertion during the response-page creation, or by the after-Filter injection if there hasn't been a new page generated) should be the one that the before-Filter then uses for comparison against (in the before-Filter) as the server starts processing the next request?  Or do I need to have another glass of wine?
Reply
#4

You are the only one person that has this issue.
So the cause seems to be in your (after) filter.

I recommend you do step debugging and find the cause.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB