‪TYPO3CMS  10.4
RedirectUrlValidatorTest.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 
20 use Psr\Log\NullLogger;
25 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
26 
30 class ‪RedirectUrlValidatorTest extends UnitTestCase
31 {
35  protected ‪$backupEnvironment = true;
36 
40  protected ‪$accessibleFixture;
41 
45  protected ‪$testHostName;
46 
50  protected ‪$testSitePath;
51 
52  protected ‪$resetSingletonInstances = true;
53 
57  protected function ‪setUp(): void
58  {
59  parent::setUp();
60 
61  $site1 = new ‪Site('dummy', 1, ['base' => 'http://sub.domainhostname.tld/path/']);
62  $site2 = new ‪Site('dummy', 1, ['base' => 'http://sub2.domainhostname.tld/']);
63  $mockedSiteFinder = $this->getAccessibleMock(SiteFinder::class, ['getAllSites'], [], '', false, false);
64  $mockedSiteFinder->method('getAllSites')->willReturn([$site1, $site2]);
65 
66  $this->testHostName = 'hostname.tld';
67  $this->testSitePath = '/';
68  $this->accessibleFixture = $this->getAccessibleMock(RedirectUrlValidator::class, ['dummy'], [$mockedSiteFinder]);
69  $this->accessibleFixture->setLogger(new NullLogger());
71  }
72 
76  protected function ‪setUpFakeSitePathAndHost()
77  {
78  $_SERVER['SCRIPT_NAME'] = $this->testSitePath . TYPO3_mainDir;
79  $_SERVER['HTTP_HOST'] = ‪$this->testHostName;
80  }
81 
88  {
89  return [
90  'absolute URL, hostname not in site, trailing slash' => ['http://badhost.tld/'],
91  'absolute URL, hostname not in site, no trailing slash' => ['http://badhost.tld'],
92  'absolute URL, subdomain in site, but main domain not, trailing slash' => ['http://domainhostname.tld.badhost.tld/'],
93  'absolute URL, subdomain in site, but main domain not, no trailing slash' => ['http://domainhostname.tld.badhost.tld'],
94  'non http absolute URL 1' => ['its://domainhostname.tld/itunes/'],
95  'non http absolute URL 2' => ['ftp://domainhostname.tld/download/'],
96  'XSS attempt 1' => ['javascript:alert(123)'],
97  'XSS attempt 2' => ['" onmouseover="alert(123)"'],
98  'invalid URL, HTML break out attempt' => ['" >blabuubb'],
99  'invalid URL, UNC path' => ['\\\\foo\\bar\\'],
100  'invalid URL, backslashes in path' => ['http://domainhostname.tld\\bla\\blupp'],
101  'invalid URL, linefeed in path' => ['http://domainhostname.tld/bla/blupp' . LF],
102  'invalid URL, only one slash after scheme' => ['http:/domainhostname.tld/bla/blupp'],
103  'invalid URL, illegal chars' => ['http://(<>domainhostname).tld/bla/blupp'],
104  ];
105  }
106 
112  public function ‪validateRedirectUrlClearsUrl($url)
113  {
116  true,
117  false,
122  ‪Environment::getBackendPath() . '/index.php',
123  ‪Environment::isWindows() ? 'WINDOWS' : 'UNIX'
124  );
125  self::assertFalse($this->accessibleFixture->isValid($url));
126  }
127 
134  {
135  return [
136  'sane absolute URL' => ['http://sub.domainhostname.tld/path/'],
137  'sane absolute URL with script' => ['http://sub.domainhostname.tld/path/index.php?id=1'],
138  'sane absolute URL with realurl' => ['http://sub.domainhostname.tld/path/foo/bar/foo.html'],
139  'sane absolute URL with homedir' => ['http://sub.domainhostname.tld/path/~user/'],
140  'sane absolute URL with some strange chars encoded' => ['http://sub.domainhostname.tld/path/~user/a%cc%88o%cc%88%c3%9fa%cc%82/foo.html'],
141  'relative URL, no leading slash 1' => ['index.php?id=1'],
142  'relative URL, no leading slash 2' => ['foo/bar/index.php?id=2'],
143  'relative URL, leading slash, no realurl' => ['/index.php?id=1'],
144  'relative URL, leading slash, realurl' => ['/de/service/imprint.html'],
145  ];
146  }
147 
153  public function ‪validateRedirectUrlKeepsCleanUrl($url)
154  {
157  true,
158  false,
163  ‪Environment::getBackendPath() . '/index.php',
164  ‪Environment::isWindows() ? 'WINDOWS' : 'UNIX'
165  );
166  self::assertTrue($this->accessibleFixture->isValid($url));
167  }
168 
175  {
176  return [
177  'absolute URL, missing subdirectory' => ['http://hostname.tld/'],
178  'absolute URL, wrong subdirectory' => ['http://hostname.tld/hacker/index.php'],
179  'absolute URL, correct subdirectory, no trailing slash' => ['http://hostname.tld/subdir'],
180  'relative URL, leading slash, no path' => ['/index.php?id=1'],
181  'relative URL, leading slash, wrong path' => ['/de/sub/site.html'],
182  'relative URL, leading slash, slash only' => ['/'],
183  ];
184  }
185 
192  {
193  $this->testSitePath = '/subdir/';
195  self::assertFalse($this->accessibleFixture->isValid($url));
196  }
197 
204  {
205  return [
206  'absolute URL, correct subdirectory' => ['http://hostname.tld/subdir/'],
207  'absolute URL, correct subdirectory, realurl' => ['http://hostname.tld/subdir/de/imprint.html'],
208  'absolute URL, correct subdirectory, no realurl' => ['http://hostname.tld/subdir/index.php?id=10'],
209  'absolute URL, correct subdirectory of site base' => ['http://sub.domainhostname.tld/path/'],
210  'relative URL, no leading slash, realurl' => ['de/service/imprint.html'],
211  'relative URL, no leading slash, no realurl' => ['index.php?id=1'],
212  'relative nested URL, no leading slash, no realurl' => ['foo/bar/index.php?id=2']
213  ];
214  }
215 
222  {
225  true,
226  false,
231  ‪Environment::getBackendPath() . '/index.php',
232  ‪Environment::isWindows() ? 'WINDOWS' : 'UNIX'
233  );
234  $this->testSitePath = '/subdir/';
236  self::assertTrue($this->accessibleFixture->isValid($url));
237  }
238 
239  /**************************************************
240  * Tests concerning isInCurrentDomain
241  **************************************************/
242 
249  {
250  return [
251  'url https, current host http' => [
252  'example.com', // HTTP_HOST
253  '0', // HTTPS
254  'https://example.com/foo.html' // URL
255  ],
256  'url http, current host https' => [
257  'example.com',
258  '1',
259  'http://example.com/foo.html'
260  ],
261  'url https, current host https' => [
262  'example.com',
263  '1',
264  'https://example.com/foo.html'
265  ],
266  'url http, current host http' => [
267  'example.com',
268  '0',
269  'http://example.com/foo.html'
270  ]
271  ];
272  }
273 
281  public function ‪isInCurrentDomainIgnoresScheme($host, $https, $url)
282  {
285  true,
286  false,
291  ‪Environment::getBackendPath() . '/index.php',
292  ‪Environment::isWindows() ? 'WINDOWS' : 'UNIX'
293  );
294  $_SERVER['HTTP_HOST'] = $host;
295  $_SERVER['HTTPS'] = $https;
296  self::assertTrue($this->accessibleFixture->_call('isInCurrentDomain', $url));
297  }
298 
303  {
304  return [
305  'simple difference' => [
306  'example.com', // HTTP_HOST
307  'http://typo3.org/foo.html' // URL
308  ],
309  'subdomain different' => [
310  'example.com',
311  'http://foo.example.com/bar.html'
312  ]
313  ];
314  }
315 
322  public function ‪isInCurrentDomainReturnsFalseIfDomainsAreDifferent($host, $url)
323  {
324  $_SERVER['HTTP_HOST'] = $host;
325  self::assertFalse($this->accessibleFixture->_call('isInCurrentDomain', $url));
326  }
327 
328  /**************************************************
329  * Tests concerning isInLocalDomain
330  **************************************************/
331 
335  public function ‪isInLocalDomainValidatesSites()
336  {
337  $url = 'http://example.com';
338  self::assertFalse($this->accessibleFixture->_call('isInLocalDomain', $url));
339 
340  $url = 'http://sub2.domainhostname.tld/some/path';
341  self::assertTrue($this->accessibleFixture->_call('isInLocalDomain', $url));
342  }
343 }
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation
Definition: RedirectUrlValidatorTest.php:18
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\isInCurrentDomainIgnoresScheme
‪isInCurrentDomainIgnoresScheme($host, $https, $url)
Definition: RedirectUrlValidatorTest.php:277
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\validateRedirectUrlKeepsCleanUrl
‪validateRedirectUrlKeepsCleanUrl($url)
Definition: RedirectUrlValidatorTest.php:149
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:180
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\isInLocalDomainValidatesSites
‪isInLocalDomainValidatesSites()
Definition: RedirectUrlValidatorTest.php:331
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\$testHostName
‪string $testHostName
Definition: RedirectUrlValidatorTest.php:42
‪TYPO3\CMS\Core\Core\Environment\isWindows
‪static bool isWindows()
Definition: Environment.php:292
‪TYPO3\CMS\Core\Site\SiteFinder
Definition: SiteFinder.php:31
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest
Definition: RedirectUrlValidatorTest.php:31
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\$accessibleFixture
‪RedirectUrlValidator TYPO3 TestingFramework Core AccessibleObjectInterface $accessibleFixture
Definition: RedirectUrlValidatorTest.php:38
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\validateRedirectUrlClearsInvalidUrlInSubdirectory
‪validateRedirectUrlClearsInvalidUrlInSubdirectory($url)
Definition: RedirectUrlValidatorTest.php:187
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\$testSitePath
‪string $testSitePath
Definition: RedirectUrlValidatorTest.php:46
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\$resetSingletonInstances
‪$resetSingletonInstances
Definition: RedirectUrlValidatorTest.php:48
‪TYPO3\CMS\Core\Core\Environment\getContext
‪static ApplicationContext getContext()
Definition: Environment.php:133
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:40
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\validateRedirectUrlKeepsCleanUrlInSubdirectoryDataProvider
‪array validateRedirectUrlKeepsCleanUrlInSubdirectoryDataProvider()
Definition: RedirectUrlValidatorTest.php:199
‪TYPO3\CMS\Core\Core\Environment\getProjectPath
‪static string getProjectPath()
Definition: Environment.php:169
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\validateRedirectUrlClearsUrl
‪validateRedirectUrlClearsUrl($url)
Definition: RedirectUrlValidatorTest.php:108
‪TYPO3\CMS\Core\Core\Environment\initialize
‪static initialize(ApplicationContext $context, bool $cli, bool $composerMode, string $projectPath, string $publicPath, string $varPath, string $configPath, string $currentScript, string $os)
Definition: Environment.php:104
‪TYPO3\CMS\Core\Core\Environment\getBackendPath
‪static string getBackendPath()
Definition: Environment.php:250
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\isInCurrentDomainReturnsFalseIfDomainsAreDifferentDataProvider
‪array isInCurrentDomainReturnsFalseIfDomainsAreDifferentDataProvider()
Definition: RedirectUrlValidatorTest.php:298
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\validateRedirectUrlKeepsCleanUrlInSubdirectory
‪validateRedirectUrlKeepsCleanUrlInSubdirectory($url)
Definition: RedirectUrlValidatorTest.php:217
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\validateRedirectUrlClearsInvalidUrlInSubdirectoryDataProvider
‪array validateRedirectUrlClearsInvalidUrlInSubdirectoryDataProvider()
Definition: RedirectUrlValidatorTest.php:170
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\setUp
‪setUp()
Definition: RedirectUrlValidatorTest.php:53
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\validateRedirectUrlKeepsCleanUrlDataProvider
‪array validateRedirectUrlKeepsCleanUrlDataProvider()
Definition: RedirectUrlValidatorTest.php:129
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:40
‪TYPO3\CMS\Core\Core\Environment\getConfigPath
‪static string getConfigPath()
Definition: Environment.php:210
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\setUpFakeSitePathAndHost
‪setUpFakeSitePathAndHost()
Definition: RedirectUrlValidatorTest.php:72
‪TYPO3\CMS\FrontendLogin\Validation\RedirectUrlValidator
Definition: RedirectUrlValidator.php:32
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\validateRedirectUrlClearsUrlDataProvider
‪array validateRedirectUrlClearsUrlDataProvider()
Definition: RedirectUrlValidatorTest.php:83
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\isInCurrentDomainReturnsFalseIfDomainsAreDifferent
‪isInCurrentDomainReturnsFalseIfDomainsAreDifferent($host, $url)
Definition: RedirectUrlValidatorTest.php:318
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\$backupEnvironment
‪bool $backupEnvironment
Definition: RedirectUrlValidatorTest.php:34
‪TYPO3\CMS\Core\Core\Environment\getVarPath
‪static string getVarPath()
Definition: Environment.php:192
‪TYPO3\CMS\FrontendLogin\Tests\Unit\Validation\RedirectUrlValidatorTest\isInCurrentDomainIgnoresSchemeDataProvider
‪array isInCurrentDomainIgnoresSchemeDataProvider()
Definition: RedirectUrlValidatorTest.php:244