CVE-2023-30855 (JavaScript, published 2023-05-08T18:15Z)
Description: value: Pimcore is an open source data and experience management platform. Versions of Pimcore prior to 10.5.18 are vulnerable to path traversal. The impact of this path traversal and arbitrary extension is limited to creation of arbitrary files and appending data to existing files. When combined with the SQL Injection, the exported data `RESTRICTED DIFFUSION 9 / 9` can be controlled and a webshell can be uploaded. Attackers can use that to execute arbitrary PHP code on the server with the permissions of the webserver. Users may upgrade to version 10.5.18 to receive a patch or, as a workaround, apply the patch manually.
Severity: nan (CVSS v3 base score: 7.5)
Weakness: CWE-22 \u2014 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
Repository: https://github.com/pimcore/pimcore
Files changed:
bundles/AdminBundle/Controller/Admin/DataObject/ClassificationstoreController.php
bundles/AdminBundle/Resources/public/js/pimcore/helpers.js
bundles/AdminBundle/Resources/public/js/pimcore/object/classificationstore/collectionsPanel.js
bundles/AdminBundle/Resources/public/js/pimcore/object/classificationstore/groupsPanel.js
bundles/AdminBundle/Resources/public/js/pimcore/object/classificationstore/propertiesPanel.js
lib/Security/SecurityHelper.php
Commit message: [Security] XSS in Classification Store of Data Objects module (#14933)

* Fix: xss in CS

* Fix: implement feedback

Vulnerable code:
        $name = $request->get('name');
        $name = $request->get('name');
        $name = $request->get('name');
                        Ext.Msg.confirm(t('delete'), sprintf(t('delete_message_advanced'), t('classificationstore_collection_relation'), data.data.groupName), function(btn) {
                        Ext.Msg.confirm(t('delete'), sprintf(t('delete_message_advanced'), t('classificationstore_collection'), data.data.name), function(btn) {

        value = value.trim();
                        Ext.Msg.confirm(t('delete'), sprintf(t('delete_message_advanced'), t('classificationstore_relation'), data.data.keyName), function(btn) {
                        Ext.Msg.confirm(t('delete'), sprintf(t('delete_message_advanced'), t('classificationstore_group'), data.data.name), function(btn) {

        value = value.trim();
                        Ext.Msg.confirm(t('delete'), sprintf(t('delete_message_advanced'), t('classificationstore_property'), data.data.name), function(btn) {

        value = value.trim();

Fixed code:
use Pimcore\Security\SecurityHelper;
        $name = SecurityHelper::getStringWithoutControlChars($request->get('name'));
        $name = SecurityHelper::getStringWithoutControlChars($request->get('name'));
        $name = SecurityHelper::getStringWithoutControlChars($request->get('name'));

pimcore.helpers.getStringWithoutControlChars = function (text) {
    return text.replace(/[<>"'`!?/\\%$(){};,:|=]/gi, '');
};
                        Ext.Msg.confirm(t('delete'), sprintf(t('delete_message_advanced'), t('classificationstore_collection_relation'), pimcore.helpers.getStringWithoutControlChars(data.data.groupName)), function(btn) {
                        Ext.Msg.confirm(t('delete'), sprintf(t('delete_message_advanced'), t('classificationstore_collection'), pimcore.helpers.getStringWithoutControlChars(data.data.name)), function(btn) {
        value = pimcore.helpers.getStringWithoutControlChars(value).trim();
                        Ext.Msg.confirm(t('delete'), sprintf(t('delete_message_advanced'), t('classificationstore_relation'), pimcore.helpers.getStringWithoutControlChars(data.data.keyName)), function(btn) {
                        Ext.Msg.confirm(t('delete'), sprintf(t('delete_message_advanced'), t('classificationstore_group'), pimcore.helpers.getStringWithoutControlChars(data.data.name)), function(btn) {
        value = pimcore.helpers.getStringWithoutControlChars(value).trim();
                        Ext.Msg.confirm(t('delete'), sprintf(t('delete_message_advanced'), t('classificationstore_property'), pimcore.helpers.getStringWithoutControlChars(data.data.name)), function(btn) {
        value = pimcore.helpers.getStringWithoutControlChars(value).trim();
<?php

/**
 * Pimcore
 *
 * This source file is available under two different licenses:
 * - GNU General Public License version 3 (GPLv3)
 * - Pimcore Commercial License (PCL)
 * Full copyright and license information is available in
 * LICENSE.md which is distributed with this source code.
 *
 *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
 *  @license    http://www.pimcore.org/license     GPLv3 and PCL
 */

namespace Pimcore\Security;

class SecurityHelper
{
    public static function getStringWithoutControlChars(string $text): string
    {
        return preg_replace('[\\\\<>"\'`!?/%$(){};,:|=]','', $text);
    }
}