magento2: Images can't be uploaded using WYSIWYG if media directory is a symlink

As of 2.2.3, it’s not possible to upload images via the WYSIWYG if the media directory is a symlink. This is due to this new file.

Preconditions

  1. Install Magento 2.2.3
  2. Ensure that the media directory is a symlink. For example, the pub/media directory should be a symlink that points somewhere else.

Steps to reproduce

  1. Edit a CMS Block and click “Insert Image”.
  2. Try to upload an image.

Expected result

  1. The image should upload successfully.

Actual result

  1. You’ll get an error like this:
    Directory /var/www/prod/releases/20180228212716/pub/media/wysiwyg is not under storage root path.
    
    magento admin-xazv0

Workaround

UPDATE: As of Magento 2.2.5 / 2.3.0, this issue has been fixed and you shouldn’t apply the patch below or else you’ll break the functionality.

We’ve temporarily fixed this by changing this line from this:

$realPath = realpath($path);
$root = $this->directoryList->getPath($directoryConfig);

to this (note the addition of the realpath function call):

$realPath = realpath($path);
// BEGIN EDIT
/**
 * Since media directory is a symlink, need to run both paths through realpath in order for the comparison to
 * work.
 * The proper fix for this should involve a STORE > Configuration setting where an admin can choose whether to
 * allow symlinked directories.
 */
$root = realpath($this->directoryList->getPath($directoryConfig));
// END EDIT

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 25
  • Comments: 44 (20 by maintainers)

Commits related to this issue

Most upvoted comments

Just ran into this issue, too. Here is the code I used to fix it (temporarily):

etc/di.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Framework\App\Filesystem\DirectoryResolver"
                type="\ModuleVendor\ModuleName\App\Filesystem\DirectoryResolver"/>
</config>

Override/App/Filesystem/DirectoryResolver.php

<?php
declare(strict_types=1);

/**
 * TODO: temporary override until patch or Magento 2.3 is released.
 * https://github.com/magento/magento2/issues/13929
 */
namespace ModuleVendor\ModuleName\Override\App\Filesystem;

use Magento\Framework\App\Filesystem\DirectoryList;

/**
 * Magento directories resolver.
 */
class DirectoryResolver
{
    /**
     * @var DirectoryList
     */
    private $directoryList;

    /**
     * @param DirectoryList $directoryList
     */
    public function __construct(DirectoryList $directoryList)
    {
        $this->directoryList = $directoryList;
    }

    /**
     * Validate path.
     *
     * Gets real path for directory provided in parameters and compares it with specified root directory.
     * Will return TRUE if real path of provided value contains root directory path and FALSE if not.
     * Throws the \Magento\Framework\Exception\FileSystemException in case when directory path is absent
     * in Directories configuration.
     *
     * @param string $path
     * @param string $directoryConfig
     * @return bool
     * @throws \Magento\Framework\Exception\FileSystemException
     */
    public function validatePath($path, $directoryConfig = DirectoryList::MEDIA)
    {
        $realPath = realpath($path);
        // BEGIN EDIT by @erikhansen
        /**
         * Since media directory is a symlink, need to run both paths through realpath in order for the comparison to
         * work.
         * The proper fix for this should involve a STORE > Configuration setting where an admin can choose whether to
         * allow symlinked directories.
         */
        $root = realpath($this->directoryList->getPath($directoryConfig));
        // END EDIT

        return strpos($realPath, $root) === 0;
    }
}

I solved with cweagans/composer-patches. I created a patch (for Magento Composer projects): name: 13929_2.2.3_directory_resolver_composer_v1.patch

Index: magento/vendor/magento/framework/App/Filesystem/DirectoryResolver.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- magento/vendor/magento/framework/App/Filesystem/DirectoryResolver.php	(date 1521531005000)
+++ magento/vendor/magento/framework/App/Filesystem/DirectoryResolver.php	(date 1521561205000)
@@ -39,7 +39,7 @@
     public function validatePath($path, $directoryConfig = DirectoryList::MEDIA)
     {
         $realPath = realpath($path);
-        $root = $this->directoryList->getPath($directoryConfig);
+        $root = realpath($this->directoryList->getPath($directoryConfig));
         
         return strpos($realPath, $root) === 0;
     }

Thank you, this is an important issue for us also. Is there a patch available for 2.2.3?

Fixed by increasing session size values (Configuration -> System -> Security).

Magento Commerce 2.4.3

image

I can confirm this behavior as well in 2.1.12. Can the backport also be considered for 2.1.x?

@clementblanco It’s fixed in 2.2.5.

Applying @osrecio patch:

1. Install composer-patches composer require cweagans/composer-patches

2. Save patch file patches/13929_2.2.3_directory_resolver_composer_v1.patch

--- /vendor/magento/framework/App/Filesystem/DirectoryResolver.php	2018-02-21 01:25:30.000000000 +0000
+++ /vendor/magento/framework/App/Filesystem/DirectoryResolver.php	2018-06-02 17:04:53.000000000 +0000
@@ -39,7 +39,7 @@
     public function validatePath($path, $directoryConfig = DirectoryList::MEDIA)
     {
         $realPath = realpath($path);
-        $root = $this->directoryList->getPath($directoryConfig);
+        $root = realpath($this->directoryList->getPath($directoryConfig));
         
         return strpos($realPath, $root) === 0;
     }

3. Modify composer.json

    "extra": {
        "magento-force": "override",
        "patches": {
            "magento/framework": {
                "Issue #13929: Images can't be uploaded using WYSIWYG if media directory is a symlink": "./patches/13929_2.2.3_directory_resolver_composer_v1.patch"
            }
        }
    }

4. Patch it! composer install

@andrewhowdencom - For the record, I much prefer to fix core issues like this using the cweagans/composer-patches approach that @osrecio mentioned above rather than using a preference. The reason for this is that if the underlying code changes in a future version of Magento (which is likely in this situation), the composer install will fail to complete which will alert you to the fact that the patch needs to be removed or changed to work with the latest code. This is assuming that you have the composer-exit-on-patch-failure option set to true.

@magento-engcom-team: can you point us to the commit where this is fixed in 2.3-develop? I have the feeling that we will run into the same problems due to the way how we deploy to the servers.

@marcelloinfoweb qual é o problema exato que você está enfrentando agora?

Error_delete-image Error_insert-image

message error in log: main.ERROR: Notice: Undefined index: force_static_path in /var/www/magento/vendor/magento/module-cms/Controller/Adminhtml/Wysiwyg/Images/OnInsert.php on line 57

Just tested this on 2.2-develop branch and it has been fixed there already. Tested this on 2.2.5 and it has been fixed there.

There is a commit for a reference: https://github.com/magento/magento2/commit/a6afb598e57ec11df51396ef2acadf4ec996da30

If someone still experience the issue, please provide more details

Hi, This problem occurs on Magento 2.3.4 as well.

1- File validation fails if upload an image 2- Sub folders shows an error as below.


Fatal error: Uncaught Error: Call to undefined function mime_content_type() in … /vendor/magento/module-cms/Model/Wysiwyg/Images/Storage.php on line 362

After testing on several PHP versions, I found that the problem is from PHP versions of 7.2 and 7.3. As it looks like working on PHP 7.1 and this is most probaly happening because of a one of required PHP extension is not enabled on the latest versions. I need to check what extension should be enabled/disabled on latest PHP versions.

Screenshot 2020-04-20 at 17 42 39

Issue is reproducible on 2.3-develop branch.

This presumably broke as part of the security patches (there’s a bunch of stuff associated with path disclosures and RCEs in the 2.2.3 release). Anyone got any idea why this change was made? (so we don’t set about reintroducing it with third party fixes)

@JosephMaxwell there’s a typo in namespace in etc/di.xml You should add \Override\

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Framework\App\Filesystem\DirectoryResolver"
                type="\ModuleVendor\ModuleName\Override\App\Filesystem\DirectoryResolver"/>
</config>