CVE-2023-48217: Unrestricted Upload of File with Dangerous Type (CWE-434)
value: Statamic is a flat-first, Laravel + Git powered CMS designed for building websites. In affected versions certain additional PHP files crafted to look like images may be uploaded regardless of mime type validation rules. This affects front-end forms using the "Forms" feature, and asset upload fields in the control panel. Malicious users could leverage this vulnerability to upload and execute code. This issue has been patched in versions 3.4.14 and 4.34.0. Users are advised to upgrade. There are no known workarounds for this vulnerability.
CWE description: The product allows the upload or transfer of dangerous file types that are automatically processed within its environment.
CVSS v3 base score: 8.8
Published: 2023-11-14T22:15Z
Repository: https://github.com/statamic/cms
Language: PHP
Files changed: src/Http/Controllers/CP/Assets/AssetsController.php, src/Http/Controllers/CP/Fieldtypes/FilesFieldtypeController.php, src/Http/Controllers/FormController.php
Commit date: 2023-11-14 14:32:15 -0500
Commit message: [4.x] More php file validation (#8991)


Diff: diff --git a/src/Http/Controllers/CP/Assets/AssetsController.php b/src/Http/Controllers/CP/Assets/AssetsController.php
index 2a1d5f7854..14b51f62c6 100644
--- a/src/Http/Controllers/CP/Assets/AssetsController.php
+++ b/src/Http/Controllers/CP/Assets/AssetsController.php
@@ -67,11 +67,11 @@ class AssetsController extends CpController
     {
         $request->validate([
             'container' => 'required',
             'folder' => 'required',
             'file' => ['file', function ($attribute, $value, $fail) {
-                if (in_array(trim(strtolower($value->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'phtml'])) {
+                if (in_array(trim(strtolower($value->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'phar'])) {
                     $fail(__('validation.uploaded'));
                 }
             }],
         ]);
 
diff --git a/src/Http/Controllers/CP/Fieldtypes/FilesFieldtypeController.php b/src/Http/Controllers/CP/Fieldtypes/FilesFieldtypeController.php
index 44fec25302..4709f602da 100644
--- a/src/Http/Controllers/CP/Fieldtypes/FilesFieldtypeController.php
+++ b/src/Http/Controllers/CP/Fieldtypes/FilesFieldtypeController.php
@@ -10,11 +10,11 @@ class FilesFieldtypeController extends CpController
 {
     public function upload(Request $request)
     {
         $request->validate([
             'file' => ['file', function ($attribute, $value, $fail) {
-                if (in_array(trim(strtolower($value->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'phtml'])) {
+                if (in_array(trim(strtolower($value->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'phar'])) {
                     $fail(__('validation.uploaded'));
                 }
             }],
         ]);
 
diff --git a/src/Http/Controllers/FormController.php b/src/Http/Controllers/FormController.php
index 1fb0adc8e2..2f228ae254 100644
--- a/src/Http/Controllers/FormController.php
+++ b/src/Http/Controllers/FormController.php
@@ -176,11 +176,11 @@ class FormController extends Controller
             ->filter(function ($field) {
                 return $field->fieldtype()->handle() === 'assets';
             })
             ->mapWithKeys(function ($field) {
                 return [$field->handle().'.*' => ['file', function ($attribute, $value, $fail) {
-                    if (in_array(trim(strtolower($value->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'phtml'])) {
+                    if (in_array(trim(strtolower($value->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'phar'])) {
                         $fail(__('validation.uploaded'));
                     }
                 }]];
             })
             ->all();

Vulnerable code:                 if (in_array(trim(strtolower($value->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'phtml'])) {
                if (in_array(trim(strtolower($value->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'phtml'])) {
                    if (in_array(trim(strtolower($value->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'phtml'])) {
Fixed code:                 if (in_array(trim(strtolower($value->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'phar'])) {
                if (in_array(trim(strtolower($value->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'phar'])) {
                    if (in_array(trim(strtolower($value->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'phar'])) {