From 511778a7a8050bda4eee673d977294d1e0a01be5 Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Fri, 22 Jul 2022 14:29:26 +0900
Subject: [PATCH] Issue #2852361 by Xano, smustgrave, pwolanin, mpdonadio,
 wolffereast, ranjith_kumar_k_u, John Cook, xjm, alexpott: Ignore repeated
 slashes in the incoming path like Drupal <= 7

---
 .../RedirectLeadingSlashesSubscriber.php            |  8 ++++----
 .../tests/src/Functional/Routing/RouterTest.php     | 13 +++++++------
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/core/lib/Drupal/Core/EventSubscriber/RedirectLeadingSlashesSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/RedirectLeadingSlashesSubscriber.php
index dce347bcf7bd..75fd237f77a8 100644
--- a/core/lib/Drupal/Core/EventSubscriber/RedirectLeadingSlashesSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/RedirectLeadingSlashesSubscriber.php
@@ -8,12 +8,12 @@
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
 /**
- * Redirects paths starting with multiple slashes to a single slash.
+ * Redirects paths containing successive slashes to those with single slashes.
  */
 class RedirectLeadingSlashesSubscriber implements EventSubscriberInterface {
 
   /**
-   * Redirects paths starting with multiple slashes to a single slash.
+   * Redirects paths containing successive slashes to those with single slashes.
    *
    * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
    *   The RequestEvent to process.
@@ -28,8 +28,8 @@ public function redirect(RequestEvent $event) {
     // submits back to the same URI this presents an open redirect
     // vulnerability. Also, Drupal 7 renders the same page for
     // http://www.example.org/foo and http://www.example.org////foo.
-    if (strpos($path, '//') === 0) {
-      $path = '/' . ltrim($path, '/');
+    if (strpos($path, '//') !== FALSE) {
+      $path = preg_replace('/\/+/', '/', $path);
       $qs = $request->getQueryString();
       if ($qs) {
         $qs = '?' . $qs;
diff --git a/core/modules/system/tests/src/Functional/Routing/RouterTest.php b/core/modules/system/tests/src/Functional/Routing/RouterTest.php
index 8dc066434415..8a032049a564 100644
--- a/core/modules/system/tests/src/Functional/Routing/RouterTest.php
+++ b/core/modules/system/tests/src/Functional/Routing/RouterTest.php
@@ -319,17 +319,18 @@ public function testRouterUninstallInstall() {
   }
 
   /**
-   * Ensure that multiple leading slashes are redirected.
+   * Ensure that multiple successive slashes are redirected.
    */
-  public function testLeadingSlashes() {
+  public function testSuccessiveSlashes() {
     $request = $this->container->get('request_stack')->getCurrentRequest();
-    $url = $request->getUriForPath('//router_test/test1');
+
+    // Test a simple path with successive leading slashes.
+    $url = $request->getUriForPath('//////router_test/test1');
     $this->drupalGet($url);
     $this->assertSession()->addressEquals($request->getUriForPath('/router_test/test1'));
 
-    // It should not matter how many leading slashes are used and query strings
-    // should be preserved.
-    $url = $request->getUriForPath('/////////////////////////////////////////////////router_test/test1') . '?qs=test';
+    // Test successive slashes in the middle.
+    $url = $request->getUriForPath('/router_test//////test1') . '?qs=test';
     $this->drupalGet($url);
     $this->assertSession()->addressEquals($request->getUriForPath('/router_test/test1') . '?qs=test');
 
-- 
GitLab