APPSEC-1281 and Dangerous Symlinks?
With the release of SUPEE-9767 there seems a lot of confusion around APPSEC-1281 and how and/or why symlinks are dangerous or being exploited. I’m going to try and add some clarification (or you know, muddy the waters even more if I’m wrong).
What’s the Exploit
As far as I’m aware, symlinks in themselves are not the problem and are not dangerous. The exploit is the ability to include arbitrary files from the server as a template for a block. Magento mitigates this by checking the path of the template and ensuring it’s inside the view directory. Since nobody on the server should have write permission to the views directory, this makes a whole lot of sense. The problem is that the check is performed using PHPs realpath
function, which will resolve the symlink, meaning it’s not inside the directory. To get around this they added the “Allow Symlinks” option which completely disables the check.
What Does the Patch Change
They have removed the config option from the admin panel (but not the usage of the config option in the code), meaning a malicious actor that manages to brute force an admin account will no longer be able to enable it. They also added a block to the admin panel warning you if the value of the config is set to 1. Well, there’s supposed to be a warning at least. In the patch I downloaded for 1.9.2.x, the layout file is wrong and the block is outside the text_list container, meaning it isn’t actually rendered anywhere. If the config option is not set to 0, there is still no protection.
What the Patch Should Have Done
In my opinion, what the patch should have done is changed how the path was validated. We care whether the file being included is inside the view directory since nobody should be able to write to this directory, whether or not that file symlinks out to a different location shouldn’t matter. So if we just compare the path without using realpath
, to avoid the symlink getting resolved, we’re good to go? The problem with this is it’s still possible to perform a directory traversal attack, by including ‘/../’ in the template path. We, therefore, need to ensure we add protections against this. Magento actually already do this in other places in the code, I’m not sure why they don’t here. Perhaps for performance reasons.
But I’m Using modman
If you’re using modman you either need to have this value set to 1 or hack the core to change the way the Template block performs the check. The patch won’t break your installation, everything will continue to function, it’s just that there is no mitigation of the exploit. Therefore if somebody manages to gain access to your admin panel, they can perform a malicious include to achieve RCE.
If you don’t like being left in that situation you only really have two options. 1). Change your deployment pipeline so the modman files are copied rather than symlinked. 2). Edit the core and modify how the check works. The README for modman actually includes a link to an example of doing this, it’s probably not a perfect solution for all environments but it’s pretty solid for most.