CVE-2020-15098: Use of a Broken or Risky Cryptographic Algorithm (CWE-327)
value: In TYPO3 CMS greater than or equal to 9.0.0 and less than 9.5.20, and greater than or equal to 10.0.0 and less than 10.4.6, it has been discovered that an internal verification mechanism can be used to generate arbitrary checksums. This allows to inject arbitrary data having a valid cryptographic message authentication code (HMAC-SHA1) and can lead to various attack chains including potential privilege escalation, insecure deserialization & remote code execution. The overall severity of this vulnerability is high based on mentioned attack chains and the requirement of having a valid backend user session (authenticated). This has been patched in versions 9.5.20 and 10.4.6.
CWE description: The product uses a broken or risky cryptographic algorithm or protocol.
CVSS v3 base score: 8.8
Published: 2020-07-29T17:15Z
Repository: https://github.com/TYPO3/TYPO3.CMS
Language: PHP
Files changed: typo3/sysext/backend/Classes/Controller/LinkBrowserController.php, typo3/sysext/backend/Classes/Form/FieldControl/EditPopup.php, typo3/sysext/backend/Classes/Form/FieldControl/LinkPopup.php
Commit date: 2020-07-28 10:19:06 +0200
Commit message: [SECURITY] Avoid ambiguous HMAC results

Cryptographic hashes being calculated from and for query
parameters must only be used for a specific use-case or
scope in order to avoid resulting hashes being ambiguous.

Resolves: #91689
Releases: master, 10.4, 9.5
Change-Id: I59ca16fe71e27195b98a822607aab564425d248d
Security-Bulletin: TYPO3-CORE-SA-2020-008
Security-References: CVE-2020-15098
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/65125
Tested-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>

Diff: diff --git a/typo3/sysext/backend/Classes/Controller/LinkBrowserController.php b/typo3/sysext/backend/Classes/Controller/LinkBrowserController.php
index 619bfcbab5..94fc5417b0 100644
--- a/typo3/sysext/backend/Classes/Controller/LinkBrowserController.php
+++ b/typo3/sysext/backend/Classes/Controller/LinkBrowserController.php
@@ -117,11 +117,11 @@ class LinkBrowserController extends AbstractLinkBrowserController
                 foreach ($fieldChangeFunctions as &$value) {
                     $value = str_replace($originalName, $cleanedName, $value);
                 }
                 unset($value);
             }
-            $result = hash_equals(GeneralUtility::hmac(serialize($fieldChangeFunctions)), $this->parameters['fieldChangeFuncHash']);
+            $result = hash_equals(GeneralUtility::hmac(serialize($fieldChangeFunctions), 'backend-link-browser'), $this->parameters['fieldChangeFuncHash']);
         }
         return $result;
     }
 
     /**
@@ -133,11 +133,11 @@ class LinkBrowserController extends AbstractLinkBrowserController
     {
         $formEngineParameters = [];
         $parameters = parent::getBodyTagAttributes();
 
         $formEngineParameters['fieldChangeFunc'] = $this->parameters['fieldChangeFunc'];
-        $formEngineParameters['fieldChangeFuncHash'] = GeneralUtility::hmac(serialize($this->parameters['fieldChangeFunc']));
+        $formEngineParameters['fieldChangeFuncHash'] = GeneralUtility::hmac(serialize($this->parameters['fieldChangeFunc']), 'backend-link-browser');
 
         $parameters['data-add-on-params'] .= HttpUtility::buildQueryString(['P' => $formEngineParameters], '&');
 
         return $parameters;
     }
diff --git a/typo3/sysext/backend/Classes/Form/FieldControl/EditPopup.php b/typo3/sysext/backend/Classes/Form/FieldControl/EditPopup.php
index 31e2a13393..849b47b4d3 100644
--- a/typo3/sysext/backend/Classes/Form/FieldControl/EditPopup.php
+++ b/typo3/sysext/backend/Classes/Form/FieldControl/EditPopup.php
@@ -76,11 +76,11 @@ class EditPopup extends AbstractNode
                 'formName' => 'editform',
                 'flexFormDataStructureIdentifier' => $flexFormDataStructureIdentifier,
                 'flexFormDataStructurePath' => $flexFormDataStructurePath,
                 'hmac' => GeneralUtility::hmac('editform' . $itemName, 'wizard_js'),
                 'fieldChangeFunc' => $parameterArray['fieldChangeFunc'],
-                'fieldChangeFuncHash' => GeneralUtility::hmac(serialize($parameterArray['fieldChangeFunc'])),
+                'fieldChangeFuncHash' => GeneralUtility::hmac(serialize($parameterArray['fieldChangeFunc']), 'backend-link-browser'),
             ],
         ];
         $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
         $url = (string)$uriBuilder->buildUriFromRoute('wizard_edit', $urlParameters);
 
diff --git a/typo3/sysext/backend/Classes/Form/FieldControl/LinkPopup.php b/typo3/sysext/backend/Classes/Form/FieldControl/LinkPopup.php
index 932185bf2f..c04ba0aa73 100644
--- a/typo3/sysext/backend/Classes/Form/FieldControl/LinkPopup.php
+++ b/typo3/sysext/backend/Classes/Form/FieldControl/LinkPopup.php
@@ -61,11 +61,11 @@ class LinkPopup extends AbstractNode
                 'field' => $this->data['fieldName'],
                 'formName' => 'editform',
                 'itemName' => $itemName,
                 'hmac' => GeneralUtility::hmac('editform' . $itemName, 'wizard_js'),
                 'fieldChangeFunc' => $parameterArray['fieldChangeFunc'],
-                'fieldChangeFuncHash' => GeneralUtility::hmac(serialize($parameterArray['fieldChangeFunc'])),
+                'fieldChangeFuncHash' => GeneralUtility::hmac(serialize($parameterArray['fieldChangeFunc']), 'backend-link-browser'),
             ],
         ];
         /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
         $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
         $url = (string)$uriBuilder->buildUriFromRoute('wizard_link', $urlParameters);

Vulnerable code:             $result = hash_equals(GeneralUtility::hmac(serialize($fieldChangeFunctions)), $this->parameters['fieldChangeFuncHash']);
        $formEngineParameters['fieldChangeFuncHash'] = GeneralUtility::hmac(serialize($this->parameters['fieldChangeFunc']));
                'fieldChangeFuncHash' => GeneralUtility::hmac(serialize($parameterArray['fieldChangeFunc'])),
                'fieldChangeFuncHash' => GeneralUtility::hmac(serialize($parameterArray['fieldChangeFunc'])),
Fixed code:             $result = hash_equals(GeneralUtility::hmac(serialize($fieldChangeFunctions), 'backend-link-browser'), $this->parameters['fieldChangeFuncHash']);
        $formEngineParameters['fieldChangeFuncHash'] = GeneralUtility::hmac(serialize($this->parameters['fieldChangeFunc']), 'backend-link-browser');
                'fieldChangeFuncHash' => GeneralUtility::hmac(serialize($parameterArray['fieldChangeFunc']), 'backend-link-browser'),
                'fieldChangeFuncHash' => GeneralUtility::hmac(serialize($parameterArray['fieldChangeFunc']), 'backend-link-browser'),