CVE-2023-2339 (PHP, published 2023-04-27T12:15Z)
Description: value: Cross-site Scripting (XSS) - Reflected in GitHub repository pimcore/pimcore prior to 10.5.21.
Severity: nan (CVSS v3 base score: 5.4)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/pimcore/pimcore
Files changed:
bundles/AdminBundle/Controller/Admin/Asset/AssetHelperController.php
bundles/AdminBundle/Controller/Admin/DataObject/DataObjectHelperController.php
bundles/AdminBundle/Resources/public/js/pimcore/object/gridcolumn/operator/AnyGetter.js
bundles/AdminBundle/Resources/public/js/pimcore/settings/metadata/predefined.js
lib/DataObject/GridColumnConfig/Operator/AbstractOperator.php
lib/DataObject/GridColumnConfig/Operator/AnyGetter.php
lib/Security/SecurityHelper.php
Commit message: [Security] Stored cross site scripting vulnerability in operator any getter in pimcore grid configuration (#14984)

* Fix: xss in anyGetter

* Fix: xss for predefined asset metadata

Vulnerable code:
                    'title' => $item->getName(),
                    'name' => $item->getName(),
                value: this.node.data.configAttributes.label
                value: this.node.data.configAttributes.attribute
                value: this.node.data.configAttributes.param1
            });
                nodeLabel += '<span class="pimcore_gridnode_hint"> (' + attr + ')</span>';
                getEditor: function() { return new Ext.form.TextField({}); }
        $this->label = $config->label;
        $this->label = $label;
        $this->attribute = $config->attribute ?? '';
        $this->param1 = $config->param1 ?? '';
        $this->attribute = $attribute;
        $this->param1 = $param1;

Fixed code:
use Pimcore\Security\SecurityHelper;
                $name = SecurityHelper::convertHtmlSpecialChars($item->getName());
                    'title' => $name,
                    'name' => $name,
use Pimcore\Security\SecurityHelper;

                foreach($gridConfig['columns'] as &$column) {
                    if (array_key_exists('isOperator', $column) && $column['isOperator']) {
                        $colAttributes = &$column['fieldConfig']['attributes'];
                        SecurityHelper::convertHtmlSpecialCharsArrayKeys($colAttributes, ['label', 'attribute', 'param1']);
                    }
                }
                value: this.node.data.configAttributes.label,
                listeners: {'change': pimcore.helpers.htmlEncodeTextField }
                value: this.node.data.configAttributes.attribute,
                listeners: {'change': pimcore.helpers.htmlEncodeTextField }
                value: this.node.data.configAttributes.param1,
                listeners: {'change': pimcore.helpers.htmlEncodeTextField }
        });
                nodeLabel += '<span class="pimcore_gridnode_hint"> (' + Ext.util.Format.htmlEncode(attr) + ')</span>';
                getEditor: function() { return new Ext.form.TextField({ listeners: {'change': pimcore.helpers.htmlEncodeTextField } }); }
use Pimcore\Security\SecurityHelper;
        $this->label = SecurityHelper::convertHtmlSpecialChars($config->label);
        $this->label = SecurityHelper::convertHtmlSpecialChars($label);
use Pimcore\Security\SecurityHelper;
        $this->attribute = SecurityHelper::convertHtmlSpecialChars($config->attribute ?? '');
        $this->param1 = SecurityHelper::convertHtmlSpecialChars($config->param1 ?? '');
        $this->attribute = SecurityHelper::convertHtmlSpecialChars($attribute);
        $this->param1 = SecurityHelper::convertHtmlSpecialChars($param1);

    public static function convertHtmlSpecialCharsArrayKeys(array &$array, array $keys): void
    {
        foreach ($keys as $key) {
            if (array_key_exists($key, $array)) {
                $array[$key] = self::convertHtmlSpecialChars($array[$key]);
            }
        }
    }