CVE-2023-22728 (published 2023-04-26T14:15Z)

Silverstripe Framework is the Model-View-Controller framework that powers the Silverstripe content management system. Prior to version 4.12.15, the GridField print view incorrectly validates the permission of DataObjects potentially allowing a content author to view records they are not authorised to access. Users should upgrade to Silverstripe Framework 4.12.15 or above to address the issue.

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-862
cwe_name: Missing Authorization
description: The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
extended_description: 
            Assuming a user with a given identity, authorization is the process of determining whether that user can access a given resource, based on the user's privileges and any permissions or other access-control specifications that apply to the resource.
            When access control checks are not applied, users are able to access data or perform actions that they should not be allowed to perform. This can lead to a wide range of problems, including information exposures, denial of service, and arbitrary code execution.
         
         

Fix information:
repo_url: https://github.com/silverstripe/silverstripe-framework
commit_details: repo_url: https://github.com/silverstripe/silverstripe-framework
author: Guy Sartorelli
author_date: 2023-02-14 12:52:39+13:00
msg: [CVE-2023-22728] Check canView before printing from GridField
repository: repo_url: https://github.com/silverstripe/silverstripe-framework
repo_name: silverstripe/silverstripe-framework
description: Silverstripe Framework, the MVC framework that powers Silverstripe CMS
repo_language: PHP
owner: silverstripe
file_changes: filename: GridFieldPrintButton.php
change_type: ModificationType.MODIFY
diff: @@ -228,21 +228,23 @@ class GridFieldPrintButton extends AbstractGridFieldComponent implements GridFie
 
         /** @var DataObject $item */
         foreach ($items->limit(null) as $item) {
-            $itemRow = new ArrayList();
+            if (!$item->hasMethod('canView') || $item->canView()) {
+                $itemRow = new ArrayList();
 
-            foreach ($printColumns as $field => $label) {
-                $value = $gridFieldColumnsComponent
-                    ? strip_tags($gridFieldColumnsComponent->getColumnContent($gridField, $item, $field))
-                    : $gridField->getDataFieldValue($item, $field);
+                foreach ($printColumns as $field => $label) {
+                    $value = $gridFieldColumnsComponent
+                        ? strip_tags($gridFieldColumnsComponent->getColumnContent($gridField, $item, $field))
+                        : $gridField->getDataFieldValue($item, $field);
+
+                    $itemRow->push(new ArrayData([
+                        "CellString" => $value,
+                    ]));
+                }
 
-                $itemRow->push(new ArrayData([
-                    "CellString" => $value,
+                $itemRows->push(new ArrayData([
+                    "ItemRow" => $itemRow
                 ]));
             }
-
-            $itemRows->push(new ArrayData([
-                "ItemRow" => $itemRow
-            ]));
             if ($item->hasMethod('destroy')) {
                 $item->destroy();
             }

programming_language: PHP
filename: GridFieldPrintButtonTest.php
change_type: ModificationType.MODIFY
diff: @@ -32,6 +32,19 @@ class GridFieldPrintButtonTest extends SapphireTest
     }
 
     public function testLimit()
+    {
+        $this->assertEquals(42, $this->getTestableRows()->count());
+    }
+
+    public function testCanViewIsRespected()
+    {
+        $orig = TestObject::$canView;
+        TestObject::$canView = false;
+        $this->assertEquals(0, $this->getTestableRows()->count());
+        TestObject::$canView = $orig;
+    }
+
+    private function getTestableRows()
     {
         $list = TestObject::get();
 
@@ -48,7 +61,6 @@ class GridFieldPrintButtonTest extends SapphireTest
 
         // Printed data should ignore pagination limit
         $printData = $button->generatePrintData($gridField);
-        $rows = $printData->ItemRows;
-        $this->assertEquals(42, $rows->count());
+        return $printData->ItemRows;
     }
 }

programming_language: PHP
filename: TestObject.php
change_type: ModificationType.MODIFY
diff: @@ -12,4 +12,11 @@ class TestObject extends DataObject implements TestOnly
     private static $db = [
         'Name' => 'Varchar'
     ];
+
+    public static bool $canView = true;
+
+    public function canView($member = null)
+    {
+        return static::$canView;
+    }
 }

programming_language: PHP