‪TYPO3CMS  11.5
SecurityTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
26 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\ActionService;
27 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
28 
32 class ‪SecurityTest extends FunctionalTestCase
33 {
37  private ‪$backendUser;
38 
43 
44  protected ‪$coreExtensionsToLoad = ['rte_ckeditor'];
45 
46  protected function ‪setUp(): void
47  {
48  parent::setUp();
49  $this->importDataSet('PACKAGE:typo3/testing-framework/Resources/Core/Functional/Fixtures/pages.xml');
50  $this->backendUser = $this->setUpBackendUserFromFixture(1);
51  $this->backendUser->workspace = 0;
52  GeneralUtility::makeInstance(Context::class)
53  ->setAspect('workspace', new ‪WorkspaceAspect(0));
55 
56  $this->actionService = GeneralUtility::makeInstance(ActionService::class);
57  }
58 
59  public function ‪crossSiteScriptingDataProvider(): array
60  {
61  return [
62  [
63  'The "test" value might be =< x or > y...', // submitted payload
64  [
65  // @todo issue in `masterminds/html5`, first `<` should be parsed and encoded to `&lt;`
66  'The "test" value might be = x or &gt; y...', // default processing, HTML Sanitizer enabled
67  'The "test" value might be =< x or > y...', // default processing, HTML Sanitizer disabled
68  ],
69  ],
70  [
71  '<p undefined="<not-allowed>"></p>',
72  [
73  '<p></p>',
74  '<p></p>',
75  ],
76  ],
77  [
78  '<p undefined=<not-allowed>></p>',
79  [
80  '<p></p>',
81  '<p></p>',
82  ],
83  ],
84  [
85  '<p title="<encode-me>"></p>',
86  [
87  '<p title="&lt;encode-me&gt;"></p>',
88  '<p title="&lt;encode-me&gt;"></p>',
89  ],
90  ],
91  [
92  '<p title=<encode-me>></p>',
93  [
94  '<p title="&lt;encode-me&gt;"></p>',
95  '<p title="&lt;encode-me&gt;"></p>',
96  ],
97  ],
98  [
99  '<p title="""></p>',
100  [
101  '<p></p>',
102  '<p></p>',
103  ],
104  ],
105  [
106  '<p title="title"></p>',
107  [
108  '<p title="title"></p>',
109  '<p title="title"></p>',
110  ],
111  ],
112  [
113  '<p title="escape"<img src=src>"></p>',
114  [
115  '<p title="escape">"&gt;</p>',
116  '<p title="escape">"></p>',
117  ],
118  ],
119  [
120  '<p title=""""></p>',
121  [
122  '<p title></p>',
123  '<p title></p>',
124  ],
125  ],
126  [
127  '<p title=""anything"></p>',
128  [
129  '<p></p>',
130  '<p></p>',
131  ],
132  ],
133  [
134  '<p title=""anything""></p>',
135  [
136  '<p title></p>',
137  '<p title></p>',
138  ],
139  ],
140  [
141  '<p title="anything""></p>',
142  [
143  '<p></p>',
144  '<p></p>',
145  ],
146  ],
147  [
148  '<not-allowed><p title="</not-allowed><img src=x onerror=alert(1)><img src=x onerror=alert(2)>',
149  [
150  '<p>&lt;not-allowed&gt;</p>' . "\r\n" . '<p></p>',
151  '<p>&lt;not-allowed&gt;</p>' . "\r\n" . '<p></p>',
152  ],
153  ],
154  [
155  '<not-allowed><p title="</not-allowed><img src="x" onerror="alert(1)"><img src="x" onerror="alert(2)">',
156  [
157  '<p>&lt;not-allowed&gt;</p>' . "\r\n" . '<p></p>',
158  '<p>&lt;not-allowed&gt;</p>' . "\r\n" . '<p></p>',
159  ],
160  ],
161  [
162  '<script>alert(3)</script>',
163  [
164  '&lt;script&gt;alert(3)&lt;/script&gt;',
165  '&lt;script&gt;alert(3)&lt;/script&gt;',
166  ],
167  ],
168  [
169  '<p><script>alert(3)</script></p>',
170  [
171  '<p>&lt;script&gt;alert(3)&lt;/script&gt;</p>',
172  '<p>&lt;script&gt;alert(3)&lt;/script&gt;</p>',
173  ],
174  ],
175  [
176  '<title>title</title>',
177  [
178  '&lt;title&gt;title&lt;/title&gt;',
179  '&lt;title&gt;title&lt;/title&gt;',
180  ],
181  ],
182  [
183  '<p><title>title</title></p>',
184  [
185  '<p>&lt;title&gt;title&lt;/title&gt;</p>',
186  '<p>&lt;title&gt;title&lt;/title&gt;</p>',
187  ],
188  ],
189  [
190  '<font face="a" color="b" onmouseover="alert(1);">text</font>'
191  . '<img src="x" alt="test" onerror="alert(2)">',
192  [
193  '<font face="a" color="b">text</font>'
194  . '<img src="x" alt="test">',
195  // @todo "expected" for the time being without using HTML Sanitizer
196  '<font face="a" color="b" onmouseover="alert(1);">text</font>'
197  . '<img src="x" alt="test" onerror="alert(2)">',
198  ],
199  ],
200  [
201  '<p>'
202  . '<font face="a" color="b" onmouseover="alert(1);">text</font>'
203  . '<img src="x" alt="test" onerror="alert(2)">'
204  . '</p>',
205  [
206  '<p><font face="a" color="b">text</font>'
207  . '<img src="x" alt="test"></p>',
208  // @todo "expected" for the time being without using HTML Sanitizer
209  '<p><font face="a" color="b" onmouseover="alert(1);">text</font>'
210  . '<img src="x" alt="test" onerror="alert(2)"></p>',
211  ],
212  ],
213  [
214  '<p><a href="https://typo3.org" target="_blank" rel="noreferrer" role="button" onmouseover="alert(1)">text</a></p>',
215  [
216  '<p><a href="https://typo3.org" target="_blank" rel="noreferrer" role="button">text</a></p>',
217  // @todo "expected" for the time being without using HTML Sanitizer
218  '<p><a href="https://typo3.org" target="_blank" rel="noreferrer" role="button" onmouseover="alert(1)">text</a></p>',
219  ],
220  ],
221  [
222  '<p><a href="t3://page?uid=1" target="_blank" rel="noreferrer" role="button" onmouseover="alert(1)">text</a></p>',
223  [
224  '<p><a href="t3://page?uid=1" target="_blank" rel="noreferrer" role="button">text</a></p>',
225  // @todo "expected" for the time being without using HTML Sanitizer
226  '<p><a href="t3://page?uid=1" target="_blank" rel="noreferrer" role="button" onmouseover="alert(1)">text</a></p>',
227  ],
228  ],
229  [
230  '<?xml >s<img src=x onerror=alert(1)> ?>',
231  [
232  '&lt;?xml &gt;s&lt;img src=x onerror=alert(1)&gt; ?&gt;',
233  '<?xml >s<img src=x onerror=alert(1)> ?>',
234  ],
235  ],
236  ];
237  }
238 
250  public function ‪markupIsSanitizedForContentBodytextWithHtmlSanitizerEnabled(string $input, array $expectations): void
251  {
252  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.backend.htmlSanitizeRte'] = true;
253  $newIds = $this->actionService->createNewRecord('tt_content', 1, [
254  'CType' => 'text',
255  'bodytext' => $input,
256  ]);
257  $contentId = current($newIds['tt_content'] ?? 0);
258  self::assertGreaterThan(0, $contentId, 'Could not resolve content id');
259 
260  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
261  ->getConnectionForTable('tt_content');
262  $record = $connection->select(['bodytext'], 'tt_content', ['uid' => (int)$contentId])->fetchAssociative();
263  $bodytext = $record['bodytext'] ?? null;
264 
265  $expectation = $expectations[0];
266  self::assertSame($expectation, $bodytext, sprintf('Given markup: `%s`', $input));
267  }
268 
280  public function ‪markupIsSanitizedForContentBodytextWithHtmlSanitizerDisabled(string $input, array $expectations): void
281  {
282  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.backend.htmlSanitizeRte'] = false;
283  $newIds = $this->actionService->createNewRecord('tt_content', 1, [
284  'CType' => 'text',
285  'bodytext' => $input,
286  ]);
287  $contentId = current($newIds['tt_content'] ?? 0);
288  self::assertGreaterThan(0, $contentId, 'Could not resolve content id');
289 
290  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
291  ->getConnectionForTable('tt_content');
292  $record = $connection->select(['bodytext'], 'tt_content', ['uid' => (int)$contentId])->fetchAssociative();
293  $bodytext = $record['bodytext'] ?? null;
294 
295  $expectation = $expectations[1];
296  self::assertSame($expectation, $bodytext, sprintf('Given markup: `%s`', $input));
297  }
298 }
‪TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler
Definition: DefaultValuesTest.php:18
‪TYPO3\CMS\Core\Context\WorkspaceAspect
Definition: WorkspaceAspect.php:31
‪TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler\SecurityTest\$backendUser
‪BackendUserAuthentication $backendUser
Definition: SecurityTest.php:36
‪TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler\SecurityTest\crossSiteScriptingDataProvider
‪crossSiteScriptingDataProvider()
Definition: SecurityTest.php:57
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:53
‪TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler\SecurityTest\markupIsSanitizedForContentBodytextWithHtmlSanitizerDisabled
‪markupIsSanitizedForContentBodytextWithHtmlSanitizerDisabled(string $input, array $expectations)
Definition: SecurityTest.php:278
‪TYPO3\CMS\Core\Core\Bootstrap\initializeLanguageObject
‪static initializeLanguageObject()
Definition: Bootstrap.php:598
‪TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler\SecurityTest\markupIsSanitizedForContentBodytextWithHtmlSanitizerEnabled
‪markupIsSanitizedForContentBodytextWithHtmlSanitizerEnabled(string $input, array $expectations)
Definition: SecurityTest.php:248
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler\SecurityTest\$actionService
‪ActionService $actionService
Definition: SecurityTest.php:40
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler\SecurityTest\$coreExtensionsToLoad
‪$coreExtensionsToLoad
Definition: SecurityTest.php:42
‪TYPO3\CMS\Core\Core\Bootstrap
Definition: Bootstrap.php:70
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler\SecurityTest\setUp
‪setUp()
Definition: SecurityTest.php:44
‪TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler\SecurityTest
Definition: SecurityTest.php:33