CVE-2022-29858 (published 2022-06-28T22:15Z)

Silverstripe silverstripe/assets through 1.10 is vulnerable to improper access control that allows protected images to be published by changing an existing image short code on website content.

Severity: MEDIUM
CVSS v2 base score: 4.0 (AV:N/AC:L/Au:S/C:P/I:N/A:N)
CVSS v3 base score: 4.3, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N)

Weakness information:
cwe_id: CWE-287
cwe_name: Improper Authentication
description: When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
extended_description: 
            
			
         
         

Fix information:
repo_url: https://github.com/silverstripe/silverstripe-assets
commit_details: repo_url: https://github.com/silverstripe/silverstripe-assets
author: Steve Boyd
author_date: 2022-04-27 12:12:37+12:00
msg: [CVE-2022-29858] Read grant config for regenerate_shortcode
repository: repo_url: https://github.com/silverstripe/silverstripe-assets
repo_name: silverstripe/silverstripe-assets
description: Silverstripe Assets component
repo_language: PHP
owner: silverstripe
file_changes: filename: ImageShortcodeProvider.php
change_type: ModificationType.MODIFY
diff: @@ -136,10 +136,12 @@ class ImageShortcodeProvider extends FileShortcodeProvider implements ShortcodeH
      */
     public static function regenerate_shortcode($args, $content, $parser, $shortcode, $extra = [])
     {
+        $allowSessionGrant = static::config()->allow_session_grant;
+
         // Check if there is a suitable record
         $record = static::find_shortcode_record($args);
         if ($record) {
-            $args['src'] = $record->getURL();
+            $args['src'] = $record->getURL($allowSessionGrant);
         }
 
         // Rebuild shortcode

programming_language: PHP
filename: ImageShortcodeProviderTest.php
change_type: ModificationType.MODIFY
diff: @@ -4,11 +4,17 @@ namespace SilverStripe\Assets\Tests\Shortcodes;
 
 use SilverStripe\Assets\File;
 use Silverstripe\Assets\Dev\TestAssetStore;
+use SilverStripe\Assets\FilenameParsing\ParsedFileID;
+use SilverStripe\Assets\Storage\AssetStore;
 use SilverStripe\Core\Config\Config;
 use SilverStripe\Dev\SapphireTest;
 use SilverStripe\View\Parsers\ShortcodeParser;
 use SilverStripe\Assets\Image;
 use SilverStripe\Assets\Shortcodes\ImageShortcodeProvider;
+use SilverStripe\Assets\Shortcodes\FileShortcodeProvider;
+use SilverStripe\Core\Injector\Injector;
+use SilverStripe\Security\InheritedPermissions;
+use SilverStripe\Security\Member;
 
 /**
  * @skipUpgrade
@@ -187,4 +193,39 @@ class ImageShortcodeProviderTest extends SapphireTest
             $this->assertStringNotContainsString('loading="lazy"', $parser->parse($shortcode));
         });
     }
+
+    public function testRegenerateShortcode()
+    {
+        $assetStore = Injector::inst()->get(AssetStore::class);
+        $member = Member::create();
+        $member->write();
+        // Logout first to throw away the existing session which may have image grants.
+        $this->logOut();
+        $this->logInAs($member);
+        // image is in protected asset store
+        $image = $this->objFromFixture(Image::class, 'imageWithTitle');
+        $image->CanViewType = InheritedPermissions::ONLY_THESE_USERS;
+        $image->write();
+        $url = $image->getUrl(false);
+        $args = [
+            'id' => $image->ID,
+            'src' => $url,
+            'width' => '550',
+            'height' => '366',
+            'class' => 'leftAlone ss-htmleditorfield-file image',
+        ];
+        $shortHash = substr($image->getHash(), 0, 10);
+        $expected = implode(' ', [
+            '[image id="' . $image->ID . '" src="/assets/folder/' . $shortHash . '/test-image.png" width="550"',
+            'height="366" class="leftAlone ss-htmleditorfield-file image"]'
+        ]);
+        $parsedFileID = new ParsedFileID($image->getFilename(), $image->getHash());
+        $html = ImageShortcodeProvider::regenerate_shortcode($args, '', '', 'image');
+        $this->assertSame($expected, $html);
+        $this->assertFalse($assetStore->isGranted($parsedFileID));
+        Config::modify()->set(FileShortcodeProvider::class, 'allow_session_grant', true);
+        $html = ImageShortcodeProvider::regenerate_shortcode($args, '', '', 'image');
+        $this->assertSame($expected, $html);
+        $this->assertTrue($assetStore->isGranted($parsedFileID));
+    }
 }

programming_language: PHP