Drupal core update + update to symfony/http-foundation causes certain views blocks to cause a "client error" and breaks page display.

Created on 23 November 2024, 25 days ago

Problem/Motivation

As instructed ๐Ÿ› An update to symfony/http-foundation plus a trailing space took down the views UI Active I'm opening this issue after the latest Drupal Code security update broke my site due to its dependency on a newer version of symfony.

After updating Drupal core and clearing caches, the front end fails to load pages of a certain content type and displays "Client error" as the title. The layout builder admin UI also shows "Client error" and is unavailable. The watchdog reports:
Symfony\Component\HttpKernel\Exception\BadRequestHttpException: Invalid URI: A URI must not start nor end with ASCII control characters or spaces. in Symfony\Component\HttpKernel\HttpKernel->handle() (line 83 of /var/www/***/vendor/symfony/http-kernel/HttpKernel.php).

I'm using layout builder on the pages in question to place a number of views blocks. I've been able to narrow the issue down to the included 2 views, I included the simplest one. It seems like the contextual filters are causing the problem.

Hope this helps, thanks in advance for any attention to this.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

๐Ÿ› Bug report
Status

Active

Version

10.3 โœจ

Component

views.module

Created by

๐Ÿ‡น๐Ÿ‡ญThailand AlfTheCat

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @AlfTheCat
  • ๐Ÿ‡น๐Ÿ‡ญThailand AlfTheCat
  • ๐Ÿ‡ณ๐Ÿ‡ฟNew Zealand quietone

    Changes are made on on 11.x (our main development branch) first, and are then back ported as needed according to our policies.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    @alfthecat the most obvious cause of this, looking at your view, would be if the product_id has a trailing space or control character. The view creates links with path: /product/{{ product_id }} and this path will be processed by Drupal\Core\Path\PathValidator, which calls Request::create('/' . $path); , which now throws that exception.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    Adding a remaining tasks item to analyze PathValidator class. On the one hand, it can be safer to throw exceptions for security reasons, as Request::create() now does in its most recent versions. On the other hand, PathValidator is a validator which returns FALSE if the path is not valid - thus it may be expected to catch this new exception and return FALSE.

  • Pipeline finished with Success
    25 days ago
    Total: 1248s
    #348051
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    @alfthecat can you check if MR !10307 resolves your issue? If not, then I guess a full stacktrace of the BadRequestHttpException would be helpful, I was really just guessing/assuming that this was the Request::create() call throwing the exception.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    I looked at how some invalid paths are handled with MR !10307 applied, and it appears they are handled correctly, because the invalid path is actually "repaired" by being URL-encoded. Some examples:

    Drupal\Core\Url::fromUri('internal:/1:1')->toString();
    // "/1%3A1"
    
    Drupal\Core\Url::fromUri('internal:/foo ')->toString();
    // "/foo%20"
    
  • ๐Ÿ‡ฆ๐Ÿ‡นAustria maxilein

    Adding an issue that may be a related symptom.

  • ๐Ÿ‡น๐Ÿ‡ญThailand AlfTheCat

    Hi @mfb, I'm very happy to report the patch fixes the issue on my end. Thank you very much for the rapid solution.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    Ok great. I added a test which passes a new line character to PathValidator - I don't know specifically what caused the exception in your case, but I don't think it matters, we just want to ensure it catches a BadRequestException and returns FALSE.

  • Pipeline finished with Success
    24 days ago
    Total: 859s
    #348501
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia pameeela

    We hit this on:

     [notice] Update started: block_content_post_update_revision_type
     [error]  Invalid URI: A URI must not start nor end with ASCII control characters or spaces. 
     [error]  Update failed: block_content_post_update_revision_type 
     [error]  Update aborted by: block_content_post_update_revision_type 

    Quickly downgraded to get the deploy working (it had worked on dev and stage, so of course we only hit it on prod), but we got dev into a broken state so we could confirm the fix later, and this appears to fix it.

  • First commit to issue fork.
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands casey

    In our monitoring tool we saw a lot of "Allowed memory size of ... bytes exhausted" errors. These errors were caused due to a infinite loop via DefaultExceptionHtmlSubscriber (and maybe in our case only because we are using menu_trail_by_path module).

    The error still occurred after the MR, because the non-ASCII characters in the request path are urlencoded. I've updated the MR to handle both encoded and non-encoded non-ASCII characters.

    The attached patch is a snapshot of the latest state for safe usage with composer patches.

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands casey

    Maybe related

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom catch

    @casey #14 definitely sounds like ๐Ÿ› DefaultExceptionHtmlSubscriber should not clone the request for 401s Active , reviews over there would be great.

    Bumping this issue to critical, also reviewed the MR and it looks good to me, so RTBC.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom catch

    And tagging beta target because this is a new regression.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom longwave UK
    Drupal\Tests\Core\Path\PathValidatorTest::testGetUrlIfValidWithoutAccessCheckWithInvalidPath
    TypeError: MockObject_UrlMatcherInterface_0ba26206::match(): Argument #1 ($pathinfo) must be of type string, null given, called in core/lib/Drupal/Core/Path/PathValidator.php on line 167
    
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    @casey re: the infinite loop + out of memory, I also needed to catch the new Request::create() exceptions in a different place, see https://git.drupalcode.org/project/drupal/-/merge_requests/10306

  • Pipeline finished with Failed
    23 days ago
    Total: 45724s
    #349205
  • Pipeline finished with Success
    23 days ago
    Total: 948s
    #349883
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco
  • ๐Ÿ‡จ๐Ÿ‡ฆCanada Charlie ChX Negyesi ๐ŸCanada

    Another example of the problem https://www.smartsheet.com/customers/stegh as you can see here Learn more online: <a href="https://www.stegh.on.ca/ "> causes no problems at all in a browser but PathValidator blows up because Symfony is garbage.

  • ๐Ÿ‡จ๐Ÿ‡ฆCanada Charlie ChX Negyesi ๐ŸCanada
  • ๐Ÿ‡จ๐Ÿ‡ฆCanada Charlie ChX Negyesi ๐ŸCanada
  • ๐Ÿ‡จ๐Ÿ‡ฆCanada Charlie ChX Negyesi ๐ŸCanada
  • ๐Ÿ‡จ๐Ÿ‡ฆCanada Charlie ChX Negyesi ๐ŸCanada

    Please commit to 10.x too.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    Committed to 11.x and backported to 10.5.x, 10.4.x and 11.1.x

    Removing beta target tag

    Setting as Patch to be ported for 11.0.x and 10.3.x

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    Updated the MR for 11.0.x so we can make sure its green before we cherry-pick to production branches

  • Pipeline finished with Failed
    21 days ago
    Total: 670s
    #351494
  • Pipeline finished with Failed
    21 days ago
    Total: 660s
    #351495
  • ๐Ÿ‡จ๐Ÿ‡ฆCanada Charlie ChX Negyesi ๐ŸCanada
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia pandaski

    Is there anything I can help with for the 10.3 patch?

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    @pandaski review the current MR and mark the issue as RTBC if it looks ok, then we can rebase it for 10.3

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10
    Drupal\Tests\Core\Path\PathValidatorTest::testGetUrlIfValidWithoutAccessCheckWithInvalidPath
    TypeError: MockObject_UrlMatcherInterface_017374f3::match(): Argument #1 ($pathinfo) must be of type string, null given, called in core/lib/Drupal/Core/Path/PathValidator.php on line 167

    Tests fail on 11.0.x, so fixing those would help too @pandaski

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia pandaski

    The patch for 10.3 and 11.0 looks good and resolves the issue locally.

    During local testing, I successfully applied the patch from this merge request to 10.3.x and 11.0.x.

    The patch has resolved the issue in initial local tests.

    The recent PHPUnit test error seems similar to issue #18. Iโ€™m running local tests to validate it.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia pandaski

    My local PHPUnit tests ran successfully.

    PHPUnit 9.6.21 by Sebastian Bergmann and contributors.
    
    Testing Drupal\Tests\Core\Path\PathValidatorTest
    Path Validator (Drupal\Tests\Core\Path\PathValidator)
     โœ” Is valid with frontpage
     โœ” Is valid with none
     โœ” Is valid with external url
     โœ” Is valid with invalid external url
     โœ” Is valid with link to any page account
     โœ” Is valid without link to any page account
     โœ” Is valid with path alias
     โœ” Is valid with access denied
     โœ” Is valid with resource not found
     โœ” Is valid with param not converted
     โœ” Is valid with method not allowed
     โœ” Is valid with failing parameter converting
     โœ” Is valid with not existing path
     โœ” Get url if valid with access
     โœ” Get url if valid with query
     โœ” Get url if valid without access
     โœ” Get url if valid with front page and query and fragments
     โœ” Get url if valid without access check
     โœ” Get url if valid without access check with invalid path
    
    Time: 00:00.017, Memory: 10.00 MB
    
    OK (19 tests, 85 assertions)
    
  • Pipeline finished with Success
    18 days ago
    Total: 864s
    #354909
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    I think what's happening is the test expectations needed to be adjusted because this branch is using an older version of symfony/http-foundation that doesn't actually throw. In other words, this MR wouldn't actually need to be backported to this branch until symfony/http-foundation is updated?

    I changed the test expectations for it to pass old with the older version of symfony/http-foundation, but on the other hand, if this branch is still supported, then actually symfony/http-foundation should be updated instead and we should revert the last commit?

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia praveenpb Bangalore

    One quick question, cant we sanitize the $path variable to remove space instead of handling it with the BadRequestException?

    For example, $path = trim($path); resolves the first issue I guess.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    @praveenpb for a few reasons.. PathValidator is already catching numerous exceptions and returning FALSE, so it clearly makes sense to do so in a new case. There is some fairly complex logic in Request::create() for deciding which strings are not valid URLs, which also includes the even more complex logic for strings that parse_url() considers "seriously malformed URLs," so you wouldn't want to try to recreate this logic. It's best to leave it to Request::create() (and parse_url()) to decide, and catch the exception that it can now throw.

    (It's actually a little bizarre that Request::create() didn't previously throw an exception - I guess you could pass any arbitrary string to it and get a request object.)

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia praveenpb Bangalore

    @mfb Okay, makes sense.

  • Pipeline finished with Canceled
    18 days ago
    Total: 192s
    #354935
  • Pipeline finished with Success
    18 days ago
    Total: 527s
    #354938
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia praveenpb Bangalore

    @mfb One more question, for existing paths which has an extra leading or trailing spaces already, this will return FALSE and consider as an invalid url. What would be the impact? Will it break some feature in existing sites?

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    By the way, I was trying to grok parse_url()'s seemingly arbitrary logic for what returns FALSE, and noticed that the PHP docs say "This function may not give correct results for relative or invalid URLs, and the results may not even match common behavior of HTTP clients. If URLs from untrusted input need to be parsed, extra validation is required, e.g. by using filter_var() with the FILTER_VALIDATE_URL filter."

    So, it might not actually be a good idea for Request::create() to rely on parse_url() for parsing relative URLs, or for Drupal core to rely on Request::create() to parse relative URLs/paths, and some followup might be needed related to this? But so far that seems to be a concern only for weird edge cases (a path with a trailing space or a colon and numbers doesn't seem normal) and could take a while to sort out, so we presumably want this fix either way.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    @praveenpb paths can contain spaces (they get URL-encoded when the path string is rendered to a URL string). But I think trailing spaces would be unlikely because a path seems to be trimmed? If there are some paths that are throwing this exception then they would already be broken - this MR wouldn't make them any more broken.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts

    I ran into this issue on a menu provided by the domain_menus module. The patch from MR 10307 applied to 10.3 and fixes the issue for me.

    Thanks for the work on this! I'd mark it RTBC, but there appears to still be some discussions about the coding.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco
  • Pipeline finished with Success
    11 days ago
    Total: 913s
    #362177
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States samia.wyatt

    Hi all! I am having a similar issue with Views module and symfony/http-foundation. After upgrading to Drupal 10.3.x
    In my case, it is a taxonomy view with an image entity reference field field_image and a content entity reference field field_park_association

    The field_image field is set to rewrite results with with the following configuration:

    • - Output this field as a custom link with link path set to {{ field_park_association }}
    • - The option "Replace spaces with dashes" is checked
    • - The option "Remove whitespace" is checked

    The error this configuration is throwing:
    Symfony\Component\HttpKernel\Exception\BadRequestHttpException: Invalid URI: A URI must not start nor end with ASCII control characters or spaces. in Symfony\Component\HttpKernel\HttpKernel->handle() (line 83 of /code/vendor/symfony/http-kernel/HttpKernel.php).

    Currently, Drupal 10.3.10 site
    PHP version 8.2
    symfony/http-foundation v6.4.16
    views 10.3.10
    views_ui 10.3.10

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    By the way, this merge request added a try/catch BadRequestException for a $router->match() call.

    However, I don't believe the Router::match() method should throw a BadRequestException - according to its upstream phpdoc, it should only throw various routing exceptions.

    I have a merge request resolving this over at ๐Ÿ’ฌ symfony/http-foundation Follow up issue for isAdminPath validator Needs work (theoretically we could remove catch statements that shouldn't be needed, but I didn't get to that yet).

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    Opened new merge request !10509 for the 10.3.x branch so folks can test/review it. This includes updating symfony/http-foundation, rather than modifying the test to pass on the older version. But if necessary, we could instead remove the update and modify the test.

  • Pipeline finished with Success
    8 days ago
    #364725
  • Pipeline finished with Success
    8 days ago
    Total: 708s
    #364723
Production build 0.71.5 2024