[SECURITY] Encode link text properly in typolink 07/40807/2
authorNicole Cordes <typo3@cordes.co>
Wed, 17 Jun 2015 14:53:48 +0000 (16:53 +0200)
committerBenjamin Mack <benni@typo3.org>
Wed, 1 Jul 2015 14:09:46 +0000 (16:09 +0200)
If the to be linked text is empty the ContentObjectRenderer chooses an
appropriate link text but doesn't encode it properly. As hsc() was
abandoned before this patch adds the parseFunc functionality to keep
common html tags which might be used by the editor but escapes unknown
characters and tags.

Resolves: #34107
Releases: master, 6.2
Security-Bulletin: TYPO3-CORE-SA-2015-004
Change-Id: I9730cb81c315a76a8fc0ef184362cabb9a59f2e5
Reviewed-on: http://review.typo3.org/40807
Reviewed-by: Benjamin Mack <benni@typo3.org>
Tested-by: Benjamin Mack <benni@typo3.org>
Reviewed-by: Helmut Hummel <helmut.hummel@typo3.org>
Tested-by: Helmut Hummel <helmut.hummel@typo3.org>
typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php

index 0df1e4b..7bdc029 100644 (file)
@@ -6178,7 +6178,7 @@ class ContentObjectRenderer {
                                                $target = $forceTarget;
                                        }
                                        if ($linktxt == '') {
-                                               $linktxt = $linkParameter;
+                                               $linktxt = $this->parseFunc($linkParameter, array('makelinks' => 0), '< lib.parseFunc');
                                        }
                                        // Parse URL:
                                        $urlParts = parse_url($linkParameter);
@@ -6210,7 +6210,7 @@ class ContentObjectRenderer {
                                        // check if the file exists or if a / is contained (same check as in detectLinkType)
                                        if (file_exists(rawurldecode($splitLinkParam[0])) || strpos($linkParameter, '/') !== FALSE) {
                                                if ($linktxt == '') {
-                                                       $linktxt = rawurldecode($linkParameter);
+                                                       $linktxt = $this->parseFunc(rawurldecode($linkParameter), array('makelinks' => 0), '< lib.parseFunc');
                                                }
                                                if ($GLOBALS['TSFE']->config['config']['jumpurl_enable'] || $conf['jumpurl']) {
                                                        $theFileEnc = str_replace('%2F', '/', rawurlencode(rawurldecode($linkParameter)));
@@ -6306,7 +6306,7 @@ class ContentObjectRenderer {
                                                }
                                                // Setting title if blank value to link:
                                                if ($linktxt == '') {
-                                                       $linktxt = $page['title'];
+                                                       $linktxt = $this->parseFunc($page['title'], array('makelinks' => 0), '< lib.parseFunc');
                                                }
                                                // Query Params:
                                                $addQueryParams = $conf['addQueryString'] ? $this->getQueryArguments($conf['addQueryString.']) : '';
index 2905b33..049a754 100644 (file)
@@ -3310,6 +3310,13 @@ class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                                ),
                                '<a href="http://typo3.org" title="Open new window" target="_blank" class="url-class">TYPO3</a>',
                        ),
+                       'Link to url with script tag' => array(
+                               '',
+                               array(
+                                       'parameter' => 'http://typo3.org<script>alert(123)</script>',
+                               ),
+                               '<a href="http://typo3.org&lt;script&gt;alert(123)&lt;/script&gt;">http://typo3.org&lt;script&gt;alert(123)&lt;/script&gt;</a>',
+                       ),
                        'Link to email address' => array(
                                'Email address',
                                array(
@@ -3351,6 +3358,20 @@ class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @dataProvider typolinkReturnsCorrectLinksForEmailsAndUrlsDataProvider
         */
        public function typolinkReturnsCorrectLinksForEmailsAndUrls($linkText, $configuration, $expectedResult) {
+               $templateServiceObjectMock = $this->getMock(\TYPO3\CMS\Core\TypoScript\TemplateService::class, array('dummy'));
+               $templateServiceObjectMock->setup = array(
+                       'lib.' => array(
+                               'parseFunc.' => $this->getLibParseFunc(),
+                       ),
+               );
+               $typoScriptFrontendControllerMockObject = $this->getMock(\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class, array(), array(), '', FALSE);
+               $typoScriptFrontendControllerMockObject->config = array(
+                       'config' => array(),
+                       'mainScript' => 'index.php',
+               );
+               $typoScriptFrontendControllerMockObject->tmpl = $templateServiceObjectMock;
+               $GLOBALS['TSFE'] = $typoScriptFrontendControllerMockObject;
+
                $this->assertEquals($expectedResult, $this->subject->typoLink($linkText, $configuration));
        }
 
@@ -3406,6 +3427,28 @@ class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                                ),
                                '<a href="index.php?id=42" title="Link to internal page" target="_self" class="page-class">My page</a>',
                        ),
+                       'Link to page with bold tag in title' => array(
+                               '',
+                               array(
+                                       'parameter' => 42,
+                               ),
+                               array(
+                                       'uid' => 42,
+                                       'title' => 'Page <b>title</b>',
+                               ),
+                               '<a href="index.php?id=42">Page <b>title</b></a>',
+                       ),
+                       'Link to page with script tag in title' => array(
+                               '',
+                               array(
+                                       'parameter' => 42,
+                               ),
+                               array(
+                                       'uid' => 42,
+                                       'title' => '<script>alert(123)</script>Page title',
+                               ),
+                               '<a href="index.php?id=42">&lt;script&gt;alert(123)&lt;/script&gt;Page title</a>',
+                       ),
                );
        }
 
@@ -3474,6 +3517,13 @@ class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                                ),
                                '<a href="fileadmin/foo.bar" title="Title of the file" target="_blank" class="file-class">My file</a>',
                        ),
+                       'Link to file with script tag in name' => array(
+                               '',
+                               array(
+                                       'parameter' => 'fileadmin/<script>alert(123)</script>',
+                               ),
+                               '<a href="fileadmin/&lt;script&gt;alert(123)&lt;/script&gt;">fileadmin/&lt;script&gt;alert(123)&lt;/script&gt;</a>',
+                       ),
                );
        }
 
@@ -3485,6 +3535,20 @@ class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @dataProvider typolinkReturnsCorrectLinksFilesDataProvider
         */
        public function typolinkReturnsCorrectLinksFiles($linkText, $configuration, $expectedResult) {
+               $templateServiceObjectMock = $this->getMock(\TYPO3\CMS\Core\TypoScript\TemplateService::class, array('dummy'));
+               $templateServiceObjectMock->setup = array(
+                       'lib.' => array(
+                               'parseFunc.' => $this->getLibParseFunc(),
+                       ),
+               );
+               $typoScriptFrontendControllerMockObject = $this->getMock(\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class, array(), array(), '', FALSE);
+               $typoScriptFrontendControllerMockObject->config = array(
+                       'config' => array(),
+                       'mainScript' => 'index.php',
+               );
+               $typoScriptFrontendControllerMockObject->tmpl = $templateServiceObjectMock;
+               $GLOBALS['TSFE'] = $typoScriptFrontendControllerMockObject;
+
                $this->assertEquals($expectedResult, $this->subject->typoLink($linkText, $configuration));
        }