CVE-2021-32717 (PHP, published 2021-06-24T21:15Z)
Description: value: Shopware is an open source eCommerce platform. In versions prior to 6.4.1.1 private files publicly accessible with Cloud Storage providers when the hashed URL is known. Users are recommend to first change their configuration to set the correct visibility according to the documentation. The visibility must be at the same level as `type`. When the Storage is saved on Amazon AWS we recommending disabling public access to the bucket containing the private files: https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html. Otherwise, update to Shopware 6.4.1.1 or install or update the Security plugin (https://store.shopware.com/en/detail/index/sArticle/518463/number/Swag136939272659) and run the command `./bin/console s3:set-visibility` to correct your cloud file visibilities.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-732 \u2014 Incorrect Permission Assignment for Critical Resource
The product specifies permissions for a security-critical resource in a way that allows that resource to be read or modified by unintended actors.
Repository: https://github.com/shopware/platform
Files changed:
changelog/_unreleased/2021-05-10-fix-visibility-setting-in-s3-storage-fs.md
src/Core/Framework/Adapter/Command/S3FilesystemVisibilityCommand.php
src/Core/Framework/Adapter/Filesystem/FilesystemFactory.php
src/Core/Framework/DependencyInjection/services.xml
Commit message: NEXT-14744 - fix visibility setting in s3 storage fs


Vulnerable code:

Fixed code:
---
title: fix visibility setting in s3 storage fs
issue: NEXT-14744
author: d.neustadt
author_email: d.neustadt@shopware.com 
author_github: dneustadt
---
# Core
* Changed setting of visibility from fallback config to nested `options` parameter as per documentation
* Added `s3:set-visibility` CLI command for retroactively setting visibility of already stored objects
<?php declare(strict_types=1);

namespace Shopware\Core\Framework\Adapter\Command;

use League\Flysystem\FilesystemInterface;
use Shopware\Core\Framework\Adapter\Console\ShopwareStyle;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class S3FilesystemVisibilityCommand extends Command
{
    protected static $defaultName = 's3:set-visibility';

    /**
     * @var FilesystemInterface
     */
    private $filesystemPrivate;

    /**
     * @var FilesystemInterface
     */
    private $filesystemPublic;

    /**
     * @var FilesystemInterface
     */
    private $filesystemTheme;

    /**
     * @var FilesystemInterface
     */
    private $filesystemSitemap;

    /**
     * @var FilesystemInterface
     */
    private $filesystemAsset;

    public function __construct(
        FilesystemInterface $filesystemPrivate,
        FilesystemInterface $filesystemPublic,
        FilesystemInterface $filesystemTheme,
        FilesystemInterface $filesystemSitemap,
        FilesystemInterface $filesystemAsset
    ) {
        parent::__construct();
        $this->filesystemPrivate = $filesystemPrivate;
        $this->filesystemPublic = $filesystemPublic;
        $this->filesystemTheme = $filesystemTheme;
        $this->filesystemSitemap = $filesystemSitemap;
        $this->filesystemAsset = $filesystemAsset;
    }

    /**
     * {@inheritdoc}
     */
    protected function configure(): void
    {
        $this
            ->setDescription('Sets visibility for all objects in corresponding bucket of S3 storage.');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $style = new ShopwareStyle($input, $output);

        $style->warning('If both private and public objects are stored in the same bucket, this command will set all of them public.');
        $continue = $style->confirm('Continue?');

        if (!$continue) {
            return 0;
        }

        $style->comment('Setting visibility to private in private bucket.');
        $this->setVisibility($this->filesystemPrivate, $style, 'private');
        $style->comment('Setting visibility to public in public bucket.');
        $this->setVisibility($this->filesystemPublic, $style, 'public');
        $style->comment('Setting visibility to public in theme bucket.');
        $this->setVisibility($this->filesystemTheme, $style, 'public');
        $style->comment('Setting visibility to public in sitemap bucket.');
        $this->setVisibility($this->filesystemSitemap, $style, 'public');
        $style->comment('Setting visibility to public in asset bucket.');
        $this->setVisibility($this->filesystemAsset, $style, 'public');

        $style->info('Finished setting visibility of objects in all pre-defined buckets.');

        return 0;
    }

    private function setVisibility(FilesystemInterface $filesystem, ShopwareStyle $style, string $visibility): void
    {
        $files = array_filter($filesystem->listContents('/', true), function (array $object): bool {
            return $object['type'] === 'file';
        });
        ProgressBar::setFormatDefinition('custom', '[%bar%] %current%/%max% -- %message%');
        $progressBar = new ProgressBar($style, \count($files));
        $progressBar->setFormat('custom');

        foreach ($files as $file) {
            if ($file['type'] === 'file') {
                $filesystem->setVisibility($file['path'], $visibility);

                $progressBar->advance();
                $progressBar->setMessage($file['path']);
            }
        }

        $progressBar->finish();
    }
}
        if (isset($config['config']['options']['visibility'])) {
            $config['visibility'] = $config['config']['options']['visibility'];
        }

        <service id="Shopware\Core\Framework\Adapter\Command\S3FilesystemVisibilityCommand">
            <argument type="service" id="shopware.filesystem.private"/>
            <argument type="service" id="shopware.filesystem.public"/>
            <argument type="service" id="shopware.filesystem.theme"/>
            <argument type="service" id="shopware.filesystem.sitemap"/>
            <argument type="service" id="shopware.filesystem.asset"/>
            <tag name="console.command"/>
        </service>