This is a post where I have collected a lot of tips and links from wherever I could find them. Originally I was going to wait for Joomla 1.6 to publish this and make sure to adjust the list according to what 1.6 will look like, but 1.6 is still in beta, and I grow tired of waiting, so this is a list targeted at Joomla 1.5.
Disclaimer: This post is not to be considered final by any means. Please help out people like yourself by adding more stuff to the comments or tweet them to me @torkilj, and I’ll update this list accordingly!
Table of contents
- Choosing a host for your Joomla site
- Setting up and configuring the website
- Running the website
- Developer’s checklist
- What to do if your site gets hacked
- Further reading, other resources
Choosing a host for your Joomla site
First of all, you should find a proper hosting provider. You could ask others in the Joomla community for their recommendations, and you could check out the shortlist of hosting providers on the Joomla Resource Directory. These have at least gone through a manual screening process where their server setup has been checked for the most common pitfalls.
If you’re considering a host, here’s a brief list of requirements that you can run by your hosting provider to see if they fit the bill:
Make sure your host supports secure connections. It will cost you around $30/year to get a 256-bit SSL certificate to secure your backend. If you need to transfer files, make sure that SFTP or SCP is an available option to you, instead of having to use plain FTP.
- As with any software: Don’t use outdated versions, like PHP4
- Disable potentially harmful PHP functions
- Use open_basedir (with care, see comments after this article by Nicholas)
- Turn magic quotes off
- Don’t register globals
- Allow users to set local php.ini files
- Enable .htaccess
- Enable mod_rewrite
- Enable mod_security
- Enable suPHP
Use SFTP or SSH when you connect to your server, and do not store your password in for instance your FTP client. This of course also goes for any subsequent connections to the server after you have finished your install.
Follow your own best practices
If you have already set up one site where you follow all the basic security measures you want to follow, and you have already implemented the security extensions of your choice, there is no need to reinvent the wheel: Use a backup tool like Akeeba Backup or something similar, take a backup of the site and use that backup as a starting point for your new site.
Kudos to @hermanpeeren for the tip!
Do not use the standard DB prefix jos_.
Many SQL injection attacks are based on the assumption that your database tables are named “jos_”. In case you did use jos_, you can still change it with a simple PHP script.
One database user per installation
Do not give the same database user access to multiple installations, and do not use the server’s root user for your database connection.
Consider db user password quality
Use a long and complicated password for your database, and when installation is done, for your login. It’s too easy to decrypt an MD5 or SHA1 hash these day. There are even webapps that help you do it. If someone gets hold of your database of hashed passwords, it’s only a matter of time before they are broken. There are lots of good tips for password quality in this previous article I wrote, “How to createâ€”and rememberâ€”a different password for every single login“, and there are also a lot of good tips in the article’s comments.
In general, when it comes to passwords: Don’t write them down anywhere, and if you have to, at least store them securely.
Don’t install sample content
Sample content identifies you and your installation, and makes you easy to find and target. Don’t install sample content on what is to be a live website, because forgetting to remove absolutely all sample content is just too easy.
Setting up and configuring the website
Use correct file- and directory permissions
Avoid 777 of course. It seems this can’t be repeated enough times though. Extensions like suPHP will take care of setting proper permissions, so talk to your host and make sure they support it.
This will also make the need for the Joomla FTP-layer redundant, so you won’t neet to use your FTP username and password anywhere.
Uninstall stuff you don’t need
Brian Teeman has a saying: “Nothing appears on my website that I didn’t put there“. Uninstall core components, modules, plugins, templates and other extensions that you’re not using, including templates and even images. Extensions on your website are all potential security liabilities, either because they add security holes or because they help attackers identify potential security holes.
Observe for instance that installing the JCE WYSIWYG editor will also install TinyMCE, as it is bundled with JCE. Joomla comes with TinyMCE installed as it’s default editor, so then you’ll have two TinyMCE installations.
Some core stuff can’t be uninstalled through the normal uninstaller. This is because they are marked as “core” elements in the database. In the components, modules and plugins database tables, there are fields called “core” which is set to 1 for these extensions. Change this value to 0 to make them possible to uninstall.
Global configuration setup
If you don’t want people to register and/or login on the frontend, make sure you disable the functionality.
Disable the XML-RPC-server if you don’t need it.
Replace default Joomla meta information with your own data
Make sure you replace, or at least replace, the default metadata. These will show up in your sourcecode and in Google.
Use SEF urls
Regular URLs gives away the fact that Joomla is running your system. But then again, so can a lot of other things. Like for instance a template graphic, a static file, a code structure. Changing from regular to SEF URLs won’t render the regular URLs useless either, so this is not a very strong security measure. Make sure you also enable the .htaccess-file, see below.
Move logs and cache outside the site root
Change the log and cache paths in the administrator to a folder outside the site root so that they can’t be accessed through a web browser, or protect the folders in some other way.
Remove generator information
Remove the generator tag from the head-section of your website.
Delete the default user account
The userid 62 and the username “admin” represents a weakness, but there’s no easy way to replace these during installation. In the administration, the easiest thing you can do is to add a new super administrator, log in as the new super administrator, then demote the admin user to a lower usergroup and then delete the user all together. As our greek friend @nikosdion demonstrates, you can also fix this and add users below id 62 with some easy SQL.
Here’s some quick SQL to help you change the user id and username of the default account right after installation:
-- Change 3 in both queries with the userid you want -- Change jos_ with your own db prefix -- Change yourusername with your new username UPDATE jos_users SET id=3, username='yourusername' WHERE id=62; UPDATE jos_core_acl_aro SET VALUE=3 WHERE VALUE=62;
Enable the .htaccess-file
The default .htaccess-file has some basic security built in. In Joomla versions earlier than 1.5.15, you should also make sure it restricts access to critical files. In versions newer than 1.5.15 (1.5.20 is the latest version at the time this writing), you still have to uncomment parts of the .htaccess-file to activate this security measure.
Enhance the .htaccess-file
Nicholas K. Dionysopoulos (that’s @nikosdion in twitterish) also has a nice Master .htaccess-file with lots of other goodies included, that’s really worth a peek. For instance: Restrict directory listings, force https on certain pages, blocking of some common exploits, file injection protection, fingerprint attack blocking, and more.
Encrypt communication, or at least the login
A nice article by Herman Peeren highlights the dangers of not logging in to your site with SSL, and suggests that if you can’t set up SSL you at least look into an extension called Encrypt configuration.
Make fingerprinting your site harder
One of the easiest ways for an attacker to decide if your site is a potential Joomla! target is to perform a rudimentary visual fingerprinting. Both Joomla! and PHP comes with many static resources, special features and even easter eggs that can make it easy to identify what software you’re using, and what versions they are.
Choose your extensions wisely
Avoid extensions with encrypted sourcecode
You can’t fix bugs in encrypted sourcecode yourself, and you’ll be left at the mercy of the extension producer should something bad surface. This is mostly a personal preference of mine, as I like probing around in people’s code both to learn and to get a general feeling for the actual quality of the software I’m running.
Avoid dead extensions
If a extension’s homepage is returning a 404 error, or hasn’t been updated in ages, it’s a good indicator that you should check out if this extension is still being maintained or not, before you decide to install it.
Avoid legacy extensions
Stick to extensions with fresh 1.5 compatible code. Joomla 1.0′s EOL has passed now, over a year ago, time to move on.
Add extra layers of security
Protect /administrator with extra measures
You could require an extra password to access /administrator, or even restrict access to certain IP addresses. Some security plugins, like jSecure can help you accomplish stuff like this too. (thanks to @nikosdion again)
Consider installing security extensions
Monitor your site for unwanted changes
Lots of tools can be used here, for example there is a Windows tool out there called Akeeba SiteDiff, which you can use with Akeeba Backup, and which will compare the state of your site with the last known good state. Read more about Akeeba SiteDiff.
Add a custom ACL solution
Joomla 1.5′s default ACL is not very restrictive, and you may be giving out more access privileges than you’d like. Brian Teeman has a nice table showing who gets to do what exactly. Consider adding a custom ACL solution for better access control.
Avoid exposing information
Disable the display of errors on live sites, so that system paths and server information is not shown. Set display_errors to 0 in a local php.ini for instance, or use php_value in a .htaccess-file.
Don’t send out username/password in plain text e-mails
Sending a plain e-mail is like sending a postcard; it’s not wise to include anything sensitive in it. Joomla does this by default (!) each time you add a new user to your users list, or when a user signs up.
One way to avoid this is to override the language files; the text that goes out in the account creating confirmation e-mails is located in the language file, so this can be tweaked to not include the password.
In Joomla 1.6 you can also override a single language string without having to create a whole language pack, which makes this easier. There is also a plugin for 1.5 called Translation Override, which may prove to be useful for this purpose. (thanks to @jlleblanc, @nikosdion and @ot2sen for the tips)
Running the website
You should use the information to avoid insecure extension, because you can bet that those looking to hack your website are also keeping up to date with news on new vulnerabilities. – Read the result of Brian Teeman’s “Investigation of Exploits” from August 2010. – Read the vulnerable extensions list in the docs wiki, and subscribe to it’s feed.
Note that you can also subscribe to changes on a wiki page like the one above, to be notified whenever it changes. If you go to the vulnerable extensions list and register an account and log in, you will get a button in the top menu that allows you to subscribe to changes on that page.
Install security patches immediately
Pay attention to mailing lists announcing insecure extensions and updates to extensions you’re using, including Joomla itself of course.
Backup your site regularly
Make sure to test that the backup works and always store the backup off-site.
Use an IDE
IDEs can help considerably with code quality, development and testing.
Use a versioning system
Stuff like SVN and Git will be a lifesaver the day something is hacked or modified without your knowledge, or goes to hell in another way. It also makes it easier to maintain and roll out different versions of your software. Use versioning even if you’re the only one doing development, it’s well worth it.
Test locally, deploy globally
Run different configurations for your test sites and live sites: Stuff that gives away information should never be done where it’s visible to the public, in particular debugging. Errors should not be shown on a live site, especially not those who disclose paths or system information. As an extensions developer though, all you can do here is probably just advise your customers. This type of setting has to be done on the server.
Don’t chmod files or folders to 777!
Not only is this a bad idea security wise, it also tells people reading your code that you’re lazy at best, and furthermore that you don’t know what you’re doing.
Filter data the user inputs and escape outputting of user-provided content, which is especially useful for preventing SQL injection and XSS attacks. Read more about this and see examples.
Keep your codebase small
Reuse previously road-tested code where you can, and stay DRY (Don’t Repeat Yourself). Less code equals less potential security risks and less code maintenance costs for you.
Use Nooku Framework
If you’re creating a Joomla extension, you should consider using Nooku Framework, which reduces your codebase with around 80% and does a lot of things automatically, where you in Joomla would have to write code manually. Directly related to security, Nooku gives you automatic CSRF protection (automatic form tokens and token control), automatic data filtering and soon also automatic output escaping by default.
No executable code in class files
In your class files, stick to one class pr file and leave no executable code.
use a _JEXEC test in files, especially templates or files with executable code, to make sure the file is loaded from within the application. Files with just a PHP class in them do not need this.
Keep names and versions hidden
Don’t display extension names and versions in the code or on your site. “Powered by Superapp version 1.5″ on page footers that use your application, combined with a listing of Superapp version 1.5 being vulnerable on the list of vulnerable extensions, makes your clients easy targets. At least don’t display this info until Joomla gets a better upgrading system so that people can update outdated extensions in a painless manner.
Worth reading in this context: New Software Notifications in Google Webmaster Tools.
What to do if your site gets hacked
Take your site offline
If malicious code has been injected into your site, you’d not want others to get their computers infected or compromised. For tougher cases: Add an IP filter so that only your IP-address can access your site while your fixing it.
Remember: Offline does not mean unavailable
Setting a website in maintenance mode is merely a visual thing that indeed will execute all plugins and component requests, but merely render the offline template. So if someone has found a loophole to get into your site, and you want to shut them out while you fix the problem, setting the site in maintenance mode will not help you.
Nicholas Dionysopoulos published a blog post with information on this subject which is useful. He outlines one possible way around this issue, where he uses .htaccess to redirect all request to offline.html directly, bypassing Joomla completely. This means you have to have an offline-page of pure HTML to serve too of course. He also adds an exception so that you yourself can access the Joomla page from a specific IP-address.
Read the original blog post for a more in-depth explenation and code sample.
Find other people with similar errors
First thing to do would be to search the Joomla forums or search the web to try to find scenarios similar or identical to yours. This can save you a lot of time in the recovery phase, since you may benefit from other people’s findings.
Make sure your computers haven’t been compromised
Malicious software on any computer with is used for accessing the site or it’s FTP accounts for instance, can be used by an intruder to gain access to your online user accounts. Use a scanner software to scan for malware, trojans, viruses, spyware, etc. A list of available software packages can be found in the Joomla documentation under “Local security”.
Verify that you have the latest versions
Check that you have the latest Joomla version and the latest versions of your extensions, and that you’re not using any extension versions with known vulnerabilities. See lists of vulnerable extensions on the Joomla documentation wiki and in the Joomla security newsfeed.
Locate modified files
Log in to your server and use the find command to find out which files have been changed recently.
This command will list all files in the current folder where the file modification time (mtime) is less than three days old:
find . -mtime -3
This command will list all files in the current folder where the last change of file status (ctime) happened less than three days ago:
find . -ctime -3
This command will list all files changed at least one day ago but less than three days ago:
find . -ctime +1 -a -ctime -3
Find out what’s changed on your server
If files have been modified on your server, or files have been uploaded for instance, you can check the timestamps on those files to find out when the attacker was on your site. This is typical in the case of sites being defaced or malicious code being injected somewhere. Most of the time, the attacker will have gained access to your site shortly before modifying or uploading files to it. By checking your access logs for the period around that time, you may find some clues as to how the attacker gained access and which IP-address the attack came from, thus enabling you to track down things more easily in the logs.
You can also try searching for suspicious POST requests made to for instance non-form addresses on your site.
Use any information gained from this to block out further attacks and patch weak spots in your system.
Check your crontab/task scheduler
Check your crontab and make sure there are no things in there that you didn’t put there yourself. If you can’t access your crontab or don’t know how to, ask your hosting provider for help.
Report the attack to your host
Get your host to help you flush out the problems and make sure the attacker has not left any hidden backdoors to make it easy for him to regain access to your site.
Change your passwords
Change passwords and, if you can, usernames to all access points to your site: MySQL databases, FTP users, administrators, SSH accounts, control panel logins, etc. Use strong passwords!
Restore a working backup, or reinstall completely
Wipe your server clean and roll back to a known, safe backup. Make sure all security holes have been patched before you reopen the site. You should also consider deleting the entire installation and just reinstall Joomla and your extensions from scratch, so that you are certain not to include any backdoors a hacker may have left behind prior to the attack.
Report security issues you may find
If you find soft spots in Joomla or any Joomla Extensions, report them on the security forum, but without outlining to the public how to hack one million Joomla sites in 10 seconds. Also contact extension developers directly to give them a chance to produce a patch for their users.
When you report problems on the security forum, use the post assistant tool to make sure you include all the required information so that people are able to help you properly.
Official tips lists
Further reading, other resources
Read Nicholas’ blog
Nicholas K. Dionysopoulos’ blog is currently, by far, the best source of new information on this subject.
Follow Jeff Channel (@jeffchannel)
Jeff has found several security holes both in the Joomla core and in well-known Joomla extensions. He tweets regularly about security, and you could probably also hire him to do a security audit of your extension.
Joomla security forum
Discuss at the Joomla 1.5 security forum.