CVE-2023-47636 (PHP, published 2023-11-15T20:15Z)
Description: value: The Pimcore Admin Classic Bundle provides a Backend UI for Pimcore. Full Path Disclosure (FPD) vulnerabilities enable the attacker to see the path to the webroot/file. e.g.: /home/omg/htdocs/file/. Certain vulnerabilities, such as using the load_file() (within a SQL Injection) query to view the page source, require the attacker to have the full path to the file they wish to view. In the case of pimcore, the fopen() function here doesn't have an error handle when the file doesn't exist on the server so the server response raises the full path "fopen(/var/www/html/var/tmp/export-{ uniqe id}.csv)". This issue has been patched in commit `10d178ef771` which has been included in release version 1.2.1. Users are advised to upgrade. There are no known workarounds for this vulnerability.

Severity: nan (CVSS v3 base score: 5.3)
Weakness: CWE-209 \u2014 Generation of Error Message Containing Sensitive Information
The product generates an error message that includes sensitive information about its environment, users, or associated data.
Repository: https://github.com/pimcore/admin-ui-classic-bundle
Files changed:
src/Controller/Admin/Asset/AssetHelperController.php
src/Controller/Admin/DataObject/DataObjectHelperController.php
Commit message: Grid Export - Catch unable to read file exception (#342)

* [DataObject] Grid Export - Catch unable to read file exception
* [Asset] Grid Export - Catch unable to read file exception

Vulnerable code:
use Pimcore\Localization\LocaleServiceInterface;
     * @param Request $request
     * @param LocaleServiceInterface $localeService
     *
     * @return JsonResponse
    public function doExportAction(Request $request, LocaleServiceInterface $localeService): JsonResponse
        $fileHandle = \Pimcore\File::getValidFilename($request->get('fileHandle'));
        $settings = $request->get('settings');
        $settings = json_decode($settings, true);
        $storage = Storage::get('temp');
        $csvFile = $this->getCsvFile($fileHandle);
        $fileStream = $storage->readStream($csvFile);
        $temp = tmpfile();
        stream_copy_to_stream($fileStream, $temp, null, 0);
        $firstLine = true;
        foreach ($csv as $line) {
            if ($addTitles && $firstLine) {
                $firstLine = false;
                $line = implode($delimiter, $line) . "\r\n";
                fwrite($temp, $line);
            } else {
                fwrite($temp, implode($delimiter, array_map([$this, 'encodeFunc'], $line)) . "\r\n");
        $storage->writeStream($csvFile, $temp);

        $fileHandle = \Pimcore\File::getValidFilename($request->get('fileHandle'));
        $fileHandle = \Pimcore\File::getValidFilename($request->get('fileHandle'));
     * @param Request $request
     * @param LocaleServiceInterface $localeService
     * @param EventDispatcherInterface $eventDispatcher
     *
     * @return JsonResponse
     *
     * @throws \Exception
    public function doExportAction(Request $request, LocaleServiceInterface $localeService, EventDispatcherInterface $eventDispatcher): JsonResponse
        $fileHandle = \Pimcore\File::getValidFilename($request->get('fileHandle'));
        $settings = $request->get('settings');
        $settings = json_decode($settings, true);
            throw new \Exception('No class definition found');
        /** @var \Pimcore\Model\DataObject\Listing $list */
        $contextFromRequest = $request->get('context');
        if ($contextFromRequest) {
            $contextFromRequest = json_decode($contextFromRequest, true);
        }

        if (is_array($contextFromRequest)) {
        $csv = DataObject\Service::getCsvData($requestedLanguage, $localeService, $list, $fields, $header, $addTitles, $context);
        $storage = Storage::get('temp');
        $csvFile = $this->getCsvFile($fileHandle);

        $fileStream = $storage->readStream($csvFile);

        $temp = tmpfile();
        stream_copy_to_stream($fileStream, $temp, null, 0);

        $firstLine = true;
        if ($request->get('initial') && $header === 'no_header') {
            array_shift($csv);
            $firstLine = false;
        }
        $lineCount = count($csv);
        if (!$addTitles && $lineCount > 0) {
            fwrite($temp, "\r\n");
        }
        for ($i = 0; $i < $lineCount; $i++) {
            $line = $csv[$i];
            if ($addTitles && $firstLine) {
                $line = implode($delimiter, $line);
                fwrite($temp, $line);
            } else {
                fwrite($temp, implode($delimiter, array_map([$this, 'encodeFunc'], $line)));
            if ($i < $lineCount - 1) {
        $storage->writeStream($csvFile, $temp);
        $fileHandle = \Pimcore\File::getValidFilename($request->get('fileHandle'));
        $fileHandle = \Pimcore\File::getValidFilename($request->get('fileHandle'));

Fixed code:
use Pimcore\File;
     * @throws FilesystemException
    public function doExportAction(Request $request): JsonResponse
        $fileHandle = File::getValidFilename($request->get('fileHandle'));
        $settings = json_decode($request->get('settings'), true);
        try {
            $storage = Storage::get('temp');
            $csvFile = $this->getCsvFile($fileHandle);
            $fileStream = $storage->readStream($csvFile);
            $temp = tmpfile();
            stream_copy_to_stream($fileStream, $temp, null, 0);
            $firstLine = true;
            foreach ($csv as $line) {
                if ($addTitles && $firstLine) {
                    $firstLine = false;
                    $line = implode($delimiter, $line) . "\r\n";
                    fwrite($temp, $line);
                } else {
                    fwrite($temp, implode($delimiter, array_map([$this, 'encodeFunc'], $line)) . "\r\n");
                }
            $storage->writeStream($csvFile, $temp);
        } catch (UnableToReadFile $exception) {
            Logger::err($exception->getMessage());

            return $this->adminJson(
                [
                    'success' => false,
                    'message' => sprintf('export file not found: %s', $fileHandle)
                ]
            );
        $fileHandle = File::getValidFilename($request->get('fileHandle'));
        $fileHandle = File::getValidFilename($request->get('fileHandle'));
use Pimcore\File;
use Pimcore\Model\DataObject\Listing;
     * @throws \Exception|FilesystemException
    public function doExportAction(
        Request $request,
        LocaleServiceInterface $localeService,
        EventDispatcherInterface $eventDispatcher
    ): JsonResponse
        $fileHandle = File::getValidFilename($request->get('fileHandle'));
        $settings = json_decode($request->get('settings'), true);
            throw new \InvalidArgumentException('No class definition found');
        /** @var Listing $list */
        $contextFromRequest = $request->get('context');
        if ($contextFromRequest) {
            $contextFromRequest = json_decode($contextFromRequest, true);
        $csv = DataObject\Service::getCsvData(
            $requestedLanguage,
            $localeService,
            $list,
            $fields,
            $header,
            $addTitles,
            $context
        );
        try {
            $storage = Storage::get('temp');
            $csvFile = $this->getCsvFile($fileHandle);
            $fileStream = $storage->readStream($csvFile);
            $temp = tmpfile();
            stream_copy_to_stream($fileStream, $temp, null, 0);
            $firstLine = true;
            if ($request->get('initial') && $header === 'no_header') {
                array_shift($csv);

            $lineCount = count($csv);

            if (!$addTitles && $lineCount > 0) {

            for ($i = 0; $i < $lineCount; $i++) {
                $line = $csv[$i];
                if ($addTitles && $firstLine) {
                    $firstLine = false;
                    $line = implode($delimiter, $line);
                    fwrite($temp, $line);
                } else {
                    fwrite($temp, implode($delimiter, array_map([$this, 'encodeFunc'], $line)));
                }
                if ($i < $lineCount - 1) {
                    fwrite($temp, "\r\n");
                }
            }
            $storage->writeStream($csvFile, $temp);
        } catch (UnableToReadFile $exception) {
            Logger::err($exception->getMessage());

            return $this->adminJson(
                [
                    'success' => false,
                    'message' => sprintf('export file not found: %s', $fileHandle)
                ]
            );
        $fileHandle = File::getValidFilename($request->get('fileHandle'));
        $fileHandle = File::getValidFilename($request->get('fileHandle'));