function FileFieldWidgetTest::doTestTemporaryFileRemovalExploit

Same name in other branches
  1. 9 core/modules/file/tests/src/Functional/FileFieldWidgetTest.php \Drupal\Tests\file\Functional\FileFieldWidgetTest::doTestTemporaryFileRemovalExploit()
  2. 8.9.x core/modules/file/tests/src/Functional/FileFieldWidgetTest.php \Drupal\Tests\file\Functional\FileFieldWidgetTest::doTestTemporaryFileRemovalExploit()
  3. 10 core/modules/file/tests/src/Functional/FileFieldWidgetTest.php \Drupal\Tests\file\Functional\FileFieldWidgetTest::doTestTemporaryFileRemovalExploit()

Helper for testing exploiting the temporary file removal using fid.

Parameters

\Drupal\user\UserInterface $victim_user: The victim user.

\Drupal\user\UserInterface $attacker_user: The attacker user.

2 calls to FileFieldWidgetTest::doTestTemporaryFileRemovalExploit()
FileFieldWidgetTest::testTemporaryFileRemovalExploit in core/modules/file/tests/src/Functional/FileFieldWidgetTest.php
Tests exploiting the temporary file removal of another user using fid.
FileFieldWidgetTest::testTemporaryFileRemovalExploitAnonymous in core/modules/file/tests/src/Functional/FileFieldWidgetTest.php
Tests exploiting the temporary file removal for anonymous users using fid.

File

core/modules/file/tests/src/Functional/FileFieldWidgetTest.php, line 562

Class

FileFieldWidgetTest
Tests the file field widget with public and private files.

Namespace

Drupal\Tests\file\Functional

Code

protected function doTestTemporaryFileRemovalExploit(UserInterface $victim_user, UserInterface $attacker_user) : void {
    $type_name = 'article';
    $field_name = 'test_file_field';
    $this->createFileField($field_name, 'node', $type_name);
    $test_file = $this->getTestFile('text');
    $type = 'no-js';
    // Create a temporary file owned by the victim user. This will be as if
    // they had uploaded the file, but not saved the node they were editing
    // or creating.
    $victim_tmp_file = $this->createTemporaryFile('some text', $victim_user);
    $victim_tmp_file = File::load($victim_tmp_file->id());
    $this->assertTrue($victim_tmp_file->isTemporary(), 'New file saved to disk is temporary.');
    $this->assertNotEmpty($victim_tmp_file->id(), 'New file has an fid.');
    $this->assertEquals($victim_user->id(), $victim_tmp_file->getOwnerId(), 'New file belongs to the victim.');
    // Have attacker create a new node with a different uploaded file and
    // ensure it got uploaded successfully.
    $edit = [
        'title[0][value]' => $type . '-title',
    ];
    // Attach a file to a node.
    $edit['files[' . $field_name . '_0]'] = $this->container
        ->get('file_system')
        ->realpath($test_file->getFileUri());
    $this->drupalGet(Url::fromRoute('node.add', [
        'node_type' => $type_name,
    ]));
    $this->submitForm($edit, 'Save');
    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
    
    /** @var \Drupal\file\FileInterface $node_file */
    $node_file = File::load($node->{$field_name}->target_id);
    $this->assertFileExists($node_file->getFileUri());
    $this->assertEquals($attacker_user->id(), $node_file->getOwnerId(), 'New file belongs to the attacker.');
    // Ensure the file can be downloaded.
    $this->drupalGet($node_file->createFileUrl());
    $this->assertSession()
        ->statusCodeEquals(200);
    // "Click" the remove button (emulating either a nojs or js submission).
    // In this POST request, the attacker "guesses" the fid of the victim's
    // temporary file and uses that to remove this file.
    $this->drupalGet($node->toUrl('edit-form'));
    $file_id_field = $this->assertSession()
        ->hiddenFieldExists($field_name . '[0][fids]');
    $file_id_field->setValue((string) $victim_tmp_file->id());
    $this->submitForm([], 'Remove');
    // The victim's temporary file should not be removed by the attacker's
    // POST request.
    $this->assertFileExists($victim_tmp_file->getFileUri());
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.