Uniform - CSRF rejection

Hey there,

i’ve implemented the ajax-example as shown in the docs: http://kirby-uniform.readthedocs.io/en/latest/examples/ajax/

The kirby()->request()->data():

Array
(
    [inputName] => thename
    [inputPhone] => thephone
    [inputDeparture] => thedeparture
    [csrf_token] => UPae8HIHULcT77VI0FuRqTnrWqistUt0T5BvKFMmgobSEijMgVyIRDXU4TPBKx17
    [website] => 
)

Raised exeption sais: Exception: The CSRF token was invalid.

My javascript is copied 1:1.
The Form-Markup looks like this:

<form id="booking-container" class="columns" action="/uniform/tourbooking" method="POST">
...
<input type="text" id="inputPhone" name="inputPhone">
<label for="inputPhone">Phone</label>
...
<?= csrf_field() ?>
<?= honeypot_field() ?>
<input type="submit" value="Submit">
<p id="message"></p>

(i also disabled the kirby cache)

Thanks for your help, i become desperate!
Sven

Maybe @mzur can help?

Could you please check the requests in your browser’s development tools. Maybe there is a request that results in the token being regenerated, invalidating the old one.

Hey, thanks for the reply!

Request URL:http://example.de/uniform/tourbooking
Request Method:POST
Status Code:500 Internal Server Error
Remote Address:[::1]:80
Response Headers
view source
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:close
Content-Type:text/html;charset=UTF-8
Date:Mon, 13 Mar 2017 10:51:43 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Pragma:no-cache
Server:Apache
Set-Cookie:kirby_session=ec320ca6a5b360828d2aa42cb557c574; path=/; httponly
Transfer-Encoding:chunked
X-Powered-By:PHP/5.6.10
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:no-cache
Connection:keep-alive
Content-Length:737
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryshSMx4OG1BY1Orcu
Cookie:kirby_session_auth=71cb1f7c24b84678a85ec4025067ef4f037f22d8%2BUxSxOyFO6UuQaRAogxm6pxdrIXEwjI9zfWfRIYRNsSXGyqQ7CNf6rSBNJFvPcDfP; resolution=1920; kirby_session=ec320ca6a5b360828d2aa42cb557c574
Host:example.de
Origin:example.de
Pragma:no-cache
Referer:example.de/tours/example/tourname
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Request Payload
------WebKitFormBoundaryshSMx4OG1BY1Orcu
Content-Disposition: form-data; name="inputName"

entered-name
------WebKitFormBoundaryshSMx4OG1BY1Orcu
Content-Disposition: form-data; name="inputPhone"

entered-phone
------WebKitFormBoundaryshSMx4OG1BY1Orcu
Content-Disposition: form-data; name="inputDeparture"

------WebKitFormBoundaryshSMx4OG1BY1Orcu
Content-Disposition: form-data; name="csrf_token"

fFGO6vy5gTRus57RXcttdhtVfR9QCSZeoCfVx4XUoFBzoOgczwgCVh5CnXKzEcAp
------WebKitFormBoundaryshSMx4OG1BY1Orcu
Content-Disposition: form-data; name="website"


------WebKitFormBoundaryshSMx4OG1BY1Orcu--

Thats the request. What else do you want me to do?

Best,
Sven

What I thought was more along the lines of checking the network tab for possible duplicate requests, because of missing favicons or similar.

I get only 200 responses.

A duplicate request that invalidates the old token would get a code 200, too. Can you post a screenshot of all requests displayed in the network tab?

For now, i know how to make the form work, but this disables the csrf-functionality of course:
uniform/vendor/mzur/kirby-form/src/Form.php: uncomment the csrf-statement.

Here is the whole network-log. I pixelated some private information:

and of course the actually 500 request:

Thanks for your help!

What about the “map” xhr request and the pixelated text/html? Are these other Kirby pages that might regenerate the CSRF token?

map is a children-page which is called via XHR. If this is not compatible, i have to think of another way :frowning:

Can you try if the form works when map is not called?

Okay, the form still does not work when i remove the map-XHR call.

And where does the other text/html request go? Generally we’re looking for a place where csrf() might be called again. Are you sure that this is the only place where csrf() or csrf_field() is called? You can confirm the CSRF mismatch by comparing s::get('csrf') with the token in the request data.

Hey mzur,

i solved the problem. I found out that in some cases the url in

style=“background-image: url()”…

was empty. This seemed to call the site once again.

Thanks for your help!

Do you know why this happens?

Best,
Sven

Well, that depends on the code you use to print that background image URL. Could you please post that code snippet?

`<div id="<?= $id ?>" class="<?= $class ?>"

<?php if(!empty($src)): ?>

style=“background-image: url(<?= $src; ?>);”>

<?php endif; ?>`

Thats the Workarround. Sometimes $src ist empty. If so, the generated markup looks like this:
<div id="the-id" class="the-classname" style="background-image: url()">

Yes, that makes sense. :slight_smile:
Your new code should work fine.

1 Like

This is exactly the kind of thing that I was expecting. But a url() in the CSS should result in duplicate requests to the current page showing up in the network log. I wonder why there weren’t any :thinking: