Skip to content

Commit

Permalink
[BUGFIX] Fix redirects to access restricted pages
Browse files Browse the repository at this point in the history
The RedirectService is using typolink to build links
to the defined target, e.g. a page. In case the redirect
target is an access restricted page and the user is
unauthorized, typolink did not build this link and
therefore the request resulted in a 404 response.

Since unauthorized requests to an access restricted
page should always return a 403 status code, the
`linkAccessRestrictedPages` option is now set in the
typolink configuration. Therefore, the link will be built
even if the user is unauthorized and then redirects to
the target page where the correct 403 status code is
returned.

Resolves: #91879
Releases: master, 10.4
Change-Id: Ib82595abb12fae2c5629920d02b08e5e3144301b
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/67498
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Richard Haeser <richard@richardhaeser.com>
Tested-by: Benjamin Franzke <bfr@qbus.de>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Richard Haeser <richard@richardhaeser.com>
Reviewed-by: Benjamin Franzke <bfr@qbus.de>
  • Loading branch information
o-ba authored and bnf committed Feb 10, 2021
1 parent f5f0881 commit 2696082
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
1 change: 1 addition & 0 deletions typo3/sysext/redirects/Classes/Service/RedirectService.php
Expand Up @@ -283,6 +283,7 @@ protected function getUriFromCustomLinkDetails(array $redirectRecord, ?SiteInter
$configuration = [
'parameter' => (string)$redirectRecord['target'],
'forceAbsoluteUrl' => true,
'linkAccessRestrictedPages' => true
];
if ($redirectRecord['force_https']) {
$configuration['forceAbsoluteUrl.']['scheme'] = 'https';
Expand Down
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<pages>
<uid>1</uid>
<pid>0</pid>
<title>Root</title>
<slug>/</slug>
<hidden>0</hidden>
<deleted>0</deleted>
<fe_group>0</fe_group>
</pages>
<pages>
<uid>2</uid>
<pid>1</pid>
<title>Access restricted page</title>
<slug>/access-restricted</slug>
<hidden>0</hidden>
<deleted>0</deleted>
<!-- Access restricted to fe_group=1 -->
<fe_group>1</fe_group>
</pages>
<sys_redirect>
<uid>1</uid>
<pid>0</pid>
<disabled>0</disabled>
<deleted>0</deleted>
<source_host>acme.com</source_host>
<source_path>/redirect-to-access-restricted-site</source_path>
<target>t3://page?uid=2</target>
</sys_redirect>
</dataset>
@@ -0,0 +1,111 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

namespace TYPO3\CMS\Redirects\Tests\Functional\Service;

use Psr\Log\LoggerInterface;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
use TYPO3\CMS\Core\Http\ServerRequest;
use TYPO3\CMS\Core\Http\Uri;
use TYPO3\CMS\Core\LinkHandling\LinkService;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
use TYPO3\CMS\Redirects\Service\RedirectCacheService;
use TYPO3\CMS\Redirects\Service\RedirectService;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;

class RedirectServiceTest extends FunctionalTestCase
{
use SiteBasedTestTrait;

/**
* @var string[]
*/
protected $coreExtensionsToLoad = ['redirects'];

protected array $testFilesToDelete = [];

protected function tearDown(): void
{
foreach ($this->testFilesToDelete as $filename) {
if (@is_file($filename)) {
unlink($filename);
}
}
parent::tearDown();
}

/**
* @test
*/
public function linkForRedirectToAccessRestrictedPageIsBuild(): void
{
$this->importDataSet(__DIR__ . '/Fixtures/RedirectToAccessRestrictedPages.xml');

$this->writeSiteConfiguration(
'acme-com',
$this->buildSiteConfiguration(1, 'https://acme.com/')
);

$typoscriptFile = Environment::getVarPath() . '/transient/setup.typoscript';
file_put_contents($typoscriptFile, 'page = PAGE' . PHP_EOL . 'page.typeNum = 0');
$this->testFilesToDelete[] = $typoscriptFile;
$this->setUpFrontendRootPage(1, [$typoscriptFile]);

$logger = $this->prophesize(LoggerInterface::class);
$frontendUserAuthentication = new FrontendUserAuthentication();
$frontendUserAuthentication->setLogger($logger->reveal());

$siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
$uri = new Uri('https://acme.com/redirect-to-access-restricted-site');
$request = $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest($uri))
->withAttribute('site', $siteFinder->getSiteByRootPageId(1))
->withAttribute('frontend.user', $frontendUserAuthentication)
->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_FE);

$linkServiceProphecy = $this->prophesize(LinkService::class);
$linkServiceProphecy->resolve('t3://page?uid=2')->willReturn(
[
'pageuid' => 2,
'type' => LinkService::TYPE_PAGE
]
);

$redirectService = new RedirectService(
new RedirectCacheService(),
$linkServiceProphecy->reveal(),
$siteFinder
);
$redirectService->setLogger($logger->reveal());

// Assert correct redirect is matched
$redirectMatch = $redirectService->matchRedirect($uri->getHost(), $uri->getPath(), $uri->getQuery());
self::assertEquals(1, $redirectMatch['uid']);
self::assertEquals('t3://page?uid=2', $redirectMatch['target']);

// Ensure we deal with an unauthorized request!
self::assertFalse(GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('frontend.user', 'isLoggedIn'));

// Assert link to access restricted page is build
$targetUrl = $redirectService->getTargetUrl($redirectMatch, $request);
self::assertEquals(new Uri('https://acme.com/access-restricted'), $targetUrl);
}
}

0 comments on commit 2696082

Please sign in to comment.