colinmollenhour / modman

Modularize extensions using symlinks. Voted #1 Magento tool by @WebShopApps!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Magento patch SUPEE-9767 and Symlinks setting

ehannes opened this issue · comments

A new Magento patch (SUPEE-9767 released yesterday, May 31 2017) suggests that you should disable Symlinks setting before applying the patch:

Before applying the patch or upgrading to the latest release, make sure to disable Symlinks setting [...] The setting, if enabled, will override configuration file setting and changing it will require direct database modification.

If you are managing modules by modman that use template files, these will not work as described in modman's README. I guess the reason for the suggestion of disabling Symlinks setting is the APPSEC-1281: Remote code execution through symlinks fix included in the patch.

How will this affect modman? If you need to have Symlinks setting enabled to use modman (if you do not want to patch Mage/Core/Block/Template.php as suggested in modman's README), this means your Magento shop is opened for at least one known security threat...

I'm running into the same issue. As a workaround I am using the --copy flag which seems to work so far.

I posted a question on Magento StackExchange concerning this issue.

Are there any downsides using --copy instead of symlinks (I'm not very experienced with modman yet)?

The only thing Magento did was to remove the system configuration in system.xml.
So the value is still there after installing 1.9.3.3 for example, but not visible in the backend.
The default value for the core_config_data entry is set to 0. You can review this in app/etc/config.xml.
The funny thing is that the code for checking if template symlinks are allowed is still there.
So you could update the database manually on fresh installations, or you could just restory the old system setting in a custom module, which is my solution for now.

For production use you can use the --copy flag. In development environment I would prefer symlinks.

@ThomasNegeli They probably removed the Symlinks setting for security reasons, for instance APPSEC-1281: Remote code execution through symlinks. Even though you can still enable the setting, the question is if you should. How dangerous is it to have it enabled?

@ehannes As stated by Piotr Kaminski in https://twitter.com/piotrekkaminski/status/870020878586617857 you will need admin access for this exploit to be a problem.
So in my opinion if any user can gain admin access, executing bad image code is your smallest problem ...

@ThomasNegeli If that is the case, then why does Magento bothers to remove the feature in the first place? Anyhow, the README for modman needs to be updated since the Symlinks setting is removed in Magento 1.9.3.3 and after the SUPEE-9767 patch.

I think the problem is that the original security fix was a bad one to begin with. The "Allow symlinks" option doesn't have anything to do with real symlinks, it just does a realpath comparison. I still after all of these years fail to see how simply allowing template files to be accessed via symlinks increases security risk, although I do see how using paths that reach outside of the Magento base path could be bad. If a malicious user can write a symlink then they can write a regular file as well. The real issue in my opinion (and I'd love for someone to explain to me if I'm wrong) is the risk of '..' being used in the template file paths. In this case rather than use realpath() you can simply use strpos($path, '..') to check for malicious paths. I tried to explain all of this years ago in Magento's bug tracker when they first added this mis-feature and was basically ignored and now it's coming back to bite everyone because their "fix" was optional and obviously a lot of people disable it. A good fix would both allow safe usage of symlinks and also not be optional.

So am I correct in the following analysis?

  • An orthodox application of SUPEE-9767 would inhibit use of Modman via symlinks.
  • Unorthodoxly, you could leave symlinks enabled, because the patch doesn't disable them, just hides the option to toggle them.
  • Modman could be used with --copy, but that goes against its philosophy and more importantly doesn't allow easy updates to installed modules in the future.

So it looks to me like I have the following choices:
a) Leave symlinks enabled, forgoing some of the protection of the patch, and creating a "concealed" config setting.
b) Stop using Modman, or at least give up on using it to perform updates.
c) Hope you (Colin Mollenhour) update Modman to circumvent this issue somehow.
d) Hack Template.php to accept [website root]/.modman alongside [website root]/app/design.

Unless (c) happens to have priority, all of these look like unhappy choices to me. I'm considering (d), but I'm not that experienced in Magento development yet and leery of core hacks unless absolutely necessary. However, a hack that actually simplifies long-term maintenance might be reasonable.

Supposing I did choose (d), would this be a reasonable approach?

try { $includeFilePath = realpath($this->_viewDir . DS . $fileName); if (strpos($includeFilePath, realpath($this->_viewDir)) === 0 || $this->_getAllowSymlinks()) { include $includeFilePath; }

Into

try { $includeFilePath = realpath($this->_viewDir . DS . $fileName); if (strpos($includeFilePath, realpath($this->_viewDir)) === 0 || $this->_getAllowSymlinks() || strpos($includeFilePath, realpath($this->getBaseDir('base') . DS . '.modman')) === 0) { include $includeFilePath; }

I would recommend (d). The README already contains a link to a patched version of Template.php (although it is old the revision history shows the changed lines which are only a few). The location of the .modman directory can be different for different installations due to the basedir option so that is something to keep in mind. In my opinion checking for '..' in the requested template path is safe already without checking the realpath because it would take file writing access to circumvent this and at that point the malicious code could just be written directly into a perfectly valid path.

Option (e): let Magento folks know that their fix is unacceptable and request a follow-up patch that isn't so wreckless. (don't hold your breath)
Option (f): jump onto the https://github.com/OpenMage/magento-lts bandwagon and watch for a suitable fix there.

Thanks! I went with the Template patch and it's working nicely.

If you're using a deployment tool to deploy your shop online (such as Deployer, Rocketeer, Capistrano, Deployhq, etc etc) setting the deploy strategy for Composer/Modman to copy instead of symlink should not introduce any problems.

For developing locally, using symlinks is nicer than copying them into the project. That's why we've added the magento-deploystrategy-dev to the Magento Composer Installer to facilitate this; Cotya/magento-composer-installer#163

commented

--copy works unproperly so if you installed module with --copy key that when you need to remove this module you use modman remove Module or modman remove --copy Module
and it removes only module in .modman dir, but doesn't installed copy of Module. So hope for the fast fixing this issue.

@devzorg - do a modman update --force which will replace the files with symlinks - then do modman remove which will remove them...

@colinmollenhour is/was there a PR at LTS for the patched version of Mage/Core/Block/Template.php?

The only thing Magento did was to remove the system configuration in system.xml.So the value is still there after installing 1.9.3.3 for example, but not visible in the backend.

Magentos update script for 1.9.3.4 removes this entry from DB and also added an config backend model that prevent changing/save this value from admin backend (if visible).

If you want to use symlink (on your own risk) you can use https://github.com/sreichel/magento-Sr-AllowSymlink. It just brings back admin config option ...

I just created a PR at Magento LTS project: OpenMage/magento-lts#442