Harden against weakness in core's PathBasedBreadcrumbBuilder: User agents modifying the farfuture URL result in repeated PHP notices filling up logs

Created on 14 January 2020, almost 5 years ago
Updated 21 September 2023, over 1 year ago

Hi,
I'm seeing a lot of these errors in the logs in our production site:

Undefined offset: 2 in Drupal\cdn\PathProcessor\CdnFarfuturePathProcessor->processFarFuture() (line 50 of /app/web/modules/contrib/cdn/src/PathProcessor/CdnFarfutureP
athProcessor.php)

Sometimes it's offset 3, for example:

NOTICE: Notice: Undefined offset: 3 in Drupal\cdn\PathProcessor\CdnFarfuturePathProcessor->processFarFuture() (line 50 of /app/web/modules/contrib/cdn/src/PathProcessor/CdnFarfutureP
athProcessor.php)

All examples I have of urls are image styles. For example:

https://example.com/cdn/ff/gYQxCoETBJifqbLiWvx5SSHL1JQlqCFHLGa4Q3ISzqI/1...(5).jpg?itok=b3DMEDON

Here is a trace:

php.NOTICE: Notice: Undefined offset: 3 in Drupal\cdn\PathProcessor\CdnFarfuturePathProcessor->processFarFuture() (line 50 of /app/web/modules/contrib/cdn/src/PathProcessor/CdnFarfutureP
athProcessor.php) #0 /app/web/core/includes/bootstrap.inc(596): _drupal_error_handler_real(8, 'Undefined offse...', '/app/web/module...', 50, Array) #1 /app/web/modules/contrib/cdn/src/PathProcessor/CdnFarfut
urePathProcessor.php(50): _drupal_error_handler(8, 'Undefined offse...', '/app/web/module...', 50, Array) #2 /app/web/modules/contrib/cdn/src/PathProcessor/CdnFarfuturePathProcessor.php(31): Drupal\cdn\PathPr
ocessor\CdnFarfuturePathProcessor->processFarFuture('/cdn/ff/gYQxCoE...', Object(Symfony\Component\HttpFoundation\Request)) #3 /app/web/core/lib/Drupal/Core/PathProcessor/PathProcessorManager.php(70): Drupal\
cdn\PathProcessor\CdnFarfuturePathProcessor->processInbound('/cdn/ff/gYQxCoE...', Object(Symfony\Component\HttpFoundation\Request)) #4 /app/web/core/lib/Drupal/Core/Routing/RouteProvider.php(178): Drupal\Core
\PathProcessor\PathProcessorManager->processInbound('/cdn/ff/gYQxCoE...', Object(Symfony\Component\HttpFoundation\Request)) #5 /app/web/core/lib/Drupal/Core/Routing/Router.php(239): Drupal\Core\Routing\RouteP
rovider->getRouteCollectionForRequest(Object(Symfony\Component\HttpFoundation\Request)) #6 /app/web/core/lib/Drupal/Core/Routing/Router.php(123): Drupal\Core\Routing\Router->getInitialRouteCollection(Object(S
ymfony\Component\HttpFoundation\Request)) #7 /app/web/core/lib/Drupal/Core/Routing/AccessAwareRouter.php(92): Drupal\Core\Routing\Router->matchRequest(Object(Symfony\Component\HttpFoundation\Request)) #8 /app
/web/core/modules/system/src/PathBasedBreadcrumbBuilder.php(225): Drupal\Core\Routing\AccessAwareRouter->matchRequest(Object(Symfony\Component\HttpFoundation\Request)) #9 /app/web/core/modules/system/src/Path
BasedBreadcrumbBuilder.php(169): Drupal\system\PathBasedBreadcrumbBuilder->getRequestForPath('/cdn/ff/gYQxCoE...', Array) #10 /app/web/core/lib/Drupal/Core/Breadcrumb/BreadcrumbManager.php(83): Drupal\system\
PathBasedBreadcrumbBuilder->build(Object(Drupal\Core\Routing\RouteMatch)) #11 /app/web/core/modules/system/src/Plugin/Block/SystemBreadcrumbBlock.php(72): Drupal\Core\Breadcrumb\BreadcrumbManager->build(Objec
t(Drupal\Core\Routing\CurrentRouteMatch)) #12 /app/web/core/modules/block/src/BlockViewBuilder.php(171): Drupal\system\Plugin\Block\SystemBreadcrumbBlock->build() #13 [internal function]: Drupal\block\BlockVi
ewBuilder::preRender(Array) #14 /app/web/core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php(100): call_user_func_array(Array, Array) #15 /app/web/core/lib/Drupal/Core/Render/Renderer.php(781): Drupal\Co
re\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_ren...', 'silenced_deprec...', 'Drupal\\Core\\Ren...') #16 /app/web/core/lib/Drupal/Core/Render/Renderer.php(372): Drupal\Core\Render\Renderer-
>doCallback('#pre_render', Array, Array) #17 /app/web/core/lib/Drupal/Core/Render/Renderer.php(444): Drupal\Core\Render\Renderer->doRender(Array) #18 /app/web/core/lib/Drupal/Core/Render/Renderer.php(200): Dr
upal\Core\Render\Renderer->doRender(Array, false) #19 /app/web/core/lib/Drupal/Core/Template/TwigExtension.php(501): Drupal\Core\Render\Renderer->render(Array) #20 /app/private/twig/5e1d4b5b7d5f4_page.html.tw
ig_n4ddrc3201xOJ3vn2scVZ5kAr/ndNyGbw-LHiya_QZOAPgndDvvYomv7PANwbMRRD9Bz8.php(71): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true) #21
/app/vendor/twig/twig/src/Template.php(455): __TwigTemplate_1f29f48cd6fa05e600b824ef5c7bb5f50edf0923ef1a0229fb96e3494a4eed70->doDisplay(Array, Array) #22 /app/vendor/twig/twig/src/Template.php(422): Twig\Temp
late->displayWithErrorHandling(Array, Array) #23 /app/vendor/twig/twig/src/Template.php(434): Twig\Template->display(Array) #24 /app/web/core/themes/engines/twig/twig.engine(64): Twig\Template->render(Array)
#25 /app/web/core/lib/Drupal/Core/Theme/ThemeManager.php(384): twig_render_template('core/themes/sev...', Array) #26 /app/web/core/lib/Drupal/Core/Render/Renderer.php(431): Drupal\Core\Theme\ThemeManager->ren
der('page', Array) #27 /app/web/core/lib/Drupal/Core/Render/Renderer.php(200): Drupal\Core\Render\Renderer->doRender(Array, false) #28 /app/web/core/lib/Drupal/Core/Template/TwigExtension.php(501): Drupal\Cor
e\Render\Renderer->render(Array) #29 /app/private/twig/5e1d4b5b7d5f4_html.html.twig_Nwc9sWVJjrPGT2LtLFJAtAZRP/8YkGjP6qDsZAPByzGFZsP--zcjhKEQ8y82PRTvMrnmM.php(102): Drupal\Core\Template\TwigExtension->escapeFi
lter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true) #30 /app/vendor/twig/twig/src/Template.php(455): __TwigTemplate_7c4527fb79750059de31d3a819b0ec4747502cd584371c312b3420f74b5ea8f2->
doDisplay(Array, Array) #31 /app/vendor/twig/twig/src/Template.php(422): Twig\Template->displayWithErrorHandling(Array, Array) #32 /app/vendor/twig/twig/src/Template.php(434): Twig\Template->display(Array) #3
3 /app/web/core/themes/engines/twig/twig.engine(64): Twig\Template->render(Array) #34 /app/web/core/lib/Drupal/Core/Theme/ThemeManager.php(384): twig_render_template('core/themes/cla...', Array) #35 /app/web/core/lib/Drupal/Core/Render/Renderer.php(431): Drupal\Core\Theme\ThemeManager->render('html', Array) #36 /app/web/core/lib/Drupal/Core/Render/Renderer.php(200): Drupal\Core\Render\Renderer->doRender(Array, false) #37 /app/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(147): Drupal\Core\Render\Renderer->render(Array) #38 /app/web/core/lib/Drupal/Core/Render/Renderer.php(573): Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() #39 /app/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(148): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #40 /app/web/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php(90): Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch)) #41 [internal function]: Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #42 /app/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #43 /app/vendor/symfony/http-kernel/HttpKernel.php(156): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent)) #44 /app/vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 2) #45 /app/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 2, true) #46 /app/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 2, true) #47 /app/web/modules/custom/connect_graphql/src/StackMiddleware/CacheControl.php(58): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 2, true) #48 /app/web/modules/contrib/cdn/src/StackMiddleware/DuplicateContentPreventionMiddleware.php(128): Drupal\connect_graphql\StackMiddleware\CacheControl->handle(Object(Symfony\Component\HttpFoundation\Request), 2, true) #49 /app/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php(49): Drupal\cdn\StackMiddleware\DuplicateContentPreventionMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 2, true) #50 /app/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Asm89\Stack\Cors->handle(Object(Symfony\Component\HttpFoundation\Request), 2, true) #51 /app/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 2, true) #52 /app/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 2, true) #53 /app/web/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php(166): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 2) #54 /app/web/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php(112): Drupal\Core\EventSubscriber\DefaultExceptionHtmlSubscriber->makeSubrequest(Object(Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent), '/system/403', 403) #55 /app/web/core/lib/Drupal/Core/EventSubscriber/HttpExceptionSubscriberBase.php(109): Drupal\Core\EventSubscriber\DefaultExceptionHtmlSubscriber->on403(Object(Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent)) #56 [internal function]: Drupal\Core\EventSubscriber\HttpExceptionSubscriberBase->onException(Object(Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent), 'kernel.exceptio...', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #57 /app/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent), 'kernel.exceptio...', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #58 /app/vendor/symfony/http-kernel/HttpKernel.php(227): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.exceptio...', Object(Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent)) #59 /app/vendor/symfony/http-kernel/HttpKernel.php(79): Symfony\Component\HttpKernel\HttpKernel->handleException(Object(Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException), Object(Symfony\Component\HttpFoundation\Request), 1) #60 /app/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #61 /app/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #62 /app/web/modules/custom/connect_graphql/src/StackMiddleware/CacheControl.php(58): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #63 /app/web/modules/contrib/cdn/src/StackMiddleware/DuplicateContentPreventionMiddleware.php(128): Drupal\connect_graphql\StackMiddleware\CacheControl->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #64 /app/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php(49): Drupal\cdn\StackMiddleware\DuplicateContentPreventionMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #65 /app/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Asm89\Stack\Cors->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #66 /app/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #67 /app/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #68 /app/web/core/lib/Drupal/Core/DrupalKernel.php(694): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #69 /app/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #70 {main}. {"severity_level":5} {"referer":"https://example.com/url","ip":"110.249.201.188","request_uri":"https://example.com/cdn/ff/gYQxCoETBJifqbLiWvx5SSHL1JQlqCFHLGa4Q3ISzqI/1568014569/public/styles/scale_1000_no_upsize/public/2019-09/Officetour-IAG-1200x750-2018(5).jpg?itok=b3DMEDON","uid":0,"user":""}

Any idea what this could be?

📌 Task
Status

Fixed

Version

4.0

Component

Code

Created by

🇦🇺Australia kyuubi

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

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024