Vulnerability: Cross-Site Scripting in TYPO3's Form Framework > ### Meta
> * CVSS: `CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N/E:F/RL:O/RC:C` (4.9)

### Problem
It has been discovered that the Form Designer backend module of the Form Framework is vulnerable to cross-site scripting. A valid backend user account with access to the form module is needed to exploit this vulnerability.

### Solution
Update to TYPO3 versions 8.7.47 ELTS, 9.5.35 ELTS, 10.4.29, 11.5.11 that fix the problem described above.

### Credits
Thanks to Gabe Troyan who reported and fixed the issue.

### References
* [TYPO3-CORE-SA-2022-003](https://typo3.org/security/advisory/typo3-core-sa-2022-003)
Vulnerability ID: GHSA-3r95-23jp-mhvg
CWE: CWE-79
Severity score: 5.4
Project: https://github.com/TYPO3/typo3
Published: 2022-06-17
File: typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/stage-component.js
Commit message: [SECURITY] Ensure text preview of multivalue items in form editor

Multivalue items in the form editor user interface were previewed
as HTML, but should be treated as scalar text only.

Resolves: #96743
Releases: main, 11.5, 10.4
Change-Id: I5e8dab26119490ecf19ac5d48c2bc7a5a00daaad
Security-Bulletin: TYPO3-CORE-SA-2022-003
Security-References: CVE-2022-31048
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/73297
Tested-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
Commit author: Gabe Troyan

Vulnerable version (before fix):
 function factory($, Helper, Icons) {      */     function setStageHeadline(title) {       if (getUtility().isUndefinedOrNull(title)) {         title = buildTitleByFormElement();       }        $(getHelper().getDomElementDataIdentifierSelector('stageHeadline')).html(title);     };      /** function factory($, Helper, Icons) {        getHelper()         .getTemplatePropertyDomElement('_type', template)         .append(getFormElementDefinition(formElement, 'label'));       getHelper()         .getTemplatePropertyDomElement('_identifier', template)         .append(formElement.get('identifier'));     };      /** function factory($, Helper, Icons) {              getHelper()               .getTemplatePropertyDomElement('_label', rowTemplate)               .append(collectionElementConfiguration['label']);             $(getHelper().getDomElementDataIdentifierSelector('validatorsContainer'), $(template))               .append(rowTemplate.html());           } function factory($, Helper, Icons) {           }         }          getHelper().getTemplatePropertyDomElement('_label', rowTemplate).append(label);          if (isPreselected) {           getHelper().getTemplatePropertyDomElement('_label', rowTemplate).addClass(

Fixed version (after fix):
 function factory($, Helper, Icons) {      */     function setStageHeadline(title) {       if (getUtility().isUndefinedOrNull(title)) {         title = buildTitleByFormElement().text();       }        $(getHelper().getDomElementDataIdentifierSelector('stageHeadline')).text(title);     };      /** function factory($, Helper, Icons) {        getHelper()         .getTemplatePropertyDomElement('_type', template)         .append(document.createTextNode(getFormElementDefinition(formElement, 'label')));       getHelper()         .getTemplatePropertyDomElement('_identifier', template)         .append(document.createTextNode(formElement.get('identifier')));     };      /** function factory($, Helper, Icons) {              getHelper()               .getTemplatePropertyDomElement('_label', rowTemplate)               .append(document.createTextNode(collectionElementConfiguration['label']));             $(getHelper().getDomElementDataIdentifierSelector('validatorsContainer'), $(template))               .append(rowTemplate.html());           } function factory($, Helper, Icons) {           }         }          getHelper().getTemplatePropertyDomElement('_label', rowTemplate).append(document.createTextNode(label));          if (isPreselected) {           getHelper().getTemplatePropertyDomElement('_label', rowTemplate).addClass(

Patch:
patch: @@ -513,10 +513,10 @@ function factory($, Helper, Icons) {
      */
     function setStageHeadline(title) {
       if (getUtility().isUndefinedOrNull(title)) {
-        title = buildTitleByFormElement();
+        title = buildTitleByFormElement().text();
       }
 
-      $(getHelper().getDomElementDataIdentifierSelector('stageHeadline')).html(title);
+      $(getHelper().getDomElementDataIdentifierSelector('stageHeadline')).text(title);
     };
 
     /**
@@ -981,10 +981,10 @@ function factory($, Helper, Icons) {
 
       getHelper()
         .getTemplatePropertyDomElement('_type', template)
-        .append(getFormElementDefinition(formElement, 'label'));
+        .append(document.createTextNode(getFormElementDefinition(formElement, 'label')));
       getHelper()
         .getTemplatePropertyDomElement('_identifier', template)
-        .append(formElement.get('identifier'));
+        .append(document.createTextNode(formElement.get('identifier')));
     };
 
     /**
@@ -1029,7 +1029,7 @@ function factory($, Helper, Icons) {
 
             getHelper()
               .getTemplatePropertyDomElement('_label', rowTemplate)
-              .append(collectionElementConfiguration['label']);
+              .append(document.createTextNode(collectionElementConfiguration['label']));
             $(getHelper().getDomElementDataIdentifierSelector('validatorsContainer'), $(template))
               .append(rowTemplate.html());
           }
@@ -1089,7 +1089,7 @@ function factory($, Helper, Icons) {
           }
         }
 
-        getHelper().getTemplatePropertyDomElement('_label', rowTemplate).append(label);
+        getHelper().getTemplatePropertyDomElement('_label', rowTemplate).append(document.createTextNode(label));
 
         if (isPreselected) {
           getHelper().getTemplatePropertyDomElement('_label', rowTemplate).addClass(
path: typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/stage-component.js