Breaking: #96221 - Deny inline JavaScript in FormEngine's requireJsModules¶
See forge#96221
Description¶
Custom FormEngine
components allowed to load RequireJS modules
with arbitrary inline JavaScript to initialize those modules. In favor
of introducing content security policy headers, the amount of inline
JavaScript shall be reduced and replaced by corresponding declarations.
Using callback functions as inline JavaScript is not possible anymore,
initializations have to be declared using an instance of
TYPO3\CMS\Core\Page\JavaScriptModuleInstruction
.
Impact¶
Using inline JavaScript to initialize RequireJS modules in FormEngine
,
like shown in the the example below, will throw a corresponding
\LogicException
.
$resultArray['requireJsModules'][] = ['TYPO3/CMS/Backend/FormEngine/Element/InputDateTimeElement' => '
// inline JavaScript code to initialize `InputDateTimeElement`
function(InputDateTimeElement) {
new InputDateTimeElement(' . GeneralUtility::quoteJSvalue($fieldId) . ');
}'
];
Affected Installations¶
All instances that are using RequireJS modules with custom initializations
as inline JavaScript in FormEngine
.
Migration¶
Previous deprecation ChangeLog documentation provided migration details already.
The following snippet shows the migrated source code of shown above - using
TYPO3\CMS\Core\Page\JavaScriptModuleInstruction
instead of inline JavaScript.
// use use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
$resultArray['requireJsModules'][] = JavaScriptModuleInstruction::forRequireJS(
'TYPO3/CMS/Backend/FormEngine/Element/InputDateTimeElement'
)->instance($fieldId);
JavaScriptModuleInstruction
forwards arguments as JSON
data - and thus
handles proper context-aware encoding implicitly (GeneralUtility::quoteJSvalue
and similar custom encoding can be omitted in this case).