From 2d40f74822a947c814155a71d1abe9daa8cee816 Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Tue, 24 Aug 2021 16:04:45 +0200 Subject: [PATCH] [BUGFIX] Allow links in sys_news Rendering links set for sys_news (shown at backend login) records via RTE does not work. Reason is a nasty dependency to TypoScript lib.parsefunc, which isn't easy to retrieve in BE scope. With recent RTE html parser related changes, it's now relatively easy to submit a fallback layer in case for instance f:html view helper isn't used within FE context. Resolves: #67556 Releases: master Change-Id: I7d6226bd998396a1d3859cbf956f9d5d61bed7d4 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/70740 Tested-by: core-ci <typo3@b13.com> Tested-by: Benni Mack <benni@typo3.org> Tested-by: Oliver Bartsch <bo@cedev.de> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> Reviewed-by: Benni Mack <benni@typo3.org> Reviewed-by: Oliver Bartsch <bo@cedev.de> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> --- .../Rendering/SecureHtmlRenderingTest.php | 16 ++++--- .../ContentObject/ContentObjectRenderer.php | 43 ++++++++++++++++++- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/typo3/sysext/fluid_styled_content/Tests/Functional/Rendering/SecureHtmlRenderingTest.php b/typo3/sysext/fluid_styled_content/Tests/Functional/Rendering/SecureHtmlRenderingTest.php index 862739624713..db8b0f4f61e2 100644 --- a/typo3/sysext/fluid_styled_content/Tests/Functional/Rendering/SecureHtmlRenderingTest.php +++ b/typo3/sysext/fluid_styled_content/Tests/Functional/Rendering/SecureHtmlRenderingTest.php @@ -234,7 +234,8 @@ class SecureHtmlRenderingTest extends FunctionalTestCase '#01 ' . self::TYPE_EMPTY_PARSEFUNCTSPATH => [ self::TYPE_EMPTY_PARSEFUNCTSPATH, '01: <script>alert(1)</script>', - '01: <script>alert(1)</script>', + // triggers fallback to default parsefunc config, which enables htmlSanitize + '01: <script>alert(1)</script>', ], '#01 ' . self::TYPE_DISABLE_HTML_SANITIZE => [ self::TYPE_DISABLE_HTML_SANITIZE, @@ -249,7 +250,8 @@ class SecureHtmlRenderingTest extends FunctionalTestCase '#03 ' . self::TYPE_EMPTY_PARSEFUNCTSPATH => [ self::TYPE_EMPTY_PARSEFUNCTSPATH, '03: <img img="img" alt="alt" onerror="alert(1)">', - '03: <img img="img" alt="alt" onerror="alert(1)">', + // triggers fallback to default parsefunc config, which enables htmlSanitize + '03: <img alt="alt">', ], '#03 ' . self::TYPE_DISABLE_HTML_SANITIZE => [ self::TYPE_DISABLE_HTML_SANITIZE, @@ -264,8 +266,8 @@ class SecureHtmlRenderingTest extends FunctionalTestCase '#07 ' . self::TYPE_EMPTY_PARSEFUNCTSPATH => [ self::TYPE_EMPTY_PARSEFUNCTSPATH, '07: <a href="t3://page?uid=1000" target="_blank" rel="noreferrer" class="button" role="button" onmouseover="alert(1)">TYPO3</a>', - // expected, with empty parseFunc configuration internal link URN is not resolved - '07: <a href="t3://page?uid=1000" target="_blank" rel="noreferrer" class="button" role="button" onmouseover="alert(1)">TYPO3</a>', + // triggers fallback to default parsefunc config, which enables htmlSanitize and resolves URNs + '07: <a href="/" target="_blank" rel="noreferrer" class="button" role="button">TYPO3</a>', ], '#07 ' . self::TYPE_DISABLE_HTML_SANITIZE => [ self::TYPE_DISABLE_HTML_SANITIZE, @@ -280,7 +282,8 @@ class SecureHtmlRenderingTest extends FunctionalTestCase '#08 ' . self::TYPE_EMPTY_PARSEFUNCTSPATH => [ self::TYPE_EMPTY_PARSEFUNCTSPATH, '08: <meta whatever="whatever">', - '08: <meta whatever="whatever">', + // triggers fallback to default parsefunc config, which enables htmlSanitize + '08:', ], '#08 ' . self::TYPE_DISABLE_HTML_SANITIZE => [ self::TYPE_DISABLE_HTML_SANITIZE, @@ -296,7 +299,8 @@ class SecureHtmlRenderingTest extends FunctionalTestCase '#09 ' . self::TYPE_EMPTY_PARSEFUNCTSPATH => [ self::TYPE_EMPTY_PARSEFUNCTSPATH, '09: <sdfield onmouseover="alert(1)">', - '09: <sdfield onmouseover="alert(1)">', + // triggers fallback to default parsefunc config, which enables htmlSanitize + '09: <sdfield onmouseover="alert(1)"></sdfield>', ], '#09 ' . self::TYPE_DISABLE_HTML_SANITIZE => [ self::TYPE_DISABLE_HTML_SANITIZE, diff --git a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php index 3f64ff5415fc..198d199e1528 100644 --- a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php +++ b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php @@ -3349,6 +3349,37 @@ class ContentObjectRenderer implements LoggerAwareInterface ]; $temp_conf = $this->mergeTSRef($temp_conf, 'parseFunc'); $conf = $temp_conf['parseFunc.']; + // Fallback configuration to always replace links. This kicks in if there is no + // default "lib.parsefunc" setup in given context, for instance if the RTE html + // parser is used in backend context and no extension adds default TypoScript. + // This fallback setup is kept in place here for now, but may be later refactored + // to be used elsewhere if needed. + if (empty($conf)) { + $conf = [ + 'tags.' => [ + 'a' => 'TEXT', + 'a.' => [ + 'current' => 1, + 'typolink.' => [ + 'parameter.' => [ + 'data' => 'parameters:href' + ], + 'title.' => [ + 'data' => 'parameters:title' + ], + 'ATagParams.' => [ + 'data' => 'parameters:allParams' + ], + 'target.' => [ + 'ifEmpty.' => [ + 'data' => ['parameters:target'] + ] + ], + ] + ] + ] + ]; + } } // early return, no processing in case no configuration is given if (empty($conf)) { @@ -4228,7 +4259,9 @@ class ContentObjectRenderer implements LoggerAwareInterface $fieldArray = $tsfe->page; } $retVal = ''; - $sections = explode('//', $string); + // @todo: getData should not be called with non-string as $string. example trigger: + // SecureHtmlRenderingTest htmlViewHelperAvoidsCrossSiteScripting set #07 PHP 8 + $sections = is_string($string) ? explode('//', $string) : []; foreach ($sections as $secKey => $secVal) { if ($retVal) { break; @@ -4696,7 +4729,13 @@ class ContentObjectRenderer implements LoggerAwareInterface $linkBuilder = GeneralUtility::makeInstance( $GLOBALS['TYPO3_CONF_VARS']['FE']['typolinkBuilder'][$linkDetails['type']], $this, - $tsfe + // AbstractTypolinkBuilder type hints an optional dependency to TypoScriptFrontendController. + // Some core parts however "fake" $GLOBALS['TSFE'] to stdCLass() due to its long list of + // dependencies. f:html view helper is such a scenario. This of course crashes if given to typolink builder + // classes. For now, we check the instance and hand over 'null', giving the link builders the option + // to take care of tsfe themselfs. This scenario is for instance triggered when in BE login when sys_news + // records set links. + $tsfe instanceof TypoScriptFrontendController ? $tsfe : null ); try { [$this->lastTypoLinkUrl, $linkText, $target] = $linkBuilder->build($linkDetails, $linkText, $target, $conf); -- GitLab