Malformed file field AJAX request leads to 'Warning: Undefined array key "#prefix"'

Created on 22 September 2023, over 1 year ago
Updated 30 August 2024, 4 months ago

Problem/Motivation

When certain security vulnerability scanners send malformed requests to Drupal's file fields, Drupal's log is flooded with Warning: Undefined array key "#prefix".

Steps to reproduce

  1. Create a contact form
  2. Add a file field to the contact form
  3. Send a malformed request (trailing %27 apostrophe) to the contact form's file field AJAX endpoint:
    curl -s -XPOST 'https://d10test.ddev.site/contact/test?ajax_form=1&_wrapper_format=drupal_ajax&element_parents=field_file/widget/0%27' -H 'Content-Type: multipart/form-data; boundary=foo' --data-binary $'--foo\r\nContent-Disposition: form-data; name="form_id"\r\n\r\ncontact_message_test_form\r\n--foo--\r\n'
Warning: Undefined array key "#prefix" in Drupal\file\Element\ManagedFile::uploadAjaxCallback() (line 199 of /var/www/html/webroot/core/modules/file/src/Element/ManagedFile.php)
#0 /var/www/html/webroot/core/includes/bootstrap.inc(347): _drupal_error_handler_real(2, 'Undefined array...', '/var/www/html/w...', 199)
#1 /var/www/html/webroot/core/modules/file/src/Element/ManagedFile.php(199): _drupal_error_handler(2, 'Undefined array...', '/var/www/html/w...', 199)
#2 [internal function]: Drupal\file\Element\ManagedFile::uploadAjaxCallback(Array, Object(Drupal\Core\Form\FormState), Object(Symfony\Component\HttpFoundation\Request))
#3 /var/www/html/webroot/core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php(69): call_user_func_array(Array, Array)
#4 /var/www/html/webroot/core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php(109): Drupal\Core\Form\FormAjaxResponseBuilder->buildResponse(Object(Symfony\Component\HttpFoundation\Request), Array, Object(Drupal\Core\Form\FormState), Array)
#5 [internal function]: Drupal\Core\Form\EventSubscriber\FormAjaxSubscriber->onException(Object(Symfony\Component\HttpKernel\Event\ExceptionEvent), 'kernel.exceptio...', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#6 /var/www/html/webroot/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(142): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\ExceptionEvent), 'kernel.exceptio...', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#7 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(229): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object(Symfony\Component\HttpKernel\Event\ExceptionEvent), 'kernel.exceptio...')
#8 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(92): Symfony\Component\HttpKernel\HttpKernel->handleThrowable(Object(Drupal\Core\Form\FormAjaxException), Object(Symfony\Component\HttpFoundation\Request), 1)
#9 /var/www/html/webroot/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#10 /var/www/html/webroot/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#11 /var/www/html/webroot/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#12 /var/www/html/webroot/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#13 /var/www/html/webroot/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#14 /var/www/html/webroot/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#15 /var/www/html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /var/www/html/webroot/core/lib/Drupal/Core/DrupalKernel.php(718): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#17 /var/www/html/webroot/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#18 {main}

Proposed resolution

Avoid the log messages β€” if $form['#prefix'] is unset, initialize it before attempting to append to it.

Remaining tasks

Review patch.

User interface changes

n/a

API changes

n/a

Data model changes

n/a

Release notes snippet

πŸ› Bug report
Status

Needs work

Version

11.0 πŸ”₯

Component
File systemΒ  β†’

Last updated 3 days ago

Created by

πŸ‡ΊπŸ‡ΈUnited States smokris Athens, Ohio, USA

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

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