Blueprint: Getting rid of cHash
|Proposal||Create a more effective mechanism to mark which parts of a request are actually relevant, and improve caching by that|
|Status||Draft, Discussion, Voting Phase, Accepted, Declined, Withdrawn|
|Current Progress||Unknown, Started, Good Progress, Bad Progress, Stalled, Review Needed|
|Topic for Gerrit||chash|
- Started during TYPO3 CMS 9.0 development
Goals / Motivation
Currently, the core does not know which request parametes are actually relevant and which are not. To prevent issues, the core hashes request parameters with a secret and appends that hash as the so called “cHash” (cache hash). This is a must to prevent issues like cache flooding: there, attackers would e.g. add parameters which would result in new cache entries being generated, without any value being added to the cache (because these new cache entries are artificial).
Additionally, the limited knowledge about requests keeps us from improving other parts of the core, e.g. with a proper URL handling solution.
Plugins and the core must be able to mark parameters as “used”. Additionally, it should be possible to report a value as valid/invalid.
The core can then derive the caching parameters from this information. For future requests, the incoming parameters can be matched against this. Parameters irrelevant for caching should automatically be removed for a cache lookup; as
The core should be able to decide if a plugin must be called or not; this should not be up to each single plugin (to reduce implementation effort and ensure a consistent API). For that, a plugin must be able to tell which parameters it expects and which values these can have. This could also be automatically derived e.g. from PHPdoc.
A plugin should also be able to return the caching parameters for a given request to the core, w/o executing the actual plugin action.
This also opens the door for further improvements like CE-level caching, where the page as a whole can be cached once, but single plugins are cached individually (which would require a custom caching solution w/ a USER_INT today)
In the most simple version, GeneralUtility::_GP() would take on the role of the "parameter custodian" that keeps track of all used parameters; this, however, is pretty error-prone.
A better solution would be to pass in request and response objects to the plugin, which they can use for getting parameter values. The request can then also keep track of which parameters were requested (with a possibility to explicitly mark them as unused again if the plugin has to; e.g. because it turned out that in the specific combination, this parameter is useless).
Request dispatching to a plugin should be moved out of the USER content object, to a dedicated plugin rendering service.
Specifying allowed values for a parameter should follow some standardized syntax; more research is required in that area. For Extbase parameters, an automated derivation will be pretty easy.
Mainly backwards compatibility; this will require all plugins to be adapted. For Extbase, it might be possible to do most of the work automatically, in the framework. For AbstractPlugin-based extensions and fully custom solutions, more work will be necessary (or a default of "every parameter is relevant with every value", but that would open cache flooding possibilities again).
It should be relatively straightforward to detect if all plugins are compatible; if not all are, cHash could stay enabled for the time being. This could be done with something like a "tainted" rendering mode, which is enabled as soon as a legacy plugin is encountered.