Problem/Motivation

This was originally reported as a private security issue but cleared by the security team for a public issue

Imagine there is a file with fid 999, uploaded to a Group. FID's are incremental, so one could easily guess this.
Now an attacker logs in, and is able to add files to content.
The code in core/modules/file/src/Element/ManagedFile.php allows to guess the file id and attach the specific file with the node.

Steps to reproduce

  1. Install Drupal with the Standard profile.
  2. Set up the private files ($settings['file_private_path'] in settings.php).
  3. Grant the permissions Create report content, View own unpublished content, and Administer node published status to the Content editor role.
    Verify that it does not have the permission Bypass content access control.
  4. Create two users with the Content editor role.
  5. Create a content type named report with a file field named field_attachment.
    • Configure the file field to use the private files upload destination.
    • Set the cardinality to Unlimited.
  6. As a user with the Content editor role:
    1. Create a node of type report.
    2. Upload a file named test_1.txt to the field_attachment field.
    3. Mark the node as unpublished.
    4. Save the node.
  7. As another user with the Content editor role:
    1. Visit the node creation form for the report content type.
    2. Open the browser developer tools.
    3. Edit the <input> element with the attribute name="field_attachment[0][fids]".
    4. Add the attribute value="1" (increment the value and retry if the following steps do not reveal the issue).
    5. Upload another file named test_2.txt using the field_attachment field.
    6. After the AJAX upload completes, the widget displays both test_1.txt and test_2.txt.

Proposed resolution

Add the validation in ManagedFile::valueCallback() element to check that user has download access of the file using $file->access('download').

Remaining tasks

Needs fix

User interface changes

N/A

Introduced terminology

N/A

API changes

N/A

Data model changes

N/A

Release notes snippet

N/A

CommentFileSizeAuthor
#17 3593472_17_regression.patch781 bytesaporie

Issue fork drupal-3593472

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mohit_aghera created an issue. See original summary.

mohit_aghera’s picture

Status: Active » Needs review
mohit_aghera’s picture

Assigned: mohit_aghera » Unassigned
smustgrave’s picture

Status: Needs review » Needs work

Small comments/questions on the MR.

mohit_aghera’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Think feedback has been addressed here. The thread about expanding a test was a question and I also couldn't find a spot so lets see what committers think.

godotislate’s picture

Status: Reviewed & tested by the community » Needs review

Q on the MR.

godotislate’s picture

Status: Needs review » Reviewed & tested by the community

Question answered, thanks to @starlight-sparkle. Back to RTBC.

  • godotislate committed d5bb973e on 11.x
    task: #3593472 Insecure Direct Object Reference in Private File Uploads...

  • godotislate committed 80ff540c on main
    task: #3593472 Insecure Direct Object Reference in Private File Uploads...
godotislate’s picture

Version: main » 11.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Committed and pushed 80ff540 to main and d5bb973 to 11.x. Thanks!

This probably can go to 11.4.x as well, but will consult other committers.

  • godotislate committed 83a5f2b4 on 11.4.x
    task: #3593472 Insecure Direct Object Reference in Private File Uploads...
godotislate’s picture

Version: 11.x-dev » 11.4.x-dev
Status: Patch (to be ported) » Fixed

Consulted with @longwave, and he agreed this is good for 11.4. Committed 83a5f2b and pushed to 11.4.x.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

aporie’s picture

StatusFileSize
new781 bytes

This security improvement introduces a regression in the following case:

  • Users are able to access a public form where they can upload files which should be securely hosted on the remote server
  • Users are anonymous and the form is using managed_file element
  • With the improvement, the managed_file element will not return the table where user can manage their recently uploaded file (remove them), before submitting the entire form.
  • When submitting the form (or during the ajax callback), users may face validation errors if the field was required or any custom implementation requesting at least one attachment was implemented.

Suggestion of improvement:

Only target $file->isPermanent(). Assuming that when the form is submitted the file is set as permanent, this should allow the above scenario without opening wide access to previously uploaded ID guessing file.

To further improve security, Drupal must be configured to erase temporary file as soon as possible (every 24h).

I'm attaching a patch which works for my case, in case it may help others.

priyankampatil’s picture

@aporie I faced a similar issue with Webform submissions where, if a file field was marked as required, the form would not allow the submission to complete. However, even after applying the patch, the submission is still being blocked when the mandatory file field is present.