diff --git a/typo3/sysext/backend/Configuration/Backend/Routes.php b/typo3/sysext/backend/Configuration/Backend/Routes.php
index 9e3978d0494efeb8fc31c5babb04a5c7195af033..5e5f4553822dbb4a5f2e685e62b9eb08b541eecd 100644
--- a/typo3/sysext/backend/Configuration/Backend/Routes.php
+++ b/typo3/sysext/backend/Configuration/Backend/Routes.php
@@ -23,7 +23,7 @@ return [
     // Main backend rendering setup (previously called backend.php) for the TYPO3 Backend
     'main' => [
         'path' => '/main',
-        'referrer' => 'required,refresh-empty',
+        'referrer' => 'required,refresh-always',
         'target' => Controller\BackendController::class . '::mainAction'
     ],
 
diff --git a/typo3/sysext/core/Classes/Http/Security/ReferrerEnforcer.php b/typo3/sysext/core/Classes/Http/Security/ReferrerEnforcer.php
index f4497c65487936c4957f63fbe1a7cacb76fca15d..5a7b840d4372d7ad4f63a73a0d79ddb2500988c6 100644
--- a/typo3/sysext/core/Classes/Http/Security/ReferrerEnforcer.php
+++ b/typo3/sysext/core/Classes/Http/Security/ReferrerEnforcer.php
@@ -29,11 +29,20 @@ use TYPO3\CMS\Core\Utility\PathUtility;
  */
 class ReferrerEnforcer
 {
+    private const TYPE_REFERRER_EMPTY = 1;
+    private const TYPE_REFERRER_SAME_SITE = 2;
+    private const TYPE_REFERRER_SAME_ORIGIN = 4;
+
     /**
      * @var ServerRequestInterface
      */
     protected $request;
 
+    /**
+     * @var string
+     */
+    protected $requestHost;
+
     /**
      * @var string
      */
@@ -42,14 +51,15 @@ class ReferrerEnforcer
     public function __construct(ServerRequestInterface $request)
     {
         $this->request = $request;
+        $this->requestHost = rtrim($this->resolveRequestHost($request), '/') . '/';
         $this->requestDir = $this->resolveRequestDir($request);
     }
 
     public function handle(array $options = null): ?ResponseInterface
     {
-        $referrer = $this->request->getServerParams()['HTTP_REFERER'] ?? '';
+        $referrerType = $this->resolveReferrerType();
         // valid referrer, no more actions required
-        if ($referrer !== '' && strpos($referrer, $this->requestDir) === 0) {
+        if ($referrerType & self::TYPE_REFERRER_SAME_ORIGIN) {
             return null;
         }
         $flags = $options['flags'] ?? [];
@@ -57,13 +67,18 @@ class ReferrerEnforcer
         // referrer is missing and route requested to refresh
         // (created HTML refresh to enforce having referrer)
         if (($this->request->getQueryParams()['referrer-refresh'] ?? 0) <= time()
-            && $referrer === '' && in_array('refresh-empty', $flags, true)) {
+            && (
+                in_array('refresh-always', $flags, true)
+                || ($referrerType & self::TYPE_REFERRER_EMPTY && in_array('refresh-empty', $flags, true))
+                || ($referrerType & self::TYPE_REFERRER_SAME_SITE && in_array('refresh-same-site', $flags, true))
+            )
+        ) {
             $refreshUri = $this->request->getUri();
             $refreshUri = $refreshUri->withQuery(
                 $refreshUri->getQuery() . '&referrer-refresh=' . (time() + $expiration)
             );
-            $scriptUri = PathUtility::getAbsoluteWebPath(
-                GeneralUtility::getFileAbsFileName('EXT:core/Resources/Public/JavaScript/ReferrerRefresh.js')
+            $scriptUri = $this->resolveAbsoluteWebPath(
+                'EXT:core/Resources/Public/JavaScript/ReferrerRefresh.js'
             );
             // simulating navigate event by clicking anchor link
             // since meta-refresh won't change `document.referrer` in e.g. Firefox
@@ -78,7 +93,7 @@ class ReferrerEnforcer
             ));
         }
         $subject = $options['subject'] ?? '';
-        if ($referrer === '') {
+        if ($referrerType & self::TYPE_REFERRER_EMPTY) {
             // still empty referrer or invalid referrer, deny route invocation
             throw new MissingReferrerException(
                 sprintf('Missing referrer%s', $subject !== '' ? ' for ' . $subject : ''),
@@ -87,11 +102,43 @@ class ReferrerEnforcer
         }
         // referrer is given, but does not match current base URL
         throw new InvalidReferrerException(
-            sprintf('Missing referrer%s', $subject !== '' ? ' for ' . $subject : ''),
+            sprintf('Invalid referrer%s', $subject !== '' ? ' for ' . $subject : ''),
             1588095936
         );
     }
 
+    protected function resolveAbsoluteWebPath(string $target): string
+    {
+        return PathUtility::getAbsoluteWebPath(
+            GeneralUtility::getFileAbsFileName($target)
+        );
+    }
+
+    protected function resolveReferrerType(): int
+    {
+        $referrer = $this->request->getServerParams()['HTTP_REFERER'] ?? '';
+        if ($referrer === '') {
+            return self::TYPE_REFERRER_EMPTY;
+        }
+        if (strpos($referrer, $this->requestDir) === 0) {
+            // same-origin implies same-site
+            return self::TYPE_REFERRER_SAME_ORIGIN | self::TYPE_REFERRER_SAME_SITE;
+        }
+        if (strpos($referrer, $this->requestHost) === 0) {
+            return self::TYPE_REFERRER_SAME_SITE;
+        }
+        return 0;
+    }
+
+    protected function resolveRequestHost(ServerRequestInterface $request): string
+    {
+        $normalizedParams = $request->getAttribute('normalizedParams');
+        if ($normalizedParams instanceof NormalizedParams) {
+            return $normalizedParams->getRequestHost();
+        }
+        return GeneralUtility::getIndpEnv('TYPO3_REQUEST_HOST');
+    }
+
     protected function resolveRequestDir(ServerRequestInterface $request): string
     {
         $normalizedParams = $request->getAttribute('normalizedParams');
diff --git a/typo3/sysext/core/Tests/Unit/Http/Security/ReferrerEnforcerTest.php b/typo3/sysext/core/Tests/Unit/Http/Security/ReferrerEnforcerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..aee48a75638c297312e98a6f2d5da46fcb545ce8
--- /dev/null
+++ b/typo3/sysext/core/Tests/Unit/Http/Security/ReferrerEnforcerTest.php
@@ -0,0 +1,183 @@
+<?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\Core\Tests\Unit\Http\Security;
+
+use Prophecy\Prophecy\ObjectProphecy;
+use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Core\Http\NormalizedParams;
+use TYPO3\CMS\Core\Http\Security\InvalidReferrerException;
+use TYPO3\CMS\Core\Http\Security\MissingReferrerException;
+use TYPO3\CMS\Core\Http\Security\ReferrerEnforcer;
+use TYPO3\CMS\Core\Http\Uri;
+use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
+
+class ReferrerEnforcerTest extends UnitTestCase
+{
+    private static function buildRefreshContentPattern(string $uri): string
+    {
+        return sprintf(
+            '#.+href="%s\d+" id="referrer-refresh".+#',
+            preg_quote(htmlspecialchars($uri . '&referrer-refresh='), '#')
+        );
+    }
+
+    public function validReferrerIsHandledDataProvider(): array
+    {
+        return [
+            [
+                'https://example.org/typo3/index.php?route=%2Flogin', // requestUri
+                'https://example.org/typo3/index.php', // referrer
+                null, // options
+                null, // response
+            ],
+            [
+                'https://example.org/typo3/index.php?route=%2Flogin',
+                '',
+                ['flags' => ['refresh-empty']],
+                self::buildRefreshContentPattern(
+                    'https://example.org/typo3/index.php?route=%2Flogin'
+                ),
+            ],
+            [
+                'https://example.org/typo3/index.php?route=%2Flogin',
+                'https://example.org/?eID=handler',
+                ['flags' => ['refresh-same-site']],
+                self::buildRefreshContentPattern(
+                    'https://example.org/typo3/index.php?route=%2Flogin'
+                ),
+            ],
+            [
+                'https://example.org/typo3/index.php?route=%2Flogin',
+                'https://other-example.site/security/',
+                ['flags' => ['refresh-always']],
+                self::buildRefreshContentPattern(
+                    'https://example.org/typo3/index.php?route=%2Flogin'
+                ),
+            ],
+        ];
+    }
+
+    /**
+     * @param string $requestUri
+     * @param string $referrer
+     * @param string[]|null $options
+     * @param string|null $expectedResponse
+     *
+     * @test
+     * @dataProvider validReferrerIsHandledDataProvider
+     */
+    public function validReferrerIsHandled(string $requestUri, string $referrer, ?array $options, ?string $expectedResponse): void
+    {
+        $subject = $this->buildSubject($requestUri, $referrer);
+        $response = $subject->handle($options);
+
+        if ($expectedResponse === null) {
+            self::assertNull($response);
+        } else {
+            self::assertRegExp($expectedResponse, (string)$response->getBody());
+        }
+    }
+
+    public function invalidReferrerIsHandledDataProvider(): array
+    {
+        return [
+            [
+                'https://example.org/typo3/index.php?route=%2Flogin', // requestUri
+                'https://example.org/?eID=handler', // referrer
+                null, // options
+            ],
+            [
+                'https://example.org/typo3/index.php?route=%2Flogin',
+                'https://example.org/?eID=handler',
+                ['flags' => ['refresh-empty']],
+            ],
+            [
+                'https://example.org/typo3/index.php?route=%2Flogin',
+                'https://example.org.security/?eID=handler',
+                ['flags' => ['refresh-same-site']],
+            ],
+            [
+                'https://example.org/typo3/index.php?route=%2Flogin',
+                'https://other-example.site/security/',
+                null,
+            ],
+        ];
+    }
+
+    /**
+     * @param string $requestUri
+     * @param string $referrer
+     * @param string[]|null $options
+     *
+     * @test
+     * @dataProvider invalidReferrerIsHandledDataProvider
+     */
+    public function invalidReferrerIsHandled(string $requestUri, string $referrer, ?array $options): void
+    {
+        $this->expectException(InvalidReferrerException::class);
+        $this->expectExceptionCode(1588095936);
+        $subject = $this->buildSubject($requestUri, $referrer);
+        $subject->handle($options);
+    }
+
+    /**
+     * @test
+     */
+    public function missingReferrerIsHandled(): void
+    {
+        $this->expectException(MissingReferrerException::class);
+        $this->expectExceptionCode(1588095935);
+        $subject = $this->buildSubject(
+            'https://example.org/typo3/index.php?route=%2Flogin',
+            ''
+        );
+        $subject->handle();
+    }
+
+    private function buildSubject(string $requestUri, string $referrer): ReferrerEnforcer
+    {
+        $requestUriInstance = new Uri($requestUri);
+        $host = sprintf(
+            '%s://%s',
+            $requestUriInstance->getScheme(),
+            $requestUriInstance->getHost()
+        );
+        $dir = $host . rtrim(dirname($requestUriInstance->getPath()), '/') . '/';
+        parse_str($requestUriInstance->getQuery(), $queryParams);
+
+        /** @var NormalizedParams|ObjectProphecy $normalizedParams */
+        $normalizedParams = $this->prophesize(NormalizedParams::class);
+        $normalizedParams->getRequestHost()->willReturn($host);
+        $normalizedParams->getRequestDir()->willReturn($dir);
+        /** @var ServerRequestInterface|ObjectProphecy $request */
+        $request = $this->prophesize(ServerRequestInterface::class);
+        $request->getAttribute('normalizedParams')->willReturn($normalizedParams);
+        $request->getServerParams()->willReturn(['HTTP_REFERER' => $referrer]);
+        $request->getUri()->willReturn($requestUriInstance);
+        $request->getQueryParams()->willReturn($queryParams);
+
+        $subject = $this->getMockBuilder(ReferrerEnforcer::class)
+            ->setConstructorArgs([$request->reveal()])
+            ->onlyMethods(['resolveAbsoluteWebPath'])
+            ->getMock();
+        $subject->method('resolveAbsoluteWebPath')
+            ->with('EXT:core/Resources/Public/JavaScript/ReferrerRefresh.js')
+            ->willReturn('/typo3/sysext/core/Resources/Public/JavaScript/ReferrerRefresh.js');
+        return $subject;
+    }
+}