Bug #61664
closedError "&cHash comparison failed" in case of POST forms
Added by Dirk Wildt almost 10 years ago. Updated over 9 years ago.
0%
Description
The cHash calculation fails in TYPO3 6.2.1 - 6.2.4, if params are sent by a POST form.
The cause is, that the method- typo3_src-6.2.4/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php::makeCacheHash
respects GET params only and ignores POST params.
This can fix by moving from _GET to _GP in the method. See (nearby line 2270):
...
public function makeCacheHash() {
// No need to test anything if caching was already disabled.
if ($this->no_cache && !$this->TYPO3_CONF_VARS['FE']['pageNotFoundOnCHashError']) {
return;
}
// dwildt, 1-
//$GET = GeneralUtility::_GET();
// dwildt, 1+
$GET = GeneralUtility::_GP();
if ($this->cHash && is_array($GET)) {
...
Updated by Helmut Hummel almost 10 years ago
- Status changed from New to Needs Feedback
Dirk Wildt wrote:
The cHash calculation fails in TYPO3 6.2.1 - 6.2.4, if params are sent by a POST form.
Please give an example what exactly fails for you.
Updated by Dirk Wildt almost 10 years ago
Dear Helmut,
If I send params including a proper cHash value by a POST form, TYPO3 throws this error:
Page Not Found
Reason: Request parameters could not be validated (&cHash empty)
If I move the form method from POST to GET the TYPO3 cHash comparison is proper.
It seems, that there is a bug in the code of the TypoScriptFrontendController class (see above).
The code evaluates GET params only.
- with form method GET
- and with form method POST
I would be happy, if my report is clear :)
Thanks for your quick response.
Dirk
Updated by Xavier Perseguers almost 10 years ago
Is it possible for you to show us a minimal code sample (controller/view/special TS configuration/...) on how to reproduce the problem?
Updated by Dirk Wildt almost 10 years ago
I read your post at
Does it mean, I must send a form with the method GET and method POST is unpossible, because cHash comparison failed?
And if yes, would it be nice, to add a tip to the error message of the TypoScriptFrontendController class like
Page Not Found
Reason: Request parameters could not be validated (&cHash empty)
Be aware: Parameters must be send by the form method GET
Kind regards
Dirk
Updated by Stefan Neufeind almost 10 years ago
You have the form-tag auto-generated by Extbase I guess? Or do you generate that yourself?
Updated by Dirk Wildt almost 10 years ago
Dear Helmut, dear Xaviar,
this is a code snippet for rreproducing the problem:
Form with method GET works proper:
<form name="form_confirm" method="GET"> <fieldset> <legend> Start the Installation </legend> <input type="hidden" name="tx_orginstaller_pi1[confirm]" value="1" /> <input type="hidden" name="cHash" value="5416c8c16f8ea7d9823472d0ff373d39" /> <input type="submit" name="submit" value=" Install it! " /> </fieldset> </form>
Form with method POST throws the error "...could not be validated (&cHash empty)" from above:
<form name="form_confirm" method="POST"> <fieldset> <legend> Start the Installation </legend> <input type="hidden" name="tx_orginstaller_pi1[confirm]" value="1" /> <input type="hidden" name="cHash" value="5416c8c16f8ea7d9823472d0ff373d39" /> <input type="submit" name="submit" value=" Install it! " /> </fieldset> </form>
The cHash value is calculated in both samples (GET and POST):
$cacheHash = t3lib_div::makeInstance('t3lib_cacheHash'); $cHash = $cacheHash->generateForParameters('&tx_orginstaller_pi1[confirm]=1&submit= Install it! ');
Kind regards
Dirk
Updated by Dirk Wildt almost 10 years ago
Be ware, the generated cHash value depends on the encryption key of your TYPO3 installation.
If you like to reproduce the error, you have to generate your cHash value first an replace my given value with yours.
Updated by Xavier Perseguers almost 10 years ago
- POST action should not get cached since POST means a change is going on, do you experience a problem if you don't have a cHash?
- cHash is meant to validate the parameters and prevent caching problems, thus when using a GET request
As such there should be no need to provide a cHash with POST requests and as you see it makes no sense to validate POST parameters.
And do not forget that best practices redirect (as GET) to some "confirmation page" or alike and do not output HTML response right away when doing a POST request.
Updated by Stefan Neufeind almost 10 years ago
For the form you mentioned: I guess for now you'd need to put the cHash into the URL (as part of the "action") for it to be recognised, instead of sending it as part of the POST.
I agree that using POST and caching is usually a strange combination. Should we maybe consider avoiding to cache POST-requests? Or give a warning of some sort if some plugin tries to use POST with something that involves caching? Maybe that helps more than complaining about a wrong/missing cHash in that case.
Updated by Marc Bastian Heinrichs almost 10 years ago
Stefan Neufeind wrote:
For the form you mentioned: I guess for now you'd need to put the cHash into the URL (as part of the "action") for it to be recognised, instead of sending it as part of the POST.
Yeah, but only, if you have get vars in your action url. If you send by POST without getvars in the url, simple remove the cHash!
Updated by Marc Bastian Heinrichs almost 10 years ago
I agree that using POST and caching is usually a strange combination. Should we maybe consider avoiding to cache POST-requests?
In general? Why that? Should be enough to be aware of not caching the content the POST is sent for.
Updated by Dirk Wildt almost 10 years ago
I agree that using POST and caching is usually a strange combination.
I agree too.
But maybe there is a problem in principle:- $TYPO3_CONF_VARS['FE']['pageNotFoundOnCHashError'] is true by default.
- typo3_src-6.2.4/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php::makeCacheHash doesn't respect the no_cache parameter, if pageNotFoundOnCHashError is true
- Effect is, you can't use a POST form without any caching but you disable pageNotFoundOnCHashError.
Code snippet from TypoScriptFrontendController.php::makeCacheHash
public function makeCacheHash() { // No need to test anything if caching was already disabled. if ($this->no_cache && !$this->TYPO3_CONF_VARS['FE']['pageNotFoundOnCHashError']) { return; }I want be able to use both:
- pageNotFoundOnCHashError = true
- A POST form without any caching
Why it isn't possible?
Or do I have a knot in my brain?
Updated by Dirk Wildt almost 10 years ago
If a request should not cached in case of the POST method, would be this a possible improvement
in typo3_src-6.2.4/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php::makeCacheHash?
Current code:
public function makeCacheHash() { // No need to test anything if caching was already disabled. if ($this->no_cache && !$this->TYPO3_CONF_VARS['FE']['pageNotFoundOnCHashError']) { return; } ...
Improved code:
public function makeCacheHash() { // #61664, 140917, dwildt, 5+ // No need to test anything if params are sent by POST method. $POST = GeneralUtility::_POST(); if (is_array($POST)) { return; } // No need to test anything if caching was already disabled. if ($this->no_cache && !$this->TYPO3_CONF_VARS['FE']['pageNotFoundOnCHashError']) { return; } ...
Updated by Helmut Hummel almost 10 years ago
- Status changed from Needs Feedback to Rejected
Dirk Wildt wrote:
I want be able to use both:
- pageNotFoundOnCHashError = true
- A POST form without any caching
Why it isn't possible?
It is possible.
Or do I have a knot in my brain?
Yes.
- TYPO3 only knows a page cache, where the complete rendered output of a page is cached.
- You can only have on cache entry per page id.
- There are some exceptions to this rule, one is: a valid cHash parameter is provided as GET parameter. This triggers a different cache entry.
- There is also a concept of cached and not cached plugins (USER vs. USER_INT). A USER_INT is never cached, although the surrounding page HTML is cached.
You can achieve what you want likewise (in Extbase terms):
indexAction -> is cached and renders form. The form action attribute has a URI to the update action with a valid cHash. The URI contains only one argument that triggers the updateAction in your plugin
updateAction -> is not cached (USER_INT) It can recieve arbitrary arguments via POST
So what you want to achieve is possible and nothing needs to be done in the TYPO3 core
Updated by Helmut Hummel almost 10 years ago
One additional note here:
If you have question on the topics cHash or USER_INT, feel free to ask on the dev list.
Updated by Dirk Wildt almost 10 years ago
Dear Helmut,
Thanks a lot for your engagement.
Kind regards
Dirk
Updated by Stefan Neufeind over 9 years ago
Had the same issue. Setting the plugin, the whole page or whatever to non-cached didn't help as well. I wonder if CoolUri might be part of the problem here in my installation. But if you look up the internal URL, there is just the id=... in the URL here. I wonder if the additional POST-data make any difference or not.
Workaround: Disable "pageNotFoundOnCacheHasherror" sigh
Updated by Christof Hagedorn over 9 years ago
same issue here.
i had to Disable "pageNotFoundOnCacheHasherror" .
How can we use fluid forms (which are generated with method="post") which act as a filter form
without disabling pageNotFoundOnCacheHasherror ?
f.e.:
form in searchAction makes a post to listAction
should listAction be listed in the list "non-cacheable actions" in ext_localconf.php ?
Could this be an issue?
Updated by Sven Burkert over 9 years ago
I have this issue with tt_news when using the search. Many others, too, I've found more than 600 results in google.
I do not understand the problem with cHash here:
I have a news search on a cached page, e.g.: news/search.html
Now, I execute the search, so this cached page is called again (the url stays exactly the same!), with POST vars.
The tt_news plugin is USER_INT, so it should display the search results. But after submitting the search form I get this "cHash comparison failed" error.