diff --git a/typo3/sysext/backend/Classes/Backend/Shortcut/ShortcutRepository.php b/typo3/sysext/backend/Classes/Backend/Shortcut/ShortcutRepository.php
index 6b14bfe5cff09acde1b7e2e505dba31126260870..94b2cb4af8b7e3655032658f59f1eba28733d15d 100644
--- a/typo3/sysext/backend/Classes/Backend/Shortcut/ShortcutRepository.php
+++ b/typo3/sysext/backend/Classes/Backend/Shortcut/ShortcutRepository.php
@@ -565,8 +565,7 @@ class ShortcutRepository
             return $routeIdentifier;
         }
 
-        $route = $this->getRoute($routeIdentifier);
-        return $route !== null ? (string)($route->getOption('moduleName') ?? '') : '';
+        return (string)($this->getRoute($routeIdentifier)?->getOption('module')?->getIdentifier() ?? '');
     }
 
     /**
diff --git a/typo3/sysext/backend/Classes/Http/RouteDispatcher.php b/typo3/sysext/backend/Classes/Http/RouteDispatcher.php
index cc523eee31b118c3773a766774b39860412c943c..22498558d4ae93387b4cc6676fcc0d23507cac25 100644
--- a/typo3/sysext/backend/Classes/Http/RouteDispatcher.php
+++ b/typo3/sysext/backend/Classes/Http/RouteDispatcher.php
@@ -1,5 +1,7 @@
 <?php
 
+declare(strict_types=1);
+
 /*
  * This file is part of the TYPO3 CMS project.
  *
@@ -15,42 +17,24 @@
 
 namespace TYPO3\CMS\Backend\Http;
 
-use Psr\Container\ContainerInterface;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
-use TYPO3\CMS\Backend\Module\ModuleInterface;
-use TYPO3\CMS\Backend\Module\ModuleProvider;
 use TYPO3\CMS\Backend\Routing\Exception\InvalidRequestTokenException;
 use TYPO3\CMS\Backend\Routing\Exception\MissingRequestTokenException;
 use TYPO3\CMS\Backend\Routing\Route;
-use TYPO3\CMS\Backend\Routing\RouteRedirect;
 use TYPO3\CMS\Backend\Routing\UriBuilder;
-use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Configuration\Features;
 use TYPO3\CMS\Core\FormProtection\AbstractFormProtection;
 use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
 use TYPO3\CMS\Core\Http\Dispatcher;
-use TYPO3\CMS\Core\Http\RedirectResponse;
 use TYPO3\CMS\Core\Http\Security\ReferrerEnforcer;
-use TYPO3\CMS\Core\Type\Bitmask\Permission;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Core\Utility\MathUtility;
 
 /**
  * Dispatcher which resolves a route to call a controller and method (but also a callable)
  */
 class RouteDispatcher extends Dispatcher
 {
-    private UriBuilder $uriBuilder;
-    private ModuleProvider $moduleProvider;
-
-    public function __construct(ContainerInterface $container, UriBuilder $uriBuilder, ModuleProvider $moduleProvider)
-    {
-        parent::__construct($container);
-        $this->uriBuilder = $uriBuilder;
-        $this->moduleProvider = $moduleProvider;
-    }
-
     /**
      * Main method checks the target of the route, and tries to call it.
      *
@@ -72,23 +56,6 @@ class RouteDispatcher extends Dispatcher
         // Ensure that a token exists, and the token is requested, if the route requires a valid token
         $this->assertRequestToken($request, $route);
 
-        if ($route->hasOption('module')) {
-            $this->validateModule($request, $route);
-
-            // This module request (which is usually opened inside the list_frame)
-            // has been issued from a toplevel browser window (e.g. a link was opened in a new tab).
-            // Redirect to open the module as frame inside the TYPO3 backend layout.
-            // HEADS UP: This header will only be available in secure connections (https:// or .localhost TLD)
-            if ($request->getHeaderLine('Sec-Fetch-Dest') === 'document') {
-                return new RedirectResponse(
-                    $this->uriBuilder->buildUriWithRedirect(
-                        'main',
-                        [],
-                        RouteRedirect::createFromRoute($route, $request->getQueryParams())
-                    )
-                );
-            }
-        }
         $targetIdentifier = $route->getOption('target');
         $target = $this->getCallableFromTarget($targetIdentifier);
         $arguments = [$request];
@@ -100,7 +67,7 @@ class RouteDispatcher extends Dispatcher
      *
      * @return AbstractFormProtection
      */
-    protected function getFormProtection()
+    protected function getFormProtection(): AbstractFormProtection
     {
         return FormProtectionFactory::get();
     }
@@ -161,40 +128,4 @@ class RouteDispatcher extends Dispatcher
             );
         }
     }
-
-    /**
-     * Fetches the module object from the resolved route and checks permissions
-     * for the current user. Furthermore, evaluates page access permissions, in
-     * case an "id" is given in the request.
-     *
-     * @param ServerRequestInterface $request
-     * @param Route $route
-     * @throws \RuntimeException
-     */
-    protected function validateModule(ServerRequestInterface $request, Route $route): void
-    {
-        $backendUserAuthentication = $GLOBALS['BE_USER'];
-        $module = $route->getOption('module');
-
-        if (!($module instanceof ModuleInterface)
-            || !$this->moduleProvider->accessGranted($module->getIdentifier(), $backendUserAuthentication)
-        ) {
-            throw new \RuntimeException('You don\'t have access to this module.', 1642450334);
-        }
-
-        // '' for "no value found at all" to guarantee that the following if condition fails.
-        $id = $request->getQueryParams()['id'] ?? $request->getParsedBody()['id'] ?? '';
-        if (MathUtility::canBeInterpretedAsInteger($id) && $id > 0) {
-            $permClause = $backendUserAuthentication->getPagePermsClause(Permission::PAGE_SHOW);
-            // Check page access
-            if (!is_array(BackendUtility::readPageAccess($id, $permClause))) {
-                // Check if page has been deleted
-                $deleteField = $GLOBALS['TCA']['pages']['ctrl']['delete'];
-                $pageInfo = BackendUtility::getRecord('pages', $id, $deleteField, $permClause ? ' AND ' . $permClause : '', false);
-                if (!($pageInfo[$deleteField] ?? false)) {
-                    throw new \RuntimeException('You don\'t have access to this page', 1289917924);
-                }
-            }
-        }
-    }
 }
diff --git a/typo3/sysext/backend/Classes/Middleware/BackendModuleValidator.php b/typo3/sysext/backend/Classes/Middleware/BackendModuleValidator.php
new file mode 100644
index 0000000000000000000000000000000000000000..ccbbc055e2e478dd2078148cf414295d34e9de7c
--- /dev/null
+++ b/typo3/sysext/backend/Classes/Middleware/BackendModuleValidator.php
@@ -0,0 +1,115 @@
+<?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\Backend\Middleware;
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use TYPO3\CMS\Backend\Module\ModuleInterface;
+use TYPO3\CMS\Backend\Module\ModuleProvider;
+use TYPO3\CMS\Backend\Routing\Route;
+use TYPO3\CMS\Backend\Routing\RouteRedirect;
+use TYPO3\CMS\Backend\Routing\UriBuilder;
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Http\RedirectResponse;
+use TYPO3\CMS\Core\Type\Bitmask\Permission;
+use TYPO3\CMS\Core\Utility\MathUtility;
+
+/**
+ * Validates module access and extends the PSR-7 Request with the
+ * resolved module object for the use in further components.
+ *
+ * @internal
+ */
+class BackendModuleValidator implements MiddlewareInterface
+{
+    public function __construct(
+        protected readonly UriBuilder $uriBuilder,
+        protected readonly ModuleProvider $moduleProvider
+    ) {
+    }
+
+    /**
+     * In case the current route targets a TYPO3 backend module and the user
+     * has necessary access permissions, add the module to the request.
+     *
+     * @param ServerRequestInterface $request
+     * @param RequestHandlerInterface $handler
+     * @return ResponseInterface
+     */
+    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+    {
+        /** @var Route $route */
+        $route = $request->getAttribute('route');
+
+        if ($route->hasOption('module')
+            && ($module = $route->getOption('module')) instanceof ModuleInterface
+        ) {
+            $this->validateModuleAccess($request, $module);
+
+            // This module request (which is usually opened inside the list_frame)
+            // has been issued from a toplevel browser window (e.g. a link was opened in a new tab).
+            // Redirect to open the module as frame inside the TYPO3 backend layout.
+            // HEADS UP: This header will only be available in secure connections (https:// or .localhost TLD)
+            if ($request->getHeaderLine('Sec-Fetch-Dest') === 'document') {
+                return new RedirectResponse(
+                    $this->uriBuilder->buildUriWithRedirect(
+                        'main',
+                        [],
+                        RouteRedirect::createFromRoute($route, $request->getQueryParams())
+                    )
+                );
+            }
+
+            // Add the validated module to the current request
+            $request = $request->withAttribute('module', $module);
+        }
+
+        return $handler->handle($request);
+    }
+
+    /**
+     * Checks whether the current user is allowed to access the requested module. Does
+     * also evaluate page access permissions, in case an "id" is given in the request.
+     *
+     * @throws \RuntimeException
+     */
+    protected function validateModuleAccess(ServerRequestInterface $request, ModuleInterface $module): void
+    {
+        $backendUserAuthentication = $GLOBALS['BE_USER'];
+        if (!$this->moduleProvider->accessGranted($module->getIdentifier(), $backendUserAuthentication)) {
+            throw new \RuntimeException('You don\'t have access to this module.', 1642450334);
+        }
+
+        $id = $request->getQueryParams()['id'] ?? $request->getParsedBody()['id'] ?? 0;
+        if (MathUtility::canBeInterpretedAsInteger($id) && $id > 0) {
+            $id = (int)$id;
+            $permClause = $backendUserAuthentication->getPagePermsClause(Permission::PAGE_SHOW);
+            // Check page access
+            if (!is_array(BackendUtility::readPageAccess($id, $permClause))) {
+                // Check if page has been deleted
+                $deleteField = $GLOBALS['TCA']['pages']['ctrl']['delete'];
+                $pageInfo = BackendUtility::getRecord('pages', $id, $deleteField, $permClause ? ' AND ' . $permClause : '', false);
+                if (!($pageInfo[$deleteField] ?? false)) {
+                    throw new \RuntimeException('You don\'t have access to this page', 1289917924);
+                }
+            }
+        }
+    }
+}
diff --git a/typo3/sysext/backend/Classes/Module/ExtbaseModule.php b/typo3/sysext/backend/Classes/Module/ExtbaseModule.php
index 4f7349d618bc74f7abec561eead986267b4ef461..6f3c5a46abd618c3965a2f78fc9c3aa885d0b2e4 100644
--- a/typo3/sysext/backend/Classes/Module/ExtbaseModule.php
+++ b/typo3/sysext/backend/Classes/Module/ExtbaseModule.php
@@ -55,7 +55,6 @@ class ExtbaseModule extends BaseModule implements ModuleInterface
     {
         return [
             'module' => $this,
-            'moduleName' => $this->identifier,
             'access' => $this->access,
             'target' => Bootstrap::class . '::handleBackendRequest',
         ];
diff --git a/typo3/sysext/backend/Classes/Module/Module.php b/typo3/sysext/backend/Classes/Module/Module.php
index 718814b271ecc4e16c3c19bcc58c732650b6cb70..0c9c1dab2b2b8155f11312d06e69b46985540573 100644
--- a/typo3/sysext/backend/Classes/Module/Module.php
+++ b/typo3/sysext/backend/Classes/Module/Module.php
@@ -39,7 +39,6 @@ class Module extends BaseModule implements ModuleInterface
         }
         return [
             'module' => $this,
-            'moduleName' => $this->identifier,
             'access' => $this->access,
             'target' => $this->routes['_default']['target'],
         ];
diff --git a/typo3/sysext/backend/Classes/Template/ModuleTemplate.php b/typo3/sysext/backend/Classes/Template/ModuleTemplate.php
index 1a4b6cadacf1a8e3f1b4d2155b6c65de9e6ba9e7..9b0aa49b064e3eb43e132d24f2ef862961412be7 100644
--- a/typo3/sysext/backend/Classes/Template/ModuleTemplate.php
+++ b/typo3/sysext/backend/Classes/Template/ModuleTemplate.php
@@ -21,7 +21,7 @@ use Psr\Http\Message\ResponseFactoryInterface;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use Psr\Http\Message\StreamFactoryInterface;
-use TYPO3\CMS\Backend\Routing\Route;
+use TYPO3\CMS\Backend\Module\ModuleInterface;
 use TYPO3\CMS\Backend\Template\Components\DocHeaderComponent;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
@@ -76,13 +76,11 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface
         protected readonly StreamFactoryInterface $streamFactory,
         protected readonly ServerRequestInterface $request,
     ) {
-        $currentRoute = $request->getAttribute('route');
-        if ($currentRoute instanceof Route) {
-            if ($currentRoute->hasOption('module')) {
-                $this->setModuleName($currentRoute->getOption('module')?->getIdentifier() ?? '');
-            } else {
-                $this->setModuleName($currentRoute->getOption('_identifier'));
-            }
+        $module = $request->getAttribute('module');
+        if ($module instanceof ModuleInterface) {
+            $this->setModuleName($module->getIdentifier());
+        } else {
+            $this->setModuleName($request->getAttribute('route')?->getOption('_identifier') ?? '');
         }
         $this->flashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
         $this->docHeaderComponent = GeneralUtility::makeInstance(DocHeaderComponent::class);
diff --git a/typo3/sysext/backend/Configuration/RequestMiddlewares.php b/typo3/sysext/backend/Configuration/RequestMiddlewares.php
index cc5506d1c060fa0dc2e1796056d2233e3fa6d60b..4e11b55e9b3b4f1bb6f9d5351d21efd0645a533e 100644
--- a/typo3/sysext/backend/Configuration/RequestMiddlewares.php
+++ b/typo3/sysext/backend/Configuration/RequestMiddlewares.php
@@ -47,10 +47,16 @@ return [
                 'typo3/cms-backend/backend-routing',
             ],
         ],
+        'typo3/cms-backend/backend-module-validator' => [
+            'target' => \TYPO3\CMS\Backend\Middleware\BackendModuleValidator::class,
+            'after' => [
+                'typo3/cms-backend/authentication',
+            ],
+        ],
         'typo3/cms-backend/site-resolver' => [
             'target' => \TYPO3\CMS\Backend\Middleware\SiteResolver::class,
             'after' => [
-                'typo3/cms-backend/backend-routing',
+                'typo3/cms-backend/backend-module-validator',
             ],
         ],
         /** internal: do not use or reference this middleware in your own code */
diff --git a/typo3/sysext/backend/Tests/Functional/Middleware/BackendModuleValidatorTest.php b/typo3/sysext/backend/Tests/Functional/Middleware/BackendModuleValidatorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..619a77a8281a1fccd7b031e70972b8133e7b5294
--- /dev/null
+++ b/typo3/sysext/backend/Tests/Functional/Middleware/BackendModuleValidatorTest.php
@@ -0,0 +1,161 @@
+<?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\Backend\Tests\Functional\Middleware;
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use TYPO3\CMS\Backend\Middleware\BackendModuleValidator;
+use TYPO3\CMS\Backend\Module\ModuleFactory;
+use TYPO3\CMS\Backend\Module\ModuleProvider;
+use TYPO3\CMS\Backend\Routing\Route;
+use TYPO3\CMS\Backend\Routing\UriBuilder;
+use TYPO3\CMS\Core\Core\Bootstrap;
+use TYPO3\CMS\Core\Http\Response;
+use TYPO3\CMS\Core\Http\ServerRequest;
+use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
+
+class BackendModuleValidatorTest extends FunctionalTestCase
+{
+    protected BackendModuleValidator $subject;
+    protected ServerRequestInterface $request;
+    protected RequestHandlerInterface $requestHandler;
+
+    protected function setUp(): void
+    {
+        parent::setUp();
+
+        $this->setUpBackendUserFromFixture(1);
+        Bootstrap::initializeLanguageObject();
+
+        $this->subject = new BackendModuleValidator(
+            $this->getContainer()->get(UriBuilder::class),
+            $this->getContainer()->get(ModuleProvider::class),
+        );
+        $this->request = new ServerRequest('/some/uri');
+        $this->requestHandler = new class() implements RequestHandlerInterface {
+            public function handle(ServerRequestInterface $request): ResponseInterface
+            {
+                // In case the module is valid, it is added to the request.
+                // To test this, we add the possible module identifier as header to the response.
+                return (new Response())->withHeader('moduleIdentifier', $request->getAttribute('module')?->getIdentifier() ?? '');
+            }
+        };
+    }
+
+    /**
+     * @test
+     */
+    public function moduleIsAddedToRequest(): void
+    {
+        $module = $this->getContainer()->get(ModuleFactory::class)->createModule(
+            'web_layout',
+            ['path' => '/module/web/layout']
+        );
+
+        $response = $this->subject->process(
+            $this->request->withAttribute('route', new Route('/some/route', ['module' => $module])),
+            $this->requestHandler
+        );
+
+        self::assertEquals('web_layout', $response->getHeaderLine('moduleIdentifier'));
+    }
+
+    /**
+     * @test
+     */
+    public function invalidModuleThrowsException(): void
+    {
+        $module = $this->getContainer()->get(ModuleFactory::class)->createModule(
+            'some_module',
+            ['path' => '/some/module']
+        );
+
+        $this->expectException(\RuntimeException::class);
+        $this->expectExceptionCode(1642450334);
+
+        $this->subject->process(
+            $this->request->withAttribute('route', new Route('/some/route', ['module' => $module])),
+            $this->requestHandler
+        );
+    }
+
+    /**
+     * @test
+     */
+    public function insufficientAccessPermissionsThrowsException(): void
+    {
+        $GLOBALS['BE_USER']->user['admin'] = 0;
+
+        // site_configuration requires admin access
+        $module = $this->getContainer()->get(ModuleFactory::class)->createModule(
+            'site_configuration',
+            ['path' => '/module/site/configuration']
+        );
+
+        $this->expectException(\RuntimeException::class);
+        $this->expectExceptionCode(1642450334);
+
+        $this->subject->process(
+            $this->request->withAttribute('route', new Route('/some/route', ['module' => $module])),
+            $this->requestHandler
+        );
+    }
+
+    /**
+     * @test
+     */
+    public function noPageAccessThrowsException(): void
+    {
+        $module = $this->getContainer()->get(ModuleFactory::class)->createModule(
+            'web_layout',
+            ['path' => '/module/web/layout']
+        );
+
+        $this->expectException(\RuntimeException::class);
+        $this->expectExceptionCode(1289917924);
+
+        $this->subject->process(
+            $this->request
+                ->withQueryParams(['id' => 123])
+                ->withAttribute('route', new Route('/some/route', ['module' => $module])),
+            $this->requestHandler
+        );
+    }
+
+    /**
+     * @test
+     */
+    public function redirectsToMainForSecFetchDestHeader(): void
+    {
+        $module = $this->getContainer()->get(ModuleFactory::class)->createModule(
+            'web_layout',
+            ['path' => '/module/web/layout']
+        );
+
+        $response = $this->subject->process(
+            $this->request
+                ->withHeader('Sec-Fetch-Dest', 'document')
+                ->withAttribute('route', new Route('/some/route', ['_identifier' => 'web_layout', 'module' => $module])),
+            $this->requestHandler
+        );
+
+        self::assertEquals(302, $response->getStatusCode());
+        self::assertMatchesRegularExpression('/^\/typo3\/main.*redirect=web_layout$/', $response->getHeaderLine('location'));
+    }
+}
diff --git a/typo3/sysext/backend/Tests/Unit/Http/RouteDispatcherTest.php b/typo3/sysext/backend/Tests/Unit/Http/RouteDispatcherTest.php
index 3e318348aa062c55a7d763ac9a0e7a4775b218aa..f1cac1b945eb5e702189cb977cd5725ff586727d 100644
--- a/typo3/sysext/backend/Tests/Unit/Http/RouteDispatcherTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Http/RouteDispatcherTest.php
@@ -22,9 +22,7 @@ use Prophecy\PhpUnit\ProphecyTrait;
 use Psr\Container\ContainerInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Backend\Http\RouteDispatcher;
-use TYPO3\CMS\Backend\Module\ModuleProvider;
 use TYPO3\CMS\Backend\Routing\Route;
-use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Backend\Tests\Unit\Http\Fixtures\RouteDispatcherClassFixture;
 use TYPO3\CMS\Backend\Tests\Unit\Http\Fixtures\RouteDispatcherClassInvokeFixture;
 use TYPO3\CMS\Backend\Tests\Unit\Http\Fixtures\RouteDispatcherClassWithoutInvokeFixture;
@@ -62,13 +60,11 @@ class RouteDispatcherTest extends UnitTestCase
         $requestProphecy->getAttribute('route')->willReturn($route);
         $containerProphecy = $this->prophesize(ContainerInterface::class);
         $containerProphecy->has(Argument::any())->willReturn(false);
-        $uriBuilderProphecy = $this->prophesize(UriBuilder::class);
-        $moduleProviderProphecy = $this->prophesize(ModuleProvider::class);
 
         $this->expectException(\InvalidArgumentException::class);
         $this->expectExceptionCode(1425381442);
 
-        $subject = new RouteDispatcher($containerProphecy->reveal(), $uriBuilderProphecy->reveal(), $moduleProviderProphecy->reveal());
+        $subject = new RouteDispatcher($containerProphecy->reveal());
         $subject->dispatch($requestProphecy->reveal());
     }
 
@@ -89,13 +85,11 @@ class RouteDispatcherTest extends UnitTestCase
         $requestProphecy->getAttribute('route')->willReturn($route);
         $containerProphecy = $this->prophesize(ContainerInterface::class);
         $containerProphecy->has(Argument::any())->willReturn(false);
-        $uriBuilderProphecy = $this->prophesize(UriBuilder::class);
-        $moduleProviderProphecy = $this->prophesize(ModuleProvider::class);
 
         $this->expectException(\RuntimeException::class);
         $this->expectExceptionCode(1520756142);
 
-        $subject = new RouteDispatcher($containerProphecy->reveal(), $uriBuilderProphecy->reveal(), $moduleProviderProphecy->reveal());
+        $subject = new RouteDispatcher($containerProphecy->reveal());
         $subject->dispatch($requestProphecy->reveal());
     }
 
@@ -116,13 +110,11 @@ class RouteDispatcherTest extends UnitTestCase
         $requestProphecy->getAttribute('route')->willReturn($route);
         $containerProphecy = $this->prophesize(ContainerInterface::class);
         $containerProphecy->has(Argument::any())->willReturn(false);
-        $uriBuilderProphecy = $this->prophesize(UriBuilder::class);
-        $moduleProviderProphecy = $this->prophesize(ModuleProvider::class);
 
         $this->expectException(\RuntimeException::class);
         $this->expectExceptionCode(1520756466);
 
-        $subject = new RouteDispatcher($containerProphecy->reveal(), $uriBuilderProphecy->reveal(), $moduleProviderProphecy->reveal());
+        $subject = new RouteDispatcher($containerProphecy->reveal());
         $subject->dispatch($requestProphecy->reveal());
     }
 
@@ -141,13 +133,11 @@ class RouteDispatcherTest extends UnitTestCase
         $requestProphecy->getAttribute('route')->willReturn($route);
         $containerProphecy = $this->prophesize(ContainerInterface::class);
         $containerProphecy->has(Argument::any())->willReturn(false);
-        $uriBuilderProphecy = $this->prophesize(UriBuilder::class);
-        $moduleProviderProphecy = $this->prophesize(ModuleProvider::class);
 
         $this->expectException(\RuntimeException::class);
         $this->expectExceptionCode(1520756623);
 
-        $subject = new RouteDispatcher($containerProphecy->reveal(), $uriBuilderProphecy->reveal(), $moduleProviderProphecy->reveal());
+        $subject = new RouteDispatcher($containerProphecy->reveal());
         $subject->dispatch($requestProphecy->reveal());
     }
 
@@ -167,13 +157,11 @@ class RouteDispatcherTest extends UnitTestCase
         $containerProphecy = $this->prophesize(ContainerInterface::class);
         $containerProphecy->has($target)->willReturn(true);
         $containerProphecy->get($target)->willReturn(new RouteDispatcherClassInvokeFixture());
-        $uriBuilderProphecy = $this->prophesize(UriBuilder::class);
-        $moduleProviderProphecy = $this->prophesize(ModuleProvider::class);
 
         $this->expectException(\RuntimeException::class);
         $this->expectExceptionCode(1520756623);
 
-        $subject = new RouteDispatcher($containerProphecy->reveal(), $uriBuilderProphecy->reveal(), $moduleProviderProphecy->reveal());
+        $subject = new RouteDispatcher($containerProphecy->reveal());
         $subject->dispatch($requestProphecy->reveal());
     }
 
@@ -193,13 +181,11 @@ class RouteDispatcherTest extends UnitTestCase
         $route = new Route('not important', ['access' => 'public', 'target' => $target]);
         $requestProphecy = $this->prophesize(ServerRequestInterface::class);
         $requestProphecy->getAttribute('route')->willReturn($route);
-        $uriBuilderProphecy = $this->prophesize(UriBuilder::class);
-        $moduleProviderProphecy = $this->prophesize(ModuleProvider::class);
 
         $this->expectException(\InvalidArgumentException::class);
         $this->expectExceptionCode(1442431631);
 
-        $subject = new RouteDispatcher($containerProphecy->reveal(), $uriBuilderProphecy->reveal(), $moduleProviderProphecy->reveal());
+        $subject = new RouteDispatcher($containerProphecy->reveal());
         $subject->dispatch($requestProphecy->reveal());
     }
 
@@ -218,13 +204,11 @@ class RouteDispatcherTest extends UnitTestCase
         $requestProphecy->getAttribute('route')->willReturn($route);
         $containerProphecy = $this->prophesize(ContainerInterface::class);
         $containerProphecy->has(Argument::any())->willReturn(false);
-        $uriBuilderProphecy = $this->prophesize(UriBuilder::class);
-        $moduleProviderProphecy = $this->prophesize(ModuleProvider::class);
 
         $this->expectException(\RuntimeException::class);
         $this->expectExceptionCode(1520756142);
 
-        $subject = new RouteDispatcher($containerProphecy->reveal(), $uriBuilderProphecy->reveal(), $moduleProviderProphecy->reveal());
+        $subject = new RouteDispatcher($containerProphecy->reveal());
         $subject->dispatch($requestProphecy->reveal());
     }
 
@@ -243,13 +227,11 @@ class RouteDispatcherTest extends UnitTestCase
         $requestProphecy->getAttribute('route')->willReturn($route);
         $containerProphecy = $this->prophesize(ContainerInterface::class);
         $containerProphecy->has(Argument::any())->willReturn(false);
-        $uriBuilderProphecy = $this->prophesize(UriBuilder::class);
-        $moduleProviderProphecy = $this->prophesize(ModuleProvider::class);
 
         $this->expectException(\RuntimeException::class);
         $this->expectExceptionCode(1520757000);
 
-        $subject = new RouteDispatcher($containerProphecy->reveal(), $uriBuilderProphecy->reveal(), $moduleProviderProphecy->reveal());
+        $subject = new RouteDispatcher($containerProphecy->reveal());
         $subject->dispatch($requestProphecy->reveal());
     }
 }
diff --git a/typo3/sysext/belog/Classes/Module/BackendLogModuleBootstrap.php b/typo3/sysext/belog/Classes/Module/BackendLogModuleBootstrap.php
index 5ea78651b84e2b07dd42d316d0d447a9a47685f4..a8ff3184f7f86223756eb70a16d8cf45018ff010 100644
--- a/typo3/sysext/belog/Classes/Module/BackendLogModuleBootstrap.php
+++ b/typo3/sysext/belog/Classes/Module/BackendLogModuleBootstrap.php
@@ -18,7 +18,6 @@ namespace TYPO3\CMS\Belog\Module;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Backend\Module\ModuleProvider;
-use TYPO3\CMS\Backend\Routing\Route;
 use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Extbase\Core\Bootstrap as ExtbaseBootstrap;
 
@@ -48,16 +47,11 @@ class BackendLogModuleBootstrap
         $queryParams = $request->getQueryParams();
         $queryParams['tx_belog_system_beloglog']['pageId'] = $request->getQueryParams()['id'] ?? $request->getParsedBody()['id'] ?? 0;
         $queryParams['tx_belog_system_beloglog']['layout'] = 'Plain';
-        $request = $request->withQueryParams($queryParams);
-
-        $routePath = $this->uriBuilder->buildUriFromRoute('system_BelogLog')->getPath();
-        $routeOptions = $this->moduleProvider->getModule('system_BelogLog')?->getDefaultRouteOptions() ?? [];
 
         return $this->extbaseBootstrap->handleBackendRequest(
-            $request->withAttribute(
-                'route',
-                new Route($routePath, $routeOptions)
-            )
+            $request
+                ->withQueryParams($queryParams)
+                ->withAttribute('module', $this->moduleProvider->getModule('system_BelogLog'))
         );
     }
 }
diff --git a/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php b/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
index d7e02aedd8666f1973c74762c85887ccd27794c9..8c62165e24fb39146c16922a5260335e57ceba5a 100644
--- a/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
+++ b/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
@@ -983,10 +983,10 @@ abstract class AbstractUserAuthentication implements LoggerAwareInterface
 
     /**
      * Stores data for a module.
-     * The data is stored with the session id so you can even check upon retrieval
+     * The data is stored with the session ID, so you can even check upon retrieval
      * if the module data is from a previous session or from the current session.
      *
-     * @param string $module Is the name of the module ($MCONF['name'])
+     * @param string $module Is the identifier of the module, e.g. "web_info"
      * @param mixed $data Is the data you want to store for that module (array, string, ...)
      * @param bool|int $noSave If $noSave is set, then the ->uc array (which carries all kinds of user data) is NOT written immediately, but must be written by some subsequent call.
      */
@@ -1006,7 +1006,7 @@ abstract class AbstractUserAuthentication implements LoggerAwareInterface
     /**
      * Gets module data for a module (from a loaded ->uc array)
      *
-     * @param string $module Is the name of the module ($MCONF['name'])
+     * @param string $module Is the identifier of the module, e.g. "web_info"
      * @param string $type If $type = 'ses' then module data is returned only if it was stored in the current session, otherwise data from a previous session will be returned (if available).
      * @return mixed The module data if available: $this->uc['moduleData'][$module];
      */
diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-96733-RemovedSupportForModuleHandlingBasedOnTBE_MODULES.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-96733-RemovedSupportForModuleHandlingBasedOnTBE_MODULES.rst
index ffb33483433f8842977b61d6ca31224b893d2a47..40520dfcf701546a5900be35c1b259635164ac72 100644
--- a/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-96733-RemovedSupportForModuleHandlingBasedOnTBE_MODULES.rst
+++ b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-96733-RemovedSupportForModuleHandlingBasedOnTBE_MODULES.rst
@@ -89,8 +89,19 @@ Migrate to the new Module Registration API, and use the :php:`ModuleProvider`
 class to get allowed modules and work with the objects. The current module
 information (an implementation of :php:`ModuleInterface`) is stored in a
 TYPO3 Backend request within the `module` option of a TYPO3 Backend route,
-which can be accessed via
-:php:`$request->getAttribute('route')->getOption('module')`.
+which can be accessed via :php:`$request->getAttribute('route')->getOption('module')`.
+
+As soon as the new TYPO3 :php:`BackendModuleValidator` PSR-15 middleware
+has validated the module for the current user, the :php:`ModuleInterface`
+object is also added to the current request and can then be accessed
+via :php:`$request->getAttribute('module')` in custom middlewares or
+components.
+
+.. note::
+
+    With the new module registration, the module identifier is also used
+    as the route identifier. Therefore, the `moduleName` option is removed
+    form the TYPO3 backend route object.
 
 The registration has to be moved from :file:`ext_tables.php` to the
 :file:`Configuration/Backend/Modules.php` file. See the
diff --git a/typo3/sysext/extbase/Classes/Core/Bootstrap.php b/typo3/sysext/extbase/Classes/Core/Bootstrap.php
index 032d2d170da138a9b67830d18b2c7398c41c6ad0..ff75861f8f692b4d5868b1de614ceba160067de7 100644
--- a/typo3/sysext/extbase/Classes/Core/Bootstrap.php
+++ b/typo3/sysext/extbase/Classes/Core/Bootstrap.php
@@ -20,7 +20,6 @@ namespace TYPO3\CMS\Extbase\Core;
 use Psr\Container\ContainerInterface;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
-use TYPO3\CMS\Backend\Routing\Route;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
 use TYPO3\CMS\Extbase\Mvc\Dispatcher;
@@ -216,12 +215,11 @@ class Bootstrap
      */
     public function handleBackendRequest(ServerRequestInterface $request): ResponseInterface
     {
-        // build the configuration from the Server request / route
-        /** @var Route $route */
-        $route = $request->getAttribute('route');
+        // build the configuration from the module, included in the current request
+        $module = $request->getAttribute('module');
         $configuration = [
-            'extensionName' => $route->getOption('module')?->getExtensionName(),
-            'pluginName' => $route->getOption('module')?->getIdentifier(),
+            'extensionName' => $module?->getExtensionName(),
+            'pluginName' => $module?->getIdentifier(),
         ];
 
         $this->initialize($configuration);
diff --git a/typo3/sysext/extbase/Classes/Mvc/Web/RequestBuilder.php b/typo3/sysext/extbase/Classes/Mvc/Web/RequestBuilder.php
index c1df23a587d27f943a4fc6dceb65044038a3c6f7..1dd321433b7ddef1da758489a5bc926352c3815d 100644
--- a/typo3/sysext/extbase/Classes/Mvc/Web/RequestBuilder.php
+++ b/typo3/sysext/extbase/Classes/Mvc/Web/RequestBuilder.php
@@ -162,7 +162,7 @@ class RequestBuilder implements SingletonInterface
     {
         $configuration = [];
         // Load values from the route object, this is used for TYPO3 Backend Modules
-        $module = $mainRequest->getAttribute('route')?->getOption('module');
+        $module = $mainRequest->getAttribute('module');
         if ($module instanceof ExtbaseModule) {
             $configuration = [
                 'controllerConfiguration' => $module->getControllerActions(),
diff --git a/typo3/sysext/extbase/Tests/Functional/Mvc/Web/RequestBuilderTest.php b/typo3/sysext/extbase/Tests/Functional/Mvc/Web/RequestBuilderTest.php
index 2d9e8fee1050c10d2882bde4d9f7432f2b2b0987..eb8da4e50c9fa9039d413b7c4f767c4fc11bc49e 100644
--- a/typo3/sysext/extbase/Tests/Functional/Mvc/Web/RequestBuilderTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Mvc/Web/RequestBuilderTest.php
@@ -20,7 +20,6 @@ namespace TYPO3\CMS\Extbase\Tests\Functional\Mvc\Web;
 use ExtbaseTeam\BlogExample\Controller\BlogController;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Backend\Module\ExtbaseModule;
-use TYPO3\CMS\Backend\Routing\Route;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Error\Http\PageNotFoundException;
 use TYPO3\CMS\Core\Http\NormalizedParams;
@@ -60,7 +59,7 @@ class RequestBuilderTest extends FunctionalTestCase
         $configurationManager->setConfiguration($configuration);
 
         $mainRequest = $this->prepareServerRequest('https://example.com/');
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $request = $requestBuilder->build($mainRequest);
 
@@ -93,7 +92,7 @@ class RequestBuilderTest extends FunctionalTestCase
         $configurationManager->setConfiguration($configuration);
 
         $mainRequest = $this->prepareServerRequest('https://example.com/');
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $request = $requestBuilder->build($mainRequest);
 
@@ -126,7 +125,7 @@ class RequestBuilderTest extends FunctionalTestCase
 
         $mainRequest = $this->prepareServerRequest('https://example.com/');
         $mainRequest = $mainRequest->withQueryParams(['tx_blog_example_blog' => ['format' => 'json']]);
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $request = $requestBuilder->build($mainRequest);
 
@@ -197,7 +196,7 @@ class RequestBuilderTest extends FunctionalTestCase
         $configurationManager->setConfiguration($configuration);
 
         $mainRequest = $this->prepareServerRequest('https://example.com/', 'POST');
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $request = $requestBuilder->build($mainRequest);
 
@@ -255,7 +254,7 @@ class RequestBuilderTest extends FunctionalTestCase
         $configurationManager->setConfiguration($configuration);
 
         $mainRequest = $this->prepareServerRequest('https://example.com/', 'POST');
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $request = $requestBuilder->build($mainRequest);
 
@@ -308,7 +307,7 @@ class RequestBuilderTest extends FunctionalTestCase
         $configurationManager->setConfiguration($configuration);
 
         $mainRequest = $this->prepareServerRequest('https://example.com/');
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $mainRequest = $mainRequest->withQueryParams(['tx_blog_example_blog' => ['controller' => 'NonExistentController']]);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $requestBuilder->build($mainRequest);
@@ -344,7 +343,7 @@ class RequestBuilderTest extends FunctionalTestCase
 
         $mainRequest = $this->prepareServerRequest('https://example.com/');
         $mainRequest = $mainRequest->withQueryParams(['tx_blog_example_blog' => ['controller' => 'NonExistentController']]);
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $requestBuilder->build($mainRequest);
     }
@@ -398,7 +397,7 @@ class RequestBuilderTest extends FunctionalTestCase
         $configurationManager->setConfiguration($configuration);
 
         $mainRequest = $this->prepareServerRequest('https://example.com/');
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $mainRequest = $mainRequest->withQueryParams(['tx_blog_example_blog' => ['controller' => 'NonExistentController']]);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $request = $requestBuilder->build($mainRequest);
@@ -432,8 +431,8 @@ class RequestBuilderTest extends FunctionalTestCase
         $configurationManager->setConfiguration($configuration);
 
         $mainRequest = $this->prepareServerRequest('https://example.com/');
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $mainRequest = $mainRequest->withQueryParams(['tx_blog_example_blog' => ['controller' => 'User']]);
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $request = $requestBuilder->build($mainRequest);
 
@@ -469,7 +468,7 @@ class RequestBuilderTest extends FunctionalTestCase
         $configurationManager->setConfiguration($configuration);
 
         $mainRequest = $this->prepareServerRequest('https://example.com/');
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $mainRequest = $mainRequest->withQueryParams(['tx_blog_example_blog' => ['action' => 'NonExistentAction']]);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $requestBuilder->build($mainRequest);
@@ -504,7 +503,7 @@ class RequestBuilderTest extends FunctionalTestCase
         $configurationManager->setConfiguration($configuration);
 
         $mainRequest = $this->prepareServerRequest('https://example.com/');
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $mainRequest = $mainRequest->withQueryParams(['tx_blog_example_blog' => ['action' => 'NonExistentAction']]);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $requestBuilder->build($mainRequest);
@@ -535,7 +534,7 @@ class RequestBuilderTest extends FunctionalTestCase
         $configurationManager->setConfiguration($configuration);
 
         $mainRequest = $this->prepareServerRequest('https://example.com/');
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $mainRequest = $mainRequest->withQueryParams(['tx_blog_example_blog' => ['action' => 'NonExistentAction']]);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $request = $requestBuilder->build($mainRequest);
@@ -568,7 +567,7 @@ class RequestBuilderTest extends FunctionalTestCase
         $configurationManager->setConfiguration($configuration);
 
         $mainRequest = $this->prepareServerRequest('https://example.com/');
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $mainRequest = $mainRequest->withQueryParams(['tx_blog_example_blog' => ['action' => 'show']]);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $request = $requestBuilder->build($mainRequest);
@@ -605,7 +604,7 @@ class RequestBuilderTest extends FunctionalTestCase
         $configurationManager->setConfiguration($configuration);
 
         $mainRequest = $this->prepareServerRequest('https://example.com/');
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
         $requestBuilder = $this->getContainer()->get(RequestBuilder::class);
         $requestBuilder->build($mainRequest);
     }
@@ -630,7 +629,7 @@ class RequestBuilderTest extends FunctionalTestCase
                 BlogController::class => ['list', 'show'],
             ],
         ]);
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
 
         $configuration = [];
         $configuration['extensionName'] = $extensionName;
@@ -668,7 +667,7 @@ class RequestBuilderTest extends FunctionalTestCase
                 BlogController::class => ['list', 'show'],
             ],
         ]);
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
 
         $configuration = [];
         $configuration['extensionName'] = $extensionName;
@@ -704,7 +703,7 @@ class RequestBuilderTest extends FunctionalTestCase
                 BlogController::class => ['list', 'show'],
             ],
         ]);
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
 
         $configuration = [];
         $configuration['extensionName'] = $extensionName;
@@ -743,7 +742,7 @@ class RequestBuilderTest extends FunctionalTestCase
                 BlogController::class => ['list', 'show'],
             ],
         ]);
-        $mainRequest = $mainRequest->withAttribute('route', new Route($module->getPath(), ['module' => $module]));
+        $mainRequest = $mainRequest->withAttribute('module', $module);
 
         $configuration = [];
         $configuration['extensionName'] = $extensionName;
diff --git a/typo3/sysext/install/Classes/Updates/ShortcutRecordsMigration.php b/typo3/sysext/install/Classes/Updates/ShortcutRecordsMigration.php
index 9a878ed919f45e99d40c3c75014e185c5db0fbf3..2997c4325b2c0f48a83c1fba41f59dad4fb487ef 100644
--- a/typo3/sysext/install/Classes/Updates/ShortcutRecordsMigration.php
+++ b/typo3/sysext/install/Classes/Updates/ShortcutRecordsMigration.php
@@ -166,15 +166,7 @@ class ShortcutRecordsMigration implements UpgradeWizardInterface
         }
 
         if ($this->moduleProvider->isModuleRegistered($moduleName)) {
-            return $this->moduleProvider->getModule($moduleName)->getIdentifier();
-        }
-
-        // If the defined route identifier can't be fetched, try from the other side
-        // by iterating over the routes to match a route by the defined module name
-        foreach ($this->routes as $identifier => $route) {
-            if ($route->hasOption('moduleName') && $route->getOption('moduleName') === $moduleName) {
-                return $identifier;
-            }
+            return $moduleName;
         }
 
         return '';
diff --git a/typo3/sysext/sys_note/Classes/Hook/ButtonBarHook.php b/typo3/sysext/sys_note/Classes/Hook/ButtonBarHook.php
index ef63f67d6f905b609d65311fce7dc91337ae57a8..db2bbd62f82debc40e8eee3eef4023761be366d5 100644
--- a/typo3/sysext/sys_note/Classes/Hook/ButtonBarHook.php
+++ b/typo3/sysext/sys_note/Classes/Hook/ButtonBarHook.php
@@ -54,17 +54,17 @@ class ButtonBarHook
         $request = $this->getRequest();
 
         $id = (int)($request->getParsedBody()['id'] ?? $request->getQueryParams()['id'] ?? 0);
-        $route = $request->getAttribute('route');
+        $module = $request->getAttribute('module');
         $normalizedParams = $request->getAttribute('normalizedParams');
         $pageTSconfig = BackendUtility::getPagesTSconfig($id);
 
         if (!$id
-            || $route === null
+            || $module === null
             || $normalizedParams === null
             || !empty($pageTSconfig['mod.']['SHARED.']['disableSysNoteButton'])
             || !$this->canCreateNewRecord($id)
-            || !in_array($route->getOption('moduleName'), self::ALLOWED_MODULES, true)
-            || ($route->getOption('moduleName') === 'web_list' && !$this->isCreationAllowed($pageTSconfig['mod.']['web_list.'] ?? []))
+            || !in_array($module->getIdentifier(), self::ALLOWED_MODULES, true)
+            || ($module->getIdentifier() === 'web_list' && !$this->isCreationAllowed($pageTSconfig['mod.']['web_list.'] ?? []))
         ) {
             return $buttons;
         }