How to patch PROPERLY Magento Zend Framework XML-RPC security issue?

On July, 5th, 2012, an important security issue has been highlighted in Zend Framework, and so in Magento. This issue allows people to read almost any file on your webserver. A very dangerous issue, that’s why it must be patched quickly

Tell me, how can we patch it?

Oh nice, there is a patch available. I open it, and now, I have some red spots appearing on my body: they edited the embedded Zend Framework and Magento core sources…. Almost everybody agree that we do not edit the Magento sources files. Why do it there?

A common workaround about Magento overloading is the following one: use local to patch Magento and Zend Framework files. We’ll use this way to patch the XML-RPC issue instead of editing Magento sources files

The following script updatepath.sh init your Magento so it can patch this way. It works with the provided patch file for CE 1.5 to 1.7 Magento version

#!/bin/bash
##################################
# config
##################################
LOCAL_FOLDER="app/code/local";
RESPONSE_FILE="Zend/XmlRpc/Response.php";
RESPONSE="$LOCAL_FOLDER/$RESPONSE_FILE";
REQUEST_FILE="Zend/XmlRpc/Request.php";
REQUEST="$LOCAL_FOLDER/$REQUEST_FILE";
PATCH_FILE="CE_1.5.0.0-1.7.0.1.patch";
DESTINATION_PATCH_FILE="kyp_$PATCH_FILE";
###################################
# process
###################################
# check if patch file already exists
if [ ! -f $PATCH_FILE ]; then
    echo "Patch file $PATCH_FILE does not exists. Please download it at http://www.magentocommerce.com/blog/comments/important-security-update-zend-platform-vulnerability/";
    exit 2;
fi
# create local folder if not exists (eg: CE1.7 and related EE)
if [ ! -d $LOCAL_FOLDER ]; then
   echo "Init app/code/local folder";
   mkdir $LOCAL_FOLDER
fi
# create folder for Zend Framework Response file patch
if [ ! -d "$LOCAL_FOLDER/Zend/XmlRpc" ]; then
    echo "Creating Zend/XmlRpc local folder";
    mkdir -p "$LOCAL_FOLDER/Zend/XmlRpc";
fi
if [ -f $RESPONSE ]; then
    echo "File $RESPONSE already exists. Please append patch in";
    exit 1;
fi
echo "copying $RESPONSE_FILE in local folder";
cp lib/$RESPONSE_FILE $RESPONSE;

if [ -f $REQUEST ]; then
    echo "File $REQUEST already exists. Please append patch in";
    exit 1;
fi
echo "copying $REQUEST_FILE in local folder";
cp lib/$REQUEST_FILE $REQUEST;
# update patch file to replace lib by app/code/local
echo "Update patch file"
sed "s|lib/|app/code/local/|g" $PATCH_FILE > $DESTINATION_PATCH_FILE
echo "new patch file $DESTINATION_PATCH_FILE has been generated. You can now apply it with patch -p0 < $DESTINATION_PATCH_FILE"

This way, you are sure that your Magento will always be patched, even if you upgrade to a prior version than 1.7.0.2 CE (first release which embedded the patch)

The only way it won't work is if you load Response.php and Request.php files with a requirement to full path to lib folder, but this is not the Magento best practices

Don’t forget app/design/adminhtml/base/default folder when adding customs elements to Magento back-office

From the beginning of Magento until today (eg Community edition 1.7 and Enterprise Edition 1.12), Magento admin design folder has always been located in the app/design/adminhtml/default/default folder.

This folder contains all the required files to build adminhtml pages:

  • layouts to define adminhtml pages structure
  • templates used by theses layouts

So, If you need to provide specific back-office interfaces, where will you put them? in this app/design/adminhtml/default/default folder?

Magento page structure loading file API

Adminhtml is managed like the same loading API used in the front office; this API has been reviewed in Magento CE 14 and related Enterprises editions to load content in the following order:

  • Custom package / Custom theme folder
  • Custom package / default theme folder
  • Base package / default theme folder

I have previously explained the aim of this rule and what you can do with it

But the question is: adminhtml default default folder is: base package or custom package?

app/design/admintml/base/default as a default package folder

Yes it is. The folder app/design/admintml/default/default is not a default one, but the the default theme for the adminhtml default package; folder app/design/admintml/base/default can also exists even if it’s not embedded with magento sources.

So for sure, this is not an error to enhance this default package, but it does not respect the role of this loading api.

So it could be interesting to use app/design/adminhtml/base/default as folder for your new back-office interfaces

Conclusion

app/design/adminhtml/base/default folder does not exist in Magento sources but you can create it as you wish.
In a dream world, back-office updates should be managed as this:

  • Move app/design/adminhtml/default/default folder to app/design/adminhtml/base/default folder: we ensure this way that we have the default magento design for back-office
  • Use a custom package for the back-office updates of the existing interfaces
  • Provide new back-office interfaces in the adminhtml/base/default folder

Do you have already created the app/design/adminhtml/base/default folder for your own back-office interfaces or you do not take care of this case?

Magento tutorial: how to overload a Varien class?

If you have read my previous post about Magento overloading mechanism, you’ll see that there is two existing mechanisms to overload classes in Magento

But these two mechanisms are only available for classes which are instantiated.

Many of Varien classes are not loaded directly through a new. So how we can overload them?

If class is only used when using extends, we have only one way to overload it’s content: the passive overload

This mechanism is based upon the auto-loading mechanism embedded with Magento

  • Loading first from app/code/local folder
  • Then first look for classes in app/code/community
  • If always not found, look for the app/code/core folder
  • Always not found? look for lib folder

The only way you can use to overload a Varien class is to use this mechanism to provide your own functionalities by copying Varien class in app/code/community or app/code/local folder (we do not touch at the app/code/core)

By using this method, this is your class which will be loaded, instead of Varien one