Magento tips: Display a Magento category path in SQL

Yes, it’s been quite a long time I’ve not been sharing something with you: many projects to handle and no time to share something. And when we are busy, it’s a bit disappointing to see how many time we may lost to do some repetitive tasks

One of these tasks, when you study a Magento sales catalog, is to find in which categories is published a product Continue reading “Magento tips: Display a Magento category path in SQL”

how to solve Magento message “Your web server is configured incorrectly. As a result, configuration files with sensitive information are accessible from the outside. Please contact your hosting provider.”

If you have this message when you are logged in your back-office, it’s because there is a misconfiguration in your Magento host. There are multiple reasons to have this message, and multiple ways to fix it

Why do I have this message displayed?

Since 1.4.2 version, back-office check from back-office if file app/etc/local.xml can be read through a browser (If the response code is a Apache 200 response code; This control is made by a CURL request on your unsecure_base_url/app/etc/local.xml URI) It’s very important not to be able to read this file from a webbrowser, because it contains your database parameters, cache and session configuration.

All files and folders in app folder are protected by a .htaccess file which denies access from everyone since it browses your Magento directory tree starting from the app folder:

Order deny,allow
Deny from all

this directive is applied starting from .htaccess path and covers also subfolders, and so, local.xml file

Origins of the problem

.htaccess usage can be disturbed for three major reasons:

htaccess file doesn’t exist

For sure, if htaccess file does not exist, there is no restriction on who can read the local.xml file, and so, the security warning is displayed

htaccess files are not the access filename

By default in Apache configuration, the AccessFilename is set to .htaccess. It can be updated with the AccessFilename directive in webserver or virtual host configurations files.

So if value has been updated, .htaccess will not be read, and so ACL is not used

But if this is your study case, you should have more complex problems with your Magento 🙂

Cannot override the directories acccess control list

Apache configuration allows also to define which rules can be overrided in AccessFilename with AllowOverride directive

If you are a hosting provider, perhaps you don’t want that your clients can update in their AccessFilename some security directives. It can be done with the AllowOverride directive

Have a look at the official documentation to see the possible values for this directive

In this case, if AllowOverride directive is not well set, the .htaccess file is read, but the ACL defined is not used, and so, we can have access to your local.xml file

Because this directive is applied only to <Directory;> instruction, you must be able to edit the vhost configuration file to fix this issue. Ask your hosting provider if you cannot

Specifics rewriting rules

For one client, we encounter this case: we have updated some elements of the Magento directory tree and define some specific rewriting rules. local.xml file was not available, but CURL test receive a 200 error code because of a rewriting rule.

In this case, this is the test which is involved, not your security policy

Conclusion

Configuration is checked on the app/etc/local.xml file, but other sensibles informations can be fetch from your app directory

It’s a shame that everybody doesn’t take care of this security issue. Take a look at the google results, you’ll be surprised

If your configuration is well set, when you request the app/etc/local.xml file on your Magento, you should have the following error displayed

Magento Overloading mecanisms

Magento is a really rich software application. However, its management rules may be diffrent from your own management.
Varien, Magento’s editor, forecasted this case and offers 2 overloading methods of its native working to allow you to adapt the solution to your specificities.

One of these mechanism is a passive overloading, whether the other needs your intervention.

Passive overloading

This overloading mechanism is closely related to Magentos’s autoload management.

Source code organization in Magento & Autoload

Reminder of source code organization in Magento

For recall, autoload is a mechanism born with PHP5 which embeds a dynamic class loader manager.
That is to say, if a class was never loaded, it’s the __autoload method which will search and find in which source if the required class exists. This method may be redefined to adapt your needs.

Magento’s source code is organized according to four repositories

  • Libraries. That’s where you will find, in particular, the Zend Framework which is a referencial for librairies in Magento
  • Magento’s core. It’s in the folder app/code/core
  • Community enrichment. They’re in the folder app/code/community
  • Local enrichment. They’re in the folder app/code/local


So these four folders are : lib, app/code/core, app/code/community, app/code/local

Magento defines its own autoloader in the Autoload class, located in the folder lib/Varien.

This autoloader will first look for classes in app/code/local, and then if it doesn’t find them, in app/code/community, and lastly in app/code/core if it still hasn’t found the right file. After all, if the file is still not found, it will be searched in the libs.

Working of passive overloading in Magento

Everything bases on this autoloader’s working : it’s therefore possible, by acting on the autoload priorities, to make a preferential choice about a local adaptation (which would be in app/code/local), rather than the native file which is in app/code/core.

This requires however that the local adaptation contains fully all the methods that are in the overloaded class.

An example of this kind of overloading is the file app/code/core/Zend/Mime.php which is used instead of the file lib/Zend/Mime.php.

Active overloading

This overloading mechanism is related to instanciation mechanism used in Magento.

Instanciation mechanism in Magento

For recall, Magento uses three generic methods to load its classes :

Mage::getModel() (and Mage::getSingleton)
Mage::getBlockSingleton
Mage::helper()

These methods will be in charge of determining the name of the class to be loaded.

What happens in case of two active overloading of the same class ?

Magento’s rules manager is confused and doesn’t know which class it has to load anymore. In this case you will surely note stange behaviours.

It’s then higly recommanded that you never fall in this case, and be therefore most carefull when you install modules from the community which might already overload the same objects as you.

Which overloading mechanism choose ?

It depends on what you wish to implement, and also on the type of class you wish to overload. Abstract classes for example cannot be overloaded with the active overloading mechanism, because they don’t have a real instanciation. To overload them, you have to choose passive overloading. With active overloading you don’t have to rewrite the full content of the overloaded class, unlike in the passive overloading case.
You also will have less compelling maintenance of your source code referring to this overloading concerning Magento upgrades.

This loading mechanism break also a common bias we can heard: “community folder is only for sources code coming from magento connect”. In this case, if we put our own development only in local folder, we avoid usage of passive overload. is it really the thing you wants?

Unix permissions policies on Magento

Recently, Prestashop has been attacked by a worm: this worm uploaded on the server was able to update the content of a template; this template load many iframe which make you request some unexpected things. Many users have been infected. According to the first feedback, it seems that a good unix permissions policy on Prestashop folder could have stopped this infection.

Magento‘s hosted on unix servers seem to have the same problem: even if there is – for the moment – no problem like Prestashop’s one, most of the plateforms I saw have unix permissions policy problems, and so provide attack facilities. This is the reason why I wrote this article.

Unix permissions resume

First remember the basic of unix permissions: For files and folders, they define if:

  • You can read a file / folder
  • You can write or delete a file / write in this folder
  • You can execute this file / browse the folder

They are defined for three users groups:

  • owner of the resource
  • one group of user
  • other users which are neitherbowner, nor member of the group defined

With this combination of users groups and roles, we can set the most common access permissions on our magento. But which one is the most secured one?

Unix permissions and Magento deployments methods

Permissions set are closely linked to your deployment method: Do you:

  • Upgrade magento directly with Magento connect?
  • Use the installer setup process and deploy your data with magento’s installers?
  • Copy a database coming from a previous server and update the configuration?

In the following article I’ll take the option that you test your updates on a non production server, push your source code through FTP, svn, or other file mechanism, and push your database upgrades with magento installers. Then, I’ll explain you which updates you require to be able to use other delivery mechanism.

Unix permissions Magento requirements

Unix permissions for Web server user in Magento

The most important thing from the point of view of your server security is the permissions defined for the owner of the files: this user run a server, so accept connexions. We must control which services can be provide by this server.
In most of the case this user is the user which run the webserver.

Common rules to apply

First, we will check what is requested for the webserver user to be able to use normally Magento scripts: this user needs to be able to read all files (this is the only requirement to be able to use PHP script) and be able to browse the magento directory tree. That’s all. So your PHP scripts must not have more than 4 octal permission. For your directory tree, we will give to your account access to read and browse, so 5 octal permission.

This is the most common structure for all Magento’s files and folders. Now we will take a look at some special cases.

Folders which require to be writable

Take a look now at the var and media subfolders; webserver user will write there its own data:

  • in var subfolder, he will write: backup files, log files, perhaps cache file, session user files, index process lock files, etc.
  • in media subofolder, he will write thumbnails and media librairy

So these two subfolders require the write permission.

Executables scripts by Webserver user

The question is : does your webserver user require to be able to execute scripts?
Depending on your Magento version, only two or four files require to be executable:

  • Installer script (pear for 1.4.2 or lower,  mage for the earlier versions): all to install modules from magento connect, or to be able to update directly from magento connect your magento
  • scheduler entry point cron.sh
  • pear embedded
  • pecl embedded

In our deployment model, pear is not used from back-office: so we do not set executable permission for our webserver to our webserver user: mage / pear / pecl won’t be executable by this user.
If you want to run scheduled tasks with this user, you must set up executable on the cron.sh file. But you can also run scheduled tasks with another account and so remove also this permission on this file for this user.

Unix permissions for group in Magento

Which group content ?

With group user, we will define all the permissions for administratives tasks: deploy, upgrade, maintenance management, etc.
This allow us to be really independant of the webserver user permissions.
So the group choice depends on who run these tasks. Most common thing is to set up the group of the administrative user as group.

Be able to upgrade source code

To be able to upgrade source code, this group must be able to write in all magento folders, delete, read files.

Be able to manage var data

Unix permissions for all others users in Magento

If all others users are not the owner of the file nor part of the group which realize the administrative tasks, they should not be able to access Magento directory tree: so no permissions

Unix permissions for others deployment methods

Deployment method with Magento connect

No, do you really update your source code from magento connect? Hope I won’t be on your website when you’ll do an upgrade 🙂

But anyway, in this case because it’s the webserver user which run magento connect, you must:

  • Give read / write on all files and folder (packages potentially contain files which can go in every folder).
  • Give the ability to execute mage / pear / pecl

This is one of the reason I don’t recommand this method: all your source files are potentially writeable by webserver user, and so, can be editable like in Prestashop worm.

Initial setup starting with Magento install program

In this case, there’s no big difference with the way I explained before: the only difference is on the app/etc/ folder which must be writeable during installation process to allow creation and update of the local.xml file. Then, when installtion process will finish, you can remove the write access on app/etc and app/etc/local.xml file.

Conclusion

You can find here a summary of the policy we should apply on our Magento folder.

#!/bin/bash
# 
# edit the following variables according with your server configuration
#
ROOT_UID="0"
GROUPUSERNAME=your_group
WEBSERVERUSERNAME=httpd
#
#Check if run as root
#
if [ "$UID" -ne "$ROOT_UID" ] ; then
   echo "You must be root to do that!"
   exit 1
fi
#
# ok, let's go for setting up permissions
#
chown $WEBSERVERUSERNAME:$GROUPUSERNAME "./*" -R
find . -type f -exec chmod 0460 {} \;
find . -type d -exec chmod 0570 {} \;
find var -type f -exec chmod 0660 {} \;
find var -type d -exec chmod 0770 {} \;
find media -type f -exec chmod 0660 {} \;
find media -type d -exec chmod 0770 {} \;
# set up installer script for our admin account
if [ -f pear ]; then
    chmod 0570 pear;
else 
   if [ -f mage ]; then
     chmod 0570 mage;
   fi
fi
if [ -f cron.sh ]; then
   chmod 0570 cron.sh
fi