Add test for SA-CORE-2024-002

Created on 30 May 2025, 4 months ago

Problem/Motivation

This is a followup to SA-CORE-2024-002 which affected CKEditor5ImageController.
We should have a test that prevents this vulnerability from being reintroduced.

Steps to reproduce

Proposed resolution

We should add a unit test that replicates the upload conditions that triggered the vulnerability.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

πŸ“Œ Task
Status

Active

Version

11.0 πŸ”₯

Component

ckeditor5.module

Created by

πŸ‡«πŸ‡·France prudloff Lille

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.

  • Security improvements

    It makes Drupal less vulnerable to abuse or misuse. Note, this is the preferred tag, though the Security tag has a large body of issues tagged to it. Do NOT publicly disclose security vulnerabilities; contact the security team instead. Anyone (whether security team or not) can apply this tag to security improvements that do not directly present a vulnerability e.g. hardening an API to add filtering to reduce a common mistake in contributed modules.

Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @prudloff
  • Merge request !12289Apply patch from private issue β†’ (Open) created by prudloff
  • Pipeline finished with Failed
    4 months ago
    #510832
  • Pipeline finished with Success
    4 months ago
    Total: 787s
    #510839
  • πŸ‡«πŸ‡·France prudloff Lille

    I added and updated the patch from the private issue.
    People from the "Fixed by" section of https://www.drupal.org/sa-core-2024-002 β†’ should probably be credited.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Reading https://www.drupal.org/sa-core-2024-002 β†’ believe this is a good coverage.

  • πŸ‡ΊπŸ‡ΈUnited States xjm

    I don't think this paragraph contains sufficient information to determine if it is good test coverage or not:

    Under certain uncommon site configurations, a bug in the CKEditor 5 module can cause some image uploads to move the entire webroot to a different location on the file system. This could be exploited by a malicious user to take down a site.

    The commit corresponding to the SA might be more helpful to review.

    Ideally, it would be reviewed by someone with access to the original private issue report (which I've added to the summary). Reviewing it might be a good task for one of our provisional Security Team members.

  • πŸ‡ΊπŸ‡ΈUnited States xjm

    Another step I would expect to see for reviewing this would to be to revert the commit that fixed SA-CORE-2025-002, and have the test fail as expected, and then document that failure here on the issue.

  • πŸ‡ΊπŸ‡ΈUnited States benjifisher Boston area
  • πŸ‡¬πŸ‡§United Kingdom catch
  • πŸ‡¦πŸ‡ΊAustralia kim.pepper πŸ„β€β™‚οΈπŸ‡¦πŸ‡ΊSydney, Australia
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10
  • πŸ‡ΊπŸ‡ΈUnited States xjm
  • Merge request !12415Resolve #3527408 "Revert change" β†’ (Open) created by smustgrave
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Uploaded an MR with the fix reverted and the unit test added fails

    Fail          0.117s testInvalidFile                                                                 
    Log           0.442s *** Process execution output ***                                                
        PHPUnit 10.5.46 by Sebastian Bergmann and contributors.
        
        Runtime:       PHP 8.3.22
        Configuration: /builds/issue/drupal-3527408/core/phpunit.xml.dist
        
        F                                                                   1 / 1 (100%)
        
        Time: 00:00.123, Memory: 10.00 MB
        
        CKEditor5Image Controller (Drupal\Tests\ckeditor5\Unit\CKEditor5ImageController)
         ✘ Invalid file
           ┐
           β”œ Failed asserting that exception message 'Destination file path is not writable' contains 'The file "foo.txt" exceeds the upload limit defined in your form.'.
    

    So believe this is test coverage works

  • Pipeline finished with Failed
    4 months ago
    Total: 293s
    #526602
  • πŸ‡ΊπŸ‡ΈUnited States xjm

    I still don't think we're quite at a complete RTBC from the above, but I re-reviewed the full details of the private issue and will add my +1 to the RTBC confirming that it does indeed provide test coverage that should prevent the vulnerability from being reintroduced, despite that it is not possible to create an actual full exploit test in this situation. :)

    • xjm β†’ committed be2e9002 on 11.x
      Issue #3527408 by prudloff, smustgrave, xjm, benjifisher, catch, kim....
    • xjm β†’ committed 23a7a521 on 11.2.x
      Issue #3527408 by prudloff, smustgrave, xjm, benjifisher, catch, kim....
    • xjm β†’ committed c1208d04 on 10.6.x
      Issue #3527408 by prudloff, smustgrave, xjm, benjifisher, catch, kim....
    • xjm β†’ committed a0a7eec9 on 10.5.x
      Issue #3527408 by prudloff, smustgrave, xjm, benjifisher, catch, kim....
  • πŸ‡ΊπŸ‡ΈUnited States xjm

    Committed to 11.x, and cherry-picked to 11.2.x, 10.6.x, and 10.5.x as a test coverage improvement for a security issue. Thanks everyone!

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    This broke head on 10.5.x and 10.6.x https://git.drupalcode.org/project/drupal/-/jobs/5716804

    Reverting from there and setting to patch to be ported - the class Drupal\file\Upload\FileUploadHandlerInterface was only added in 11.1 (from memory).

    • larowlan β†’ committed a3fd7099 on 10.6.x
      Revert "Issue #3527408 by prudloff, smustgrave, xjm, benjifisher, catch...
    • larowlan β†’ committed ed874aed on 10.5.x
      Revert "Issue #3527408 by prudloff, smustgrave, xjm, benjifisher, catch...
  • πŸ‡ΊπŸ‡ΈUnited States xjm

    Whoopsidaisy, email notifications for core pipelines is clearly still an issue for me. Only thing I miss about DrupalCI. RIP, Testbot.

  • Merge request !1254810.x patch version from Leafy Sea Dragon. β†’ (Closed) created by xjm
  • πŸ‡ΊπŸ‡ΈUnited States xjm

    I dug a 10.2.x patch out of the private issue and spliced out the test. Applied locally, it has this diff against the previous commit:

    diff --git a/core/modules/ckeditor5/tests/src/Unit/CKEditor5ImageControllerTest.php b/core/modules/ckeditor5/tests/src/Unit/CKEditor5ImageControllerTest.php
    index bb69c28c6fb..eef04de7a16 100644
    --- a/core/modules/ckeditor5/tests/src/Unit/CKEditor5ImageControllerTest.php
    +++ b/core/modules/ckeditor5/tests/src/Unit/CKEditor5ImageControllerTest.php
    @@ -5,22 +5,25 @@
     namespace Drupal\Tests\ckeditor5\Unit;
     
     use Drupal\ckeditor5\Controller\CKEditor5ImageController;
    -use Drupal\ckeditor5\Plugin\CKEditor5PluginManagerInterface;
     use Drupal\Core\Entity\EntityConstraintViolationList;
     use Drupal\Core\Entity\EntityStorageInterface;
     use Drupal\Core\Entity\EntityTypeManagerInterface;
     use Drupal\Core\Entity\EntityTypeRepositoryInterface;
     use Drupal\Core\File\FileSystemInterface;
     use Drupal\Core\Lock\LockBackendInterface;
    +use Drupal\Core\Session\AccountInterface;
     use Drupal\editor\EditorInterface;
     use Drupal\file\Entity\File;
     use Drupal\file\FileInterface;
    -use Drupal\file\Upload\FileUploadHandlerInterface;
    +use Drupal\file\Validation\FileValidatorInterface;
     use Drupal\Tests\UnitTestCase;
     use Prophecy\Argument;
     use Symfony\Component\DependencyInjection\ContainerInterface;
     use Symfony\Component\HttpFoundation\Request;
     use Symfony\Component\HttpKernel\Exception\HttpException;
    +use Symfony\Component\Mime\MimeTypeGuesserInterface;
    +use Symfony\Component\Validator\ConstraintViolationListInterface;
    +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
     
     /**
      * Tests CKEditor5ImageController.
    @@ -30,15 +33,14 @@
      */
     final class CKEditor5ImageControllerTest extends UnitTestCase {
     
    -  /**
    -   * Tests that upload fails correctly when the file is too large.
    -   */
       public function testInvalidFile(): void {
         $file_system = $this->prophesize(FileSystemInterface::class);
         $file_system->move(Argument::any())->shouldNotBeCalled();
         $directory = 'public://';
         $file_system->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY)->willReturn(TRUE);
         $file_system->getDestinationFilename(Argument::cetera())->willReturn('/tmp/foo.txt');
    +    $event_dispatcher = $this->prophesize(EventDispatcherInterface::class);
    +    $event_dispatcher->dispatch(Argument::any())->willReturnArgument(0);
         $lock = $this->prophesize(LockBackendInterface::class);
         $lock->acquire(Argument::any())->willReturn(TRUE);
         $container = $this->prophesize(ContainerInterface::class);
    @@ -55,11 +57,15 @@ public function testInvalidFile(): void {
         $entity_type_repository->getEntityTypeFromClass(File::class)->willReturn('file');
         $container->get('entity_type.repository')->willReturn($entity_type_repository->reveal());
         \Drupal::setContainer($container->reveal());
    +    $file_validator = $this->prophesize(FileValidatorInterface::class);
    +    $file_validator->validate(Argument::cetera())->willReturn($this->prophesize(ConstraintViolationListInterface::class)->reveal());
         $controller = new CKEditor5ImageController(
           $file_system->reveal(),
    -      $this->prophesize(FileUploadHandlerInterface::class)->reveal(),
    +      $this->prophesize(AccountInterface::class)->reveal(),
    +      $this->prophesize(MimeTypeGuesserInterface::class)->reveal(),
           $lock->reveal(),
    -      $this->prophesize(CKEditor5PluginManagerInterface::class)->reveal(),
    +      $event_dispatcher->reveal(),
    +      $file_validator->reveal(),
         );
         // We can't use vfsstream here because of how Symfony request works.
         $file_uri = tempnam(sys_get_temp_dir(), 'tmp');
    
    

    Let's see if it passes on 10.6.x.

  • πŸ‡ΊπŸ‡ΈUnited States xjm

    xjm β†’ changed the visibility of the branch 3527408-revert-change to hidden.

  • πŸ‡ΊπŸ‡ΈUnited States xjm

    xjm β†’ changed the visibility of the branch 3527408-add-test-for to hidden.

  • Pipeline finished with Failed
    3 months ago
    Total: 652s
    #535078
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Seems the unit test keeps failing, re-ran twice

  • πŸ‡ΊπŸ‡ΈUnited States xjm

    Failing test output is:

    ---- Drupal\Tests\ckeditor5\Unit\CKEditor5ImageControllerTest ----
    Status    Group      Filename          Line Function                            
    --------------------------------------------------------------------------------
    Fail      Other      phpunit-700.xml      0 Drupal\Tests\ckeditor5\Unit\CKEdito
        PHPUnit Test failed to complete; Error: PHPUnit 9.6.23 by Sebastian
        Bergmann and contributors.
        
        Testing Drupal\Tests\ckeditor5\Unit\CKEditor5ImageControllerTest
        E                                                                   1 / 1
        (100%)R
        
        Time: 00:00.080, Memory: 8.00 MB
        
        There was 1 error:
        
        1)
        Drupal\Tests\ckeditor5\Unit\CKEditor5ImageControllerTest::testInvalidFile
        TypeError: Cannot assign null to property
        Drupal\ckeditor5\Controller\CKEditor5ImageController::$fileUploadHandler of
        type Drupal\file\Upload\FileUploadHandler
        
        /builds/issue/drupal-3527408/core/modules/ckeditor5/src/Controller/CKEditor5ImageController.php:99
        /builds/issue/drupal-3527408/core/modules/ckeditor5/tests/src/Unit/CKEditor5ImageControllerTest.php:62
        /builds/issue/drupal-3527408/vendor/phpunit/phpunit/src/Framework/TestResult.php:729
        /builds/issue/drupal-3527408/vendor/phpunit/phpunit/src/Framework/TestSuite.php:685
        /builds/issue/drupal-3527408/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:651
        /builds/issue/drupal-3527408/vendor/phpunit/phpunit/src/TextUI/Command.php:146
        /builds/issue/drupal-3527408/vendor/phpunit/phpunit/src/TextUI/Command.php:99
        
        --
        
        There was 1 risky test:
        
        1)
        Drupal\Tests\ckeditor5\Unit\CKEditor5ImageControllerTest::testInvalidFile
        This test did not perform any assertions
        
        /builds/issue/drupal-3527408/core/tests/Drupal/Tests/Listeners/DrupalListener.php:62
        /builds/issue/drupal-3527408/vendor/phpunit/phpunit/src/Framework/TestResult.php:453
        /builds/issue/drupal-3527408/vendor/phpunit/phpunit/src/Framework/TestResult.php:981
        /builds/issue/drupal-3527408/vendor/phpunit/phpunit/src/Framework/TestSuite.php:685
        /builds/issue/drupal-3527408/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:651
        /builds/issue/drupal-3527408/vendor/phpunit/phpunit/src/TextUI/Command.php:146
        /builds/issue/drupal-3527408/vendor/phpunit/phpunit/src/TextUI/Command.php:99
        
        ERRORS!
        Tests: 1, Assertions: 0, Errors: 1, Risky: 1.
        
        Remaining self deprecation notices (1)
        
          1x: Calling
        Drupal\ckeditor5\Controller\CKEditor5ImageController::__construct() with
        the $current_user argument is deprecated in drupal:10.3.0 and is removed
        from drupal:11.0.0. See https://www.drupal.org/node/3388990
            1x in CKEditor5ImageControllerTest::testInvalidFile from
    
  • Pipeline finished with Failed
    6 days ago
    Total: 708s
    #616680
  • Pipeline finished with Success
    6 days ago
    Total: 764s
    #616689
  • Status changed to Needs review 6 days ago
Production build 0.71.5 2024