Home >> Blog >> Securing your Joomla! site

Wednesday, 21 October 2009 20:18

Securing your Joomla! site

Written by Nicholas K. Dionysopoulos
Rate this item
(0 votes)

Today I was reading Brian Teeman's blog post "Help my Joomla web site has been hacked!!". It outlines a pretty much scary story of site hacking. As we all know, security is a speed race. We have to upgrade our site software before a potential hacker gets wind of our outdated scripts, otherwise we run the risk of having our site compromised before we can react. What's more, the compromise might be exploited to the attacker's benefit long after we have upgraded the vulnerable site software, adding to our confusion. Quite a nightmare. But the hidden gem of this story, is a link back to Brian's "Are you a Dork?" post. He implies that attackers can easily guess the version of our site's extension, before breaking in our site. How can they? And what can we do to stop them? Read on for the full disclosure.

 

A little background

As you (should) all know, Joomla! extensions are installed in two places inside your site's directory structure: the administrator directory's (back-end) and the site's root (front-end) components, modules, plugins and templates sub-directories. One of the lesser known facts is that each component, by definition, has an XML manifest file which is stored inside the administrator/components/com_mycomponent directory. Here is the problem: a. this file says everything about your extension, including version number b. it is always present in the same well known location c. has a known, extension-specific name d. it is most probably web-accessible. This is a design flaw of Joomla! - it could just store this information in the database and be done with it. It is not a flaw of any particular extension and all extensions are vulnerable to this problem.

Let's give an example of the problem. Let's say that you have installed JoomlaPack on your site, hosted at http://www.example.com. Enter the following URL to your browser: http://www.example.com/administrator/components/com_joomlapack/joomlapack.xml. With any luck you should see a screenfull of information including the name of the software, the creation date and the version. To make a bad case even worse, Google gives you the opportunity to find out which servers are vulnerable to this problem, as Brian pointed out in his blog post.

Are you feeling like a sitting duck already?

Edit 23 Oct 2009: A small inaccuracy on my part. Brian Teeman explicitly mentions that the hidden danger is direct access to the XML files in his presentation "Joomla Hidden Secrets". This is a must-watch presentation for all Joomla! site administrators. He also proposes a solution, which cuts short all access to XML files. My solution is a bit more elaborate and also protects you from potential RFI attacks in mal-coded extensions' PHP files. Do note that future Joomla! releases will have a new rule in its htaccess.txt file, disabled by default, which disallows access to extensions' XML files. This patch was approved yesterday, October 22nd.

Countermeasures

Prevention is the best defense. Instead of waiting for script kiddies and more serious hackers to close in and start hammering their tools on your site, it's a prudent idea to make it much harder for them to get to files visitors are not supposed to. Think of it like this: if you had a brick and mortar store, would you allow every random client come inside your storage area, take a look at your supplier's invoices and probably try tampering with your safe deposit box, or would you lock the door to the storage area? Obvious answer, isn't it? Let's do the same with our site.

There are many approaches to locking down the door. One is using file and directory permissions, but IMHO this is a bit too hard and ineffective. You can always password protect the administrator directory (use your host's Control Panel to do that). The problem with this approach is two-fold:

  • Logging to your site's administrator section requires two logins: one for the web server level password protection, one entering your Joomla! credentials
  • Not all extensions have their manifest files located in the administrator directory of your site. For example, plugins, front-end modules and front-end templates have their files stored in plugins, modules and templates directories respectively. Password protecting these directories is like throwing yourself against a wall holding a sharp knife, as these directories are the very place where those extensions also store user-accessible files (e.g. CSS and images!) which you do not want to become inaccessible. You get the picture, right?

Most of the same concerns are valid if you decide to use the trick I blogged about a while ago, using a .htaccess file per directory to completely disallow access to it. Even though this trick works well for directories which have no visitor-reachable content (e.g. the tmp, cache, logs and libraries directories) it will not work as intended with the adminstrator, components, modules and other directories which are the home for both system files (incl. XML manifests and executable code) and visitor-reachable content, such as CSS and media files.

Quite thankfully, Apache and most other web servers - even IIS with a commercial plug-in - offer us the mod_rewrite alternative. The rest of the article describes a solution based on Apache's mod_rewrite implementation, which is also 100% compatible with Lighttpd's implementation.

Using mod_rewrite rules inside our site's .htaccess we will accomplish the following goals:

  1. Allow access to the index.php, index2.php and index3.php inside the administrator directory
  2. Disallow access to anything else inside the administrator directory, except select media types (JS, CSS, web image formats, HTML)
  3. We'll do the same for the front-end directories components, templates, plugins, modules
  4. Completely disallow access to other Joomla! system directories (cache, includes, language, libraries, logs, tmp), except for includes/js which contains the Joomla! system Javascript files
  5. Allow access to the XML-RPC directory if and only if the call ends up to index.php (this directory has no visitor accessible material)
  6. Optionally allow access to PHP files inside the protected directories, in case you have call-back scripts used by e-commerce systems' payment gateways.

In order to do that, we have to add the following code inside our site's .htaccess file, just right below the RewriteBase directive:

Edit 23 Oct 2009: My original rule set caused XML-RPC to stop working. This is now fixed. Also, accessing your backend as http://www.example.com/administrator doesn't work. You have to use http://www.example.com/administrator/index.php instead. I am working on this, but I think line 2 in the script below has to be rewriten to read administrator/index.php instead of $1 at the very end. It looks like it's server-specific, so take this advice with a grain of salt.

Edit 29 Oct 2009: As I thought, the original rules on lines 2 & 3 were causing some problems. So, I replaced them with the correct ones. The original rules had $1 instead of administrator/index.php which a. didn't allow you to access the backend without tucking the /index.php to the end of the administrator URL and b. caused some buttons onseveral sites to stop working, including JoomlaPack's "Backup Now" button. Heh... talking about epic failure :)

Updated October 29th, 2009 EET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## Back-end protection
RewriteRule ^(administrator[/]?)$ administrator/index.php [L]
RewriteRule ^(administrator/index.htm[l]?)$ administrator/index.php [L]
RewriteRule ^(administrator/index.php)$ $1 [L]
RewriteRule ^(administrator/index[2-3].php)$ $1 [L]
RewriteRule ^(administrator/(components|modules|templates)/.*\.(jpg|jpe[g,2]?|png|gif|bmp|css|js|swf|htm[l]?))$ $1 [L]
# RewriteRule ^administrator/.*\.php(.*))$ $1 [L]
RewriteRule ^administrator/(.*)$ index.php [F,L]

## Explicitly allow access only to XML-RPC's xmlrpc/index.php or plain xmlrpc/ directory
RewriteRule ^xmlrpc[/]?$ xmlrpc/index.php [L]
RewriteRule ^xmlrpc/index\.php$ xmlrpc/index.php [L]
RewriteRule ^xmlrpc/(.*)$ xmlrpc/index.php [F,L]

## Disallow front-end access for certain Joomla! system directories
RewriteRule ^(includes/js/.*)$ $1 [L]
RewriteRule ^(cache|includes|language|libraries|logs|tmp)/.*$ index.php [F,L]

## Allow limited access for certain Joomla! system directories with client-accessible content
RewriteRule ^((components|modules|plugins|templates)/.*\.(jpg|jpe[g,2]?|png|gif|bmp|css|js|swf|htm[l]?))$ $1 [L]
# RewriteRule ^((components|modules|plugins|templates)/.*\.php(.*))$ $1 [L]
RewriteRule ^((components|modules|plugins|templates)/.*index\.php(.*))$ $1 [L]
RewriteRule ^(components|modules|plugins|templates)/.*$ index.php [F,L]

See the commented out lines (starting with a single hash)? These allow access to any PHP file inside the otherwise protected directories. This is dangerous! Remove them, unless you have an explicit need for callback PHP scripts running outside of Joomla!. Normally, this should not be necessary and even if it is, it is better to modify them in order to explicitly allow access to the specific PHP scripts to which you require direct access.

For this hefty mod_rewrite trick to work, you must make sure that your RewriteBase line is set up correctly. This is required if you have installed your Joomla! site in a subdirectory. For example, if your Joomla! site is located in http://www.example.com/portal, your RewriteBase line should be:

RewriteBase /portal

If you fail to do that, the protection will not work, as none of the rules will match the URLs making their way to the mod_rewrite Apache module.

Another thing requiring caution is the placement of these rules. As I've written above, they have to placed exactly after the RewriteBase directive in your .htaccess file. The only thing that may appear before them is perhaps a domain redirection (e.g. directing non www prefixed domain names to their www prefixed counterpart). More specifically, Joomla!'s anti-exploits and SEO rule stabs must appear after these site protection rules. The reason is that all rule sets contain "final" rules which stop mod_rewrite processing once they are triggered. Since Joomla!'s rules are very generic, putting my rule set below Joomla!'s would effectively cause my rule set to be always overridden.

I will be glad to receive your feedback in the comments below, as well as by email!

Last modified on Saturday, 03 April 2010 12:37

13 comments

  • Comment Link FUTURE PUMA Saturday, 31 July 2010 08:54 posted by FUTURE PUMA

    57.documentation n'existent, mais la Chine est aujourd'hui le plus dominante dans la littérature SHOX RIVALRY révolutionnaire (même LUNETTES CARRERA ceux prétendant être un écrivain prolétaire d'oeuvres littéraires, en fait, également appartient à cette NIKE SKYLINE catégorie de portée NIKE TN littéraire). Exclusion de cette littérature, appelée vers le bas pour ces auteurs, a dit qu'ils étaient bourgeois capitaliste, dont essentiellement abandonné sur le United Front révolutionnaire dans les domaine des arts et donc naïf de milliers

    This e-mail address is being protected from spambots. You need JavaScript enabled to view it
  • Comment Link PUMA FUTURE Saturday, 31 July 2010 04:09 posted by PUMA FUTURE

    58Au SHOX R2 début de balistiques la Chine former NIKE TN hypothèque voile La Chine a maintenant la version air, sous-marine et routes terrestres, ferroviaires mobile lancer Trinity missiles stratégiques attaque capacité, a donc une capacité de rétorsion forte de missiles nucléaires stratégiques. La Chine a une attaque directe contre l'ennemi de défense en profondeur stratégie objectifs, tout PUMA CHAUSSURES pays à poursuivre une attaque nucléaire sur la Chine, nous devons garder une certaine échelle de Counterstrike nucléaire NIKE TN de la Chine. Il s'agit de la dissuasion nucléaire limitée. Étant donné que la technologie de missiles balistiques de lancement mobile ferroviaire exige un

    This e-mail address is being protected from spambots. You need JavaScript enabled to view it
  • Comment Link Adnan Kurtovic Saturday, 24 July 2010 16:15 posted by Adnan Kurtovic

    Thanks on excellent advices in this article as well as in other articles you wrote. I've sent you on mail htaccess file I use and, like I noted in mail, it would be great if you provide complete htaccess file one should use on Joomla powered site. Thanks again

    This e-mail address is being protected from spambots. You need JavaScript enabled to view it
  • Comment Link Nicholas K. Dionysopoulos Friday, 16 July 2010 13:01 posted by Nicholas K. Dionysopoulos

    It makes more sense, security-wise at least, changing your JCE temporary directory. The Joomla! tmp directory SHOULD NEVER, EVER BE PUBLICLY ACCESSIBLE. Think about it. In there you'll find leftovers of component installations, temporary files created by pretty much all extensions, you name it. This is the first place I would try to poke around if I were a hacker, with the cache folder being my second pick.

    I've seen many component, module, plugin and template developers not "getting" the importance of this simple statement. I've seen too many CSS/JS aggregators requiring direct web access to tmp and cache. In one word, I declare them "unsafe". It's like a car hi-fi which won't work until you unfasten your seatbelt. I'd rather not listen to music than risk flying out of the front-window of my car, even though the chance of crashing is very low. You don't mess around with security. You either apply it stringently or accept the consequences of not applying it at all.

    This e-mail address is being protected from spambots. You need JavaScript enabled to view it
  • Comment Link Mike Prince Friday, 16 July 2010 12:35 posted by Mike Prince

    It would be great to see an article about this as you suggest. I'm sure I'm one of a large proportion of Joomla webmasters who have blundered there way along starting from no knowledge in this area :-)

    One further update. The JCE Image Manager Extended plugin needs a cache folder which by default is the Joomla temporary folder. I had to remove tmp from line 17 above for this to work properly - without it it is not able to display image previews for example. (Alternatively it might make sense to use a different cache folder for JCE, which you can do easily within the JCE config.)

    This e-mail address is being protected from spambots. You need JavaScript enabled to view it
  • Comment Link Nicholas K. Dionysopoulos Thursday, 01 July 2010 00:25 posted by Nicholas K. Dionysopoulos

    I am glad you sorted it out :) My intention is to refine these rules and present them in a future Joomla! Community Magazine article. The ultimate (utopian?) objective is to have all webmasters get a grasp on key security ideas and implement them on their sites. Safer Joomla! sites for all will make the world a slightly better place :)

    This e-mail address is being protected from spambots. You need JavaScript enabled to view it
  • Comment Link Mike Prince Wednesday, 30 June 2010 13:17 posted by Mike Prince

    Pleased to confirm it was a JCE installation problem, and now I'm working fine with .htaccess as above (and the change you mentioned below).

    Thanks for the useful article and help.

    This e-mail address is being protected from spambots. You need JavaScript enabled to view it
  • Comment Link Mike Prince Tuesday, 29 June 2010 08:36 posted by Mike Prince

    Ok, the problem I have is with the last line: line 23 above. However it is only a problem if I am not using browser cacheing. The last line seems to prevent JCE from loading something that it needs - this only manifests itself if the browser isn't using its cache, so is admittedly pretty obscure.

    Not sure yet whether this is a general problem with that line, or just something with my JCE installation...

    This e-mail address is being protected from spambots. You need JavaScript enabled to view it
  • Comment Link Nicholas K. Dionysopoulos Friday, 25 June 2010 16:41 posted by Nicholas K. Dionysopoulos

    I use this .htaccess file and JCE on all of my sites, without any conflicts so far. I am not sure why JCE isn't loading on your site.

    This e-mail address is being protected from spambots. You need JavaScript enabled to view it
  • Comment Link Mike Prince Monday, 21 June 2010 13:07 posted by Mike Prince

    I've also discovered that another part of this htaccess breaks the Wysiwyg editor, at least with JCE which is what I'm using. For example, I just tried editing a section description and the editor did not show properly and the content could not be saved.

    Thanks for your reply on the other comment - will give it a try.

    This e-mail address is being protected from spambots. You need JavaScript enabled to view it
«StartPrev12NextEnd»

Add comment