Skip to content

Commit a0c4348

Browse files
waldhacker1ohader
authored andcommitted
[SECURITY] Use a fluid template for the ConfirmationFinisher message
The ConfirmationFinisher message is now rendered within a fluid template to allow styling of the message. Furthermore, the FormRuntime (and thus all form element values) and the finisherVariableProvider are available in the template. Custom variables can be added globally within the form setup or at form level in the form definition. By using a fluid template and the associated html escaping, the display of the ConfirmationFinisher message is protected against XSS / html injection attacks. Resolves: #84902 Releases: master, 9.5, 8.7 Security-Commit: e73ae7cae8ccc3450d850f554ab50bc09b57e716 Security-Bulletin: TYPO3-CORE-SA-2019-007 Change-Id: Id8aa02d92f6b89a3008e8c91cf8ab318a05e7489 Reviewed-on: https://review.typo3.org/59532 Reviewed-by: Oliver Hader <oliver.hader@typo3.org> Tested-by: Oliver Hader <oliver.hader@typo3.org>
1 parent d578fd3 commit a0c4348

File tree

6 files changed

+264
-5
lines changed

6 files changed

+264
-5
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
.. include:: ../../Includes.txt
2+
3+
===================================================
4+
Feature: #83405 - add ConfirmationFinisher template
5+
===================================================
6+
7+
See :issue:`83405`
8+
9+
Description
10+
===========
11+
12+
The ConfirmationFinisher message is now rendered within a fluid template to allow styling of the message.
13+
Furthermore, the FormRuntime (and thus all form element values) and the finisherVariableProvider are available in the template [1].
14+
Custom variables can be added globally within the form setup or at form level in the form definition [2].
15+
By using a fluid template and the associated html escaping, the display of the ConfirmationFinisher message is protected against XSS / html injection attacks.
16+
The ext: form supplied fluid template does not include any HTML wrapping to remain compatible with existing installations, but it is possible to implement your own template [3].
17+
18+
[1] Template variables
19+
----------------------
20+
21+
* :html:`{form}` - Object for access to submitted form element values (https://docs.typo3.org/typo3cms/extensions/form/Concepts/FrontendRendering/Index.html#accessing-form-values)
22+
* :html:`{finisherVariableProvider}` - Object with data from previous finishers (https://docs.typo3.org/typo3cms/extensions/form/Concepts/FrontendRendering/Index.html#share-data-between-finishers)
23+
* :html:`{message}` - The confirmation message
24+
25+
[2] custom template variables
26+
-----------------------------
27+
28+
global within the form setup:
29+
30+
.. code-block:: yaml
31+
32+
TYPO3:
33+
CMS:
34+
Form:
35+
prototypes:
36+
standard:
37+
finishersDefinition:
38+
Confirmation:
39+
options:
40+
variables:
41+
foo: bar
42+
43+
per form within the form definition:
44+
45+
.. code-block:: yaml
46+
47+
finishers:
48+
-
49+
identifier: Confirmation
50+
options:
51+
message: 'Thx'
52+
variables:
53+
foo: bar
54+
55+
[3] custom Template
56+
-------------------
57+
58+
form setup:
59+
60+
.. code-block:: yaml
61+
62+
TYPO3:
63+
CMS:
64+
Form:
65+
prototypes:
66+
standard:
67+
finishersDefinition:
68+
Confirmation:
69+
options:
70+
templateRootPaths:
71+
20: 'EXT:my_site_package/Resources/Private/Templates/Form/Finishers/Confirmation/'
72+
73+
Impact
74+
======
75+
76+
Integrators can use a ConfirmationFinisher message within a fluid template.
77+
Integrators can use additional information such as form element values within the template.
78+
The ConfirmationFinisher message is protected against XSS / html injection attacks.
79+
80+
.. index:: Frontend, ext:form, NotScanned

typo3/sysext/form/Classes/Domain/Finishers/ConfirmationFinisher.php

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
/*
66
* This file is part of the TYPO3 CMS project.
77
*
8-
* It originated from the Neos.Form package (www.neos.io)
9-
*
108
* It is free software; you can redistribute it and/or modify it under
119
* the terms of the GNU General Public License, either version 2
1210
* of the License, or any later version.
@@ -19,15 +17,19 @@
1917

2018
use TYPO3\CMS\Core\Utility\GeneralUtility;
2119
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
20+
use TYPO3\CMS\Fluid\View\StandaloneView;
2221
use TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException;
22+
use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
23+
use TYPO3\CMS\Form\ViewHelpers\RenderRenderableViewHelper;
2324
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
2425

2526
/**
26-
* A simple finisher that outputs a given text
27+
* A finisher that outputs a given text
2728
*
2829
* Options:
2930
*
3031
* - message: A hard-coded message to be rendered
32+
* - contentElementUid: A content element uid to be rendered
3133
*
3234
* Usage:
3335
* //...
@@ -113,6 +115,45 @@ protected function executeInternal()
113115
$message = $this->parseOption('message');
114116
}
115117

116-
return $message;
118+
$standaloneView = $this->initializeStandaloneView(
119+
$this->finisherContext->getFormRuntime()
120+
);
121+
122+
$standaloneView->assign('message', $message);
123+
124+
return $standaloneView->render();
125+
}
126+
127+
/**
128+
* @param FormRuntime $formRuntime
129+
* @return StandaloneView
130+
* @throws FinisherException
131+
*/
132+
protected function initializeStandaloneView(FormRuntime $formRuntime): StandaloneView
133+
{
134+
$standaloneView = $this->objectManager->get(StandaloneView::class);
135+
136+
if (!isset($this->options['templateName'])) {
137+
throw new FinisherException(
138+
'The option "templateName" must be set for the ConfirmationFinisher.',
139+
1521573955
140+
);
141+
}
142+
143+
$standaloneView->setTemplate($this->options['templateName']);
144+
$standaloneView->getTemplatePaths()->fillFromConfigurationArray($this->options);
145+
146+
if (isset($this->options['variables']) && is_array($this->options['variables'])) {
147+
$standaloneView->assignMultiple($this->options['variables']);
148+
}
149+
150+
$standaloneView->assign('form', $formRuntime);
151+
$standaloneView->assign('finisherVariableProvider', $this->finisherContext->getFinisherVariableProvider());
152+
153+
$standaloneView->getRenderingContext()
154+
->getViewHelperVariableContainer()
155+
->addOrUpdate(RenderRenderableViewHelper::class, 'formRuntime', $formRuntime);
156+
157+
return $standaloneView;
117158
}
118159
}

typo3/sysext/form/Configuration/Yaml/BaseSetup.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,14 @@ TYPO3:
296296

297297
Confirmation:
298298
implementationClassName: 'TYPO3\CMS\Form\Domain\Finishers\ConfirmationFinisher'
299-
#options:
299+
options:
300300
#message: ''
301301
#contentElementUid: 0
302302
#typoscriptObjectPath: 'lib.tx_form.contentElementRendering'
303+
#variables:
304+
templateName: 'Confirmation'
305+
templateRootPaths:
306+
10: 'EXT:form/Resources/Private/Frontend/Templates/Finishers/Confirmation/'
303307

304308
EmailToSender:
305309
__inheritances:

typo3/sysext/form/Documentation/Config/configuration/Index.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3529,6 +3529,10 @@ Full default configuration
35293529
closure: ''
35303530
Confirmation:
35313531
implementationClassName: TYPO3\CMS\Form\Domain\Finishers\ConfirmationFinisher
3532+
options:
3533+
templateName: 'Confirmation'
3534+
templateRootPaths:
3535+
10: 'EXT:form/Resources/Private/Frontend/Templates/Finishers/Confirmation/'
35323536
formEditor:
35333537
iconIdentifier: t3-form-icon-finisher
35343538
label: formEditor.elements.Form.finisher.Confirmation.editor.header.label

typo3/sysext/form/Documentation/Config/proto/finishersDefinition/finishers/Confirmation.rst

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,133 @@ options.message
7474
The text which is shown if the finisher is invoked.
7575

7676

77+
.. _typo3.cms.form.prototypes.<prototypeIdentifier>.finishersdefinition.confirmation.options.contentelementuid:
78+
79+
options.contentElementUid
80+
-------------------------
81+
82+
:aspect:`Option path`
83+
TYPO3.CMS.Form.prototypes.<prototypeIdentifier>.finishersDefinition.Confirmation.options.contentElementUid
84+
85+
:aspect:`Data type`
86+
integer
87+
88+
:aspect:`Needed by`
89+
Frontend
90+
91+
:aspect:`Mandatory`
92+
No
93+
94+
:aspect:`Default value`
95+
undefined
96+
97+
:aspect:`Description`
98+
The option "contentElementUid" can be used to render a content element.
99+
If contentElementUid is set, the option "message" will be ignored.
100+
101+
102+
.. _typo3.cms.form.prototypes.<prototypeIdentifier>.finishersdefinition.confirmation.options.typoscriptobjectpath:
103+
104+
options.typoscriptObjectPath
105+
----------------------------
106+
107+
:aspect:`Option path`
108+
TYPO3.CMS.Form.prototypes.<prototypeIdentifier>.finishersDefinition.Confirmation.options.typoscriptObjectPath
109+
110+
:aspect:`Data type`
111+
string
112+
113+
:aspect:`Needed by`
114+
Frontend
115+
116+
:aspect:`Mandatory`
117+
No
118+
119+
:aspect:`Default value`
120+
'lib.tx_form.contentElementRendering'
121+
122+
:aspect:`Description`
123+
The option "typoscriptObjectPath" can be used to render the content element (options.contentElementUid) through a typoscript lib.
124+
125+
126+
.. _typo3.cms.form.prototypes.<prototypeIdentifier>.finishersdefinition.confirmation.options.variables:
127+
128+
options.variables
129+
-----------------
130+
131+
:aspect:`Option path`
132+
TYPO3.CMS.Form.prototypes.<prototypeIdentifier>.finishersDefinition.Confirmation.options.variables
133+
134+
:aspect:`Data type`
135+
array
136+
137+
:aspect:`Needed by`
138+
Frontend
139+
140+
:aspect:`Mandatory`
141+
No
142+
143+
:aspect:`Default value`
144+
undefined
145+
146+
:aspect:`Description`
147+
Variables which should be available within the template.
148+
149+
150+
.. _typo3.cms.form.prototypes.<prototypeIdentifier>.finishersdefinition.confirmation.options.templatename:
151+
152+
options.templateName
153+
--------------------
154+
155+
:aspect:`Option path`
156+
TYPO3.CMS.Form.prototypes.<prototypeIdentifier>.finishersDefinition.Confirmation.options.templateName
157+
158+
:aspect:`Data type`
159+
string
160+
161+
:aspect:`Needed by`
162+
Frontend
163+
164+
:aspect:`Mandatory`
165+
Yes
166+
167+
:aspect:`Default value`
168+
'Confirmation'
169+
170+
:aspect:`Description`
171+
Define a custom template name which should be used.
172+
173+
174+
.. _typo3.cms.form.prototypes.<prototypeIdentifier>.finishersdefinition.confirmation.options.templaterootpaths:
175+
176+
options.templateRootPaths
177+
-------------------------
178+
179+
:aspect:`Option path`
180+
TYPO3.CMS.Form.prototypes.<prototypeIdentifier>.finishersDefinition.Confirmation.options.templateRootPaths
181+
182+
:aspect:`Data type`
183+
array
184+
185+
:aspect:`Needed by`
186+
Frontend
187+
188+
:aspect:`Mandatory`
189+
Yes
190+
191+
:aspect:`Default value`
192+
.. code-block:: yaml
193+
:linenos:
194+
195+
Confirmation:
196+
options:
197+
templateRootPaths:
198+
10: 'EXT:form/Resources/Private/Frontend/Templates/Finishers/Confirmation/'
199+
200+
:aspect:`Description`
201+
Used to define several paths for templates, which will be tried in reversed order (the paths are searched from bottom to top).
202+
203+
77204
.. _typo3.cms.form.prototypes.<prototypeIdentifier>.finishersdefinition.confirmation.options.translation.translationfile:
78205

79206
options.translation.translationFile
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
2+
{message}
3+
</html>

0 commit comments

Comments
 (0)