Problem/Motivation

Upgrade to 6.3.1(security update), a Webform with a file upload field loses file on submit for anonymous and shows error "The uploaded file is invalid"

Steps to reproduce

  1. Use a webform with a managed_file element
  2. Upload a file, submit webform
  3. You'll get "The uploaded file is invalid" — the file is cleared

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Comments

priyankampatil created an issue. See original summary.

priyankampatil’s picture

Issue summary: View changes
liam morland’s picture

priyankampatil’s picture

No, this is a completely different scenario. In our case, an anonymous user is unable to submit a webform containing a managed file field and receives “The uploaded file is invalid” error, whereas an authenticated user can successfully submit the same form with the same file field. This issue is not related to resuming a draft or re-uploading a previously uploaded file.

liam morland’s picture

Is this new between 6.3.0 and 6.3.1? Can you use git bisect to figure out which commit caused the problem?

cilefen’s picture

Status: Active » Postponed (maintainer needs more info)
Issue tags: +Possible duplicate
priyankampatil’s picture

Similar issue of file getting removed on webform submit caused by webform update from 6.3.0 to 6.3.1. #3619282: Upgrade to 11.4.5, a Webform with a file upload field loses file on submit for anonymous issue got resolved by reverting #3593472: Insecure Direct Object Reference in Private File Uploads code.

rossb89’s picture

Yes we are getting this as well! But weirdly, not locally or on production, but when the production site that hosts a webform embedded on another website... weird!

This is the code that was added valueCallback() https://git.drupalcode.org/project/webform/-/blob/19b86bcb011c857f67d789...

That seems to be causing the issue. Still trying to work out why it's only happening when the site is in an iFrame..

We are also using the sf3s module for the private file system on production which may be relevant.

rossb89’s picture

Update **fixed** : the issue for us was specifically around the fact our website with the webforms is included through iFrames on other known trusted websites. After doing the ajax upload for the file, the browser was blocking the cookie due to the cookie_samesite value being the default of Lax. In our circumstance for this website and it's purpose, it is acceptable to set the policy to None to mitigate the issue and allow the session cookie to be set cross origin.

Because of the check to !$file->access('download') in the updated 6.3.1 webform code, core's file access control check runs indirectly here and checks anonymous_allowed_file_ids in the session to decide access for an anonymous file owner.

The core code here https://git.drupalcode.org/project/drupal/-/blob/11.3.x/core/modules/fil... sets anonymous_allowed_file_ids and then is checked here https://git.drupalcode.org/project/drupal/-/blob/11.3.x/core/modules/fil... to determine access.

If it's missing from the session (i.e. due to the cross origin cookie not being allowed) then the check will fail and thus validation fails, causing the issue.

rossb89’s picture

Further to this ^ what I posted above did not fix this for Safari on desktop or iOS.

Had to do some funky stuff with adding some middleware to write in a Partitioned session cookie re https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Third-party_...

Which worked a treat, except still for older iOS (e.g. 18.5) where CHIPS isn't supported. So, I also added a workaround on the webforms in a little preprocess where we inject some JS on webforms where there is a file upload field, that will test if partitioned cookies are allowed, if not and the webform is currently embedded in an iFrame, output a link to the webform on the site it's hosted on so there are no third party cookie issues. We have redirection code anyway on this site that serves up the webforms after submission so the user ends up back on the original site after submission anyway.

Aside from adding some code to undo the work of the security fix, I couldn't see another way around this annoyingly!

lexxerlee’s picture

I ran into this issue and found a workaround that resolved it for me.

In:

webform/src/Plugin/WebformElement/WebformManagedFileBase.php

around line 907, replace:

$token = NestedArray::getValue($form_state->getUserInput(), $parents);

with:

$inputs = $form_state->getUserInput();

foreach ($parents as $parent) {
  if (isset($inputs[$parent]) && isset($inputs[$parent]['files_group'])) {
    $inputs[$parent] = array_merge(
      $inputs[$parent],
      $inputs[$parent]['files_group']
    );
  }
}

$token = NestedArray::getValue($inputs, $parents);

From my debugging, the problem occurs when multiple file uploads are allowed.
In this case, the expected key can be nested inside files_group,
and NestedArray::getValue() is unable to find the token using the original input structure.

As a result, $token becomes NULL, the HMAC validation fails, and Webform throws:

The uploaded file is invalid.

This patch was written quickly as a proof of concept and is still being tested against different configurations and file upload scenarios.
I cannot guarantee that it covers all edge cases yet, but it resolved the issue in my case.