[SECURITY] Encode link text properly in typolink 14/40814/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:17:30 +0000 (16:17 +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: I9a1442932c47032e3135f05b0994efe16689cdea
Reviewed-on: http://review.typo3.org/40814
Reviewed-by: Helmut Hummel <helmut.hummel@typo3.org>
Tested-by: Helmut Hummel <helmut.hummel@typo3.org>
Reviewed-by: Benjamin Mack <benni@typo3.org>
Tested-by: Benjamin Mack <benni@typo3.org>
typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php

index 6460d05..d0fe745 100644 (file)
@@ -6181,7 +6181,7 @@ class ContentObjectRenderer {
                                                $target = $forceTarget;
                                        }
                                        if ($linktxt == '') {
-                                               $linktxt = $linkParameter;
+                                               $linktxt = $this->parseFunc($linkParameter, array('makelinks' => 0), '< lib.parseFunc');
                                        }
                                        // Parse URL:
                                        $urlParts = parse_url($linkParameter);
@@ -6213,7 +6213,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)));
@@ -6309,7 +6309,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));
        }