Only check the request token for master requests #2204
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
If you have a form on a page and a fragment element after the form, and if, during the POST request, the form does not validate, hence the form does not throw a
RedirectException
and rendering of the page continues, theRequestTokenListener
will be executed for the subsequent sub-requests for fragments, where the session will be set (due to the failing form before), but no CSRF Token will be present and thus the listener will throw theInvalidRequestTokenException
.Reproduction
1. Create a form
1.1. Create a form and disable its HTML5 validation.
1.2. Create a single text field and make it mandatory.
1.3. Create a submit button.
1.4. Insert the form on a page via a form include content element.
2. Create a fragment content element
Create a content element of type
example_element
after (❗) the form include element.3. Execute the POST request
3.1. Open a private browsing window, or clear all cookies for the domain of your Contao installation.
3.2. Open the page in the front end where the form and fragment is included.
3.3. Submit the form without any input in the text element.
This will show the invalid request token error in the front end.
Cause
Usually
\Contao\Form
will either reload the current page or redirect to a new page, thus halting execution. However, when a form field does not validate, thePOST
request continues and the remaining fragments are rendered. Since the fragments are rendered via sub-requests, thekernel.request
event is dispatched for each sub-request, thus also triggering theRequestTokenListener
again. But by this point,\Contao\Form
has initiated a session and therefore fulfilling all of the conditions for the request to require a valid request token - if the fragment is rendered with theforward
renderer (which Contao Content Element fragments are by default), because those fragments get a full duplicate of the original request. Of course no request token will be present in the request, since no request token was necessary yet before thePOST
request was initiated.Solution
As discussed with @Toflar in Slack, the
RequestTokenListener
should probably check whether the request is actually a master request. Thus in this PR I have added this in the beginning of the listener.