CVE-2023-41892: Improper Control of Generation of Code ('Code Injection') (CWE-94)
value: Craft CMS is a platform for creating digital experiences. This is a high-impact, low-complexity attack vector. Users running Craft installations before 4.4.15 are encouraged to update to at least that version to mitigate the issue. This issue has been fixed in Craft CMS 4.4.15.
CWE description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
CVSS v3 base score: 9.8
Published: 2023-09-13T20:15Z
Repository: https://github.com/craftcms/cms
Language: PHP
Files changed: src/controllers/AssetIndexesController.php, src/controllers/AssetSettingsController.php, src/controllers/BaseElementsController.php, src/controllers/ConditionsController.php, src/controllers/FieldsController.php, src/controllers/FsController.php, src/controllers/GraphqlController.php, src/controllers/ImageTransformsController.php, src/controllers/LivePreviewController.php, src/controllers/PluginStoreController.php, src/controllers/PluginsController.php, src/controllers/RebrandController.php, src/controllers/RoutesController.php, src/controllers/SectionsController.php, src/controllers/SitesController.php, src/controllers/StructuresController.php, src/controllers/SystemMessagesController.php, src/controllers/SystemSettingsController.php, src/controllers/UserSettingsController.php, src/controllers/VolumesController.php
Commit date: 2023-06-27 16:13:30 -0700
Commit message: Call beforeAction() up front

Diff: diff --git a/src/controllers/AssetIndexesController.php b/src/controllers/AssetIndexesController.php
index 89a5a0fd569..fbeb58a9790 100644
--- a/src/controllers/AssetIndexesController.php
+++ b/src/controllers/AssetIndexesController.php
@@ -34,15 +34,19 @@ class AssetIndexesController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // No permission no bueno
         $this->requirePermission('utility:asset-indexes');
         $this->requireAcceptsJson();
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Start an indexing session.
      *
diff --git a/src/controllers/AssetSettingsController.php b/src/controllers/AssetSettingsController.php
index 17b7b220cf9..65ea0a4f2fe 100644
--- a/src/controllers/AssetSettingsController.php
+++ b/src/controllers/AssetSettingsController.php
@@ -23,14 +23,18 @@ class AssetSettingsController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All user settings actions require an admin
         $this->requireAdmin();
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Saves the system asset settings.
      *
diff --git a/src/controllers/BaseElementsController.php b/src/controllers/BaseElementsController.php
index a0058e2966b..a4fb5fde4a9 100644
--- a/src/controllers/BaseElementsController.php
+++ b/src/controllers/BaseElementsController.php
@@ -25,14 +25,18 @@ abstract class BaseElementsController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All actions require control panel requests
         $this->requireCpRequest();
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Returns the posted element type class.
      *
diff --git a/src/controllers/ConditionsController.php b/src/controllers/ConditionsController.php
index ca3bb38b515..c1be139dc29 100644
--- a/src/controllers/ConditionsController.php
+++ b/src/controllers/ConditionsController.php
@@ -32,10 +32,16 @@ class ConditionsController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
+        $this->requireCpRequest();
+
         $baseConfig = Json::decodeIfJson($this->request->getBodyParam('config'));
         $config = $this->request->getBodyParam($baseConfig['name']);
         $newRuleType = ArrayHelper::remove($config, 'new-rule-type');
         $conditionsService = Craft::$app->getConditions();
         $this->_condition = $conditionsService->createCondition($config);
@@ -46,11 +52,11 @@ class ConditionsController extends Controller
             $rule = $conditionsService->createConditionRule($newRuleType);
             $rule->setAutofocus();
             $this->_condition->addConditionRule($rule);
         }
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * @return string
      */
diff --git a/src/controllers/FieldsController.php b/src/controllers/FieldsController.php
index 98734cd1b2f..5d8f4faa554 100644
--- a/src/controllers/FieldsController.php
+++ b/src/controllers/FieldsController.php
@@ -36,14 +36,18 @@ class FieldsController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All field actions require an admin
         $this->requireAdmin();
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     // Groups
     // -------------------------------------------------------------------------
 
diff --git a/src/controllers/FsController.php b/src/controllers/FsController.php
index c3c5409c51b..c92e55481aa 100644
--- a/src/controllers/FsController.php
+++ b/src/controllers/FsController.php
@@ -31,14 +31,18 @@ class FsController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All asset volume actions require an admin
         $this->requireAdmin();
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Shows the filesystem list.
      *
diff --git a/src/controllers/GraphqlController.php b/src/controllers/GraphqlController.php
index ab77b12ed19..f2e93c18388 100644
--- a/src/controllers/GraphqlController.php
+++ b/src/controllers/GraphqlController.php
@@ -57,17 +57,21 @@ class GraphqlController extends Controller
     {
         if (!Craft::$app->getConfig()->getGeneral()->enableGql) {
             throw new NotFoundHttpException(Craft::t('yii', 'Page not found.'));
         }
 
-        Craft::$app->requireEdition(Craft::Pro);
-
         if ($action->id === 'api') {
             $this->enableCsrfValidation = false;
         }
 
-        return parent::beforeAction($action);
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
+        Craft::$app->requireEdition(Craft::Pro);
+
+        return true;
     }
 
     /**
      * Performs a GraphQL query.
      *
diff --git a/src/controllers/ImageTransformsController.php b/src/controllers/ImageTransformsController.php
index 450b8f2a5e6..45e581a61ae 100644
--- a/src/controllers/ImageTransformsController.php
+++ b/src/controllers/ImageTransformsController.php
@@ -29,14 +29,18 @@ class ImageTransformsController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All image transform actions require an admin
         $this->requireAdmin();
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Shows the image transform index.
      *
diff --git a/src/controllers/LivePreviewController.php b/src/controllers/LivePreviewController.php
index 935539192d9..59fb58bd74a 100644
--- a/src/controllers/LivePreviewController.php
+++ b/src/controllers/LivePreviewController.php
@@ -34,16 +34,20 @@ class LivePreviewController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // Mark this as a Live Preview request
         if ($action->id === 'preview') {
             $this->request->setIsLivePreview(true);
         }
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Creates a token for Live Preview requests.
      *
diff --git a/src/controllers/PluginStoreController.php b/src/controllers/PluginStoreController.php
index deab20e1811..bd674e5f903 100644
--- a/src/controllers/PluginStoreController.php
+++ b/src/controllers/PluginStoreController.php
@@ -33,14 +33,18 @@ class PluginStoreController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All plugin store actions require an admin
         $this->requireAdmin(false);
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Plugin Store index.
      *
diff --git a/src/controllers/PluginsController.php b/src/controllers/PluginsController.php
index 827a86f9af4..764d2bafa11 100644
--- a/src/controllers/PluginsController.php
+++ b/src/controllers/PluginsController.php
@@ -26,14 +26,18 @@ class PluginsController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All plugin actions require an admin
         $this->requireAdmin();
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Installs a plugin.
      *
diff --git a/src/controllers/RebrandController.php b/src/controllers/RebrandController.php
index a5b646cee39..6f2c259da1d 100644
--- a/src/controllers/RebrandController.php
+++ b/src/controllers/RebrandController.php
@@ -33,12 +33,17 @@ class RebrandController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         Craft::$app->requireEdition(Craft::Pro);
-        return parent::beforeAction($action);
+
+        return true;
     }
 
     /**
      * Handles control panel logo and site icon uploads.
      *
diff --git a/src/controllers/RoutesController.php b/src/controllers/RoutesController.php
index dd0a259bf50..38780ccfac7 100644
--- a/src/controllers/RoutesController.php
+++ b/src/controllers/RoutesController.php
@@ -24,14 +24,18 @@ class RoutesController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All route actions require an admin
         $this->requireAdmin();
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Saves a new or existing route.
      *
diff --git a/src/controllers/SectionsController.php b/src/controllers/SectionsController.php
index d1161f52861..b12a55c1b90 100644
--- a/src/controllers/SectionsController.php
+++ b/src/controllers/SectionsController.php
@@ -34,14 +34,18 @@ class SectionsController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All section actions require an admin
         $this->requireAdmin();
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Sections index.
      *
diff --git a/src/controllers/SitesController.php b/src/controllers/SitesController.php
index 2e726971845..057ed5f5300 100644
--- a/src/controllers/SitesController.php
+++ b/src/controllers/SitesController.php
@@ -34,14 +34,18 @@ class SitesController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All actions require an admin account
         $this->requireAdmin();
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Site settings index.
      *
diff --git a/src/controllers/StructuresController.php b/src/controllers/StructuresController.php
index d094d14861a..1c1b7ab57c8 100644
--- a/src/controllers/StructuresController.php
+++ b/src/controllers/StructuresController.php
@@ -39,10 +39,14 @@ class StructuresController extends Controller
      * @inheritdoc
      * @throws NotFoundHttpException if the requested element cannot be found
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         $this->requirePostRequest();
         $this->requireAcceptsJson();
 
         // This controller is only available to the control panel
         if (!$this->request->getIsCpRequest()) {
@@ -78,11 +82,11 @@ class StructuresController extends Controller
 
         if (!isset($this->_element)) {
             throw new NotFoundHttpException('Element not found');
         }
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Returns the descendant level delta for a given element.
      *
diff --git a/src/controllers/SystemMessagesController.php b/src/controllers/SystemMessagesController.php
index 6548e77f10f..17579924b82 100644
--- a/src/controllers/SystemMessagesController.php
+++ b/src/controllers/SystemMessagesController.php
@@ -25,16 +25,20 @@ class SystemMessagesController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         Craft::$app->requireEdition(Craft::Pro);
 
         // Make sure they have access to the System Messages utility
         $this->requirePermission('utility:system-messages');
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Returns the HTML for a system email message modal.
      *
diff --git a/src/controllers/SystemSettingsController.php b/src/controllers/SystemSettingsController.php
index 4cfc2b3aa01..6aa7446e883 100644
--- a/src/controllers/SystemSettingsController.php
+++ b/src/controllers/SystemSettingsController.php
@@ -38,14 +38,18 @@ class SystemSettingsController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All system setting actions require an admin
         $this->requireAdmin();
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Shows the general settings form.
      *
diff --git a/src/controllers/UserSettingsController.php b/src/controllers/UserSettingsController.php
index 3d8a6ad43c6..2e9bc827701 100644
--- a/src/controllers/UserSettingsController.php
+++ b/src/controllers/UserSettingsController.php
@@ -26,18 +26,22 @@ class UserSettingsController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All user settings actions require an admin
         $this->requireAdmin();
 
         if ($action->id !== 'save-user-settings') {
             Craft::$app->requireEdition(Craft::Pro);
         }
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Saves a user group.
      *
diff --git a/src/controllers/VolumesController.php b/src/controllers/VolumesController.php
index 87bab1a2891..ecdf7ceaf3c 100644
--- a/src/controllers/VolumesController.php
+++ b/src/controllers/VolumesController.php
@@ -33,14 +33,18 @@ class VolumesController extends Controller
     /**
      * @inheritdoc
      */
     public function beforeAction($action): bool
     {
+        if (!parent::beforeAction($action)) {
+            return false;
+        }
+
         // All asset volume actions require an admin
         $this->requireAdmin();
 
-        return parent::beforeAction($action);
+        return true;
     }
 
     /**
      * Shows the asset volume list.
      *

Vulnerable code:         return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        Craft::$app->requireEdition(Craft::Pro);

        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
        return parent::beforeAction($action);
Fixed code:         if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        $this->requireCpRequest();

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        Craft::$app->requireEdition(Craft::Pro);

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }


        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;
        if (!parent::beforeAction($action)) {
            return false;
        }

        return true;