CVE-2024-29885 (published 2024-07-17T20:15Z)

silverstripe/reports is an API for creating backend reports in the Silverstripe Framework. In affected versions reports can be accessed by their direct URL by any user who has access to view the reports admin section, even if the `canView()` method for that report returns `false`. This issue has been addressed in version 5.2.3. All users are advised to upgrade. There are no known workarounds for this vulnerability.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/silverstripe/silverstripe-reports
commit_details: repo_url: https://github.com/silverstripe/silverstripe-reports
author: Guy Sartorelli
author_date: 2024-03-27 14:06:39+13:00
msg: [CVE-2024-29885] Respect canView permissions for viewing reports
repository: repo_url: https://github.com/silverstripe/silverstripe-reports
repo_name: silverstripe/silverstripe-reports
description: API for creating backend reports in the Silverstripe Framework.
repo_language: PHP
owner: silverstripe
file_changes: filename: ReportAdmin.php
change_type: ModificationType.MODIFY
diff: @@ -124,6 +124,9 @@ class ReportAdmin extends LeftAndMain implements PermissionProvider
                 return $this->httpError(404);
             }
             $this->reportObject = $allReports[$this->reportClass];
+            if (!$this->reportObject->canView()) {
+                return Security::permissionFailure($this);
+            }
         }
 
         // Delegate to sub-form

programming_language: PHP
filename: ReportAdminTest.php
change_type: ModificationType.MODIFY
diff: @@ -4,14 +4,14 @@ namespace SilverStripe\Reports\Tests;
 
 use ReflectionClass;
 use SilverStripe\Control\Controller;
-use SilverStripe\Control\HTTPRequest;
-use SilverStripe\Dev\SapphireTest;
+use SilverStripe\Dev\FunctionalTest;
 use SilverStripe\Reports\Report;
 use SilverStripe\Reports\ReportAdmin;
+use SilverStripe\Reports\Tests\ReportAdminTest\CannotViewReport;
 use SilverStripe\Reports\Tests\ReportAdminTest\FakeReport;
 use SilverStripe\Reports\Tests\ReportAdminTest\FakeReport2;
 
-class ReportAdminTest extends SapphireTest
+class ReportAdminTest extends FunctionalTest
 {
     public function testBreadcrumbsAreGenerated()
     {
@@ -46,6 +46,34 @@ class ReportAdminTest extends SapphireTest
         $this->assertSame('Fake report two', $map['Title']);
     }
 
+    public function provideShowReport(): array
+    {
+        return [
+            'cannot view' => [
+                'reportClass' => CannotViewReport::class,
+                'expected' => 403,
+            ],
+            'can view' => [
+                'reportClass' => FakeReport::class,
+                'expected' => 200,
+            ],
+        ];
+    }
+
+    /**
+     * @dataProvider provideShowReport
+     */
+    public function testShowReport(string $reportClass, int $expected): void
+    {
+        $this->logInWithPermission('ADMIN');
+        $report = new $reportClass();
+        $controller = $this->mockController($report);
+        $breadcrumbs = $controller->BreadCrumbs();
+        $response = $this->get($breadcrumbs[1]->Link);
+
+        $this->assertSame($expected, $response->getStatusCode());
+    }
+
     /**
      * @param Report $report
      * @return ReportAdmin

programming_language: PHP
filename: CannotViewReport.php
change_type: ModificationType.ADD
diff: @@ -0,0 +1,19 @@
+<?php
+
+namespace SilverStripe\Reports\Tests\ReportAdminTest;
+
+use SilverStripe\Dev\TestOnly;
+use SilverStripe\Reports\Report;
+
+class CannotViewReport extends Report implements TestOnly
+{
+    public function title()
+    {
+        return 'Cannot View report';
+    }
+
+    public function canView($member = null)
+    {
+        return false;
+    }
+}

programming_language: PHP
filename: FakeReport.php
change_type: ModificationType.MODIFY
diff: @@ -3,7 +3,9 @@
 namespace SilverStripe\Reports\Tests\ReportAdminTest;
 
 use SilverStripe\Dev\TestOnly;
+use SilverStripe\ORM\ArrayList;
 use SilverStripe\Reports\Report;
+use SilverStripe\Security\Member;
 
 class FakeReport extends Report implements TestOnly
 {
@@ -11,4 +13,11 @@ class FakeReport extends Report implements TestOnly
     {
         return 'Fake report';
     }
+
+    public function sourceRecords($params = [], $sort = null, $limit = null)
+    {
+        $list = new ArrayList();
+        $list->setDataClass(Member::class);
+        return $list;
+    }
 }

programming_language: PHP