Before You Begin
- The number one cause of compromised Joomla installs is users failing to keep up to date with security patches. Are YOU running the latest secure version?
- The number two reason is insecure hosting setups. Is your hosting secure?
Once you have passed the two tests above, you are ready to begin.
Read Me First! (OK, Second!)
About this document
- Security is a vast and fast-moving subject. No one document can cover it all. This checklist is designed to help you with only two things.
- Alert you to important issues
- Point you in the right direction to learn more
- Not all security techniques are appropriate for both versions of Joomla. Where a technique only applies to one version, an image is added. For example:
Joomla! 1.0.x Example
- Set Joomla! Register Globals Emulation OFF.
Joomla! 1.5.x Example
- To take full advantage of new security features, ensure that all third party extensions are Joomla! 1.5 native.
- Download extensions from trusted sites, and compare the file's MD5 hash to detect download errors. This suggestions applies to both versions, so no compatibility image is used.
There's no free lunch!
- Don't be fooled by Joomla's award winning ease-of-use. Maintaining a secure, dynamic Web site on the open Internet is not easy. Adequate security requires skill, knowledge, constant watchfulness, good backups, and continual effort.
There's no one right way!
- Due to the variety and complexity of modern web systems, security issues can't be resolved with simple, one-size-fits-all solutions. You, or someone you trust, must learn enough about your server infrastructure to make valid security decisions.
There's no substitute for experience!
- To secure your web site, you must gain real experience (some of which will be bitter), or get experienced help from others.
Rise above the herd
- The Security Forums are filled with "Help! I've been hacked" posts by people who did NOT follow standard security practices (this author included). If you decided to study documents such as this before your site is attacked, congratulation, you're already above the herd.
It's not as hard as it looks
- All complex, dynamic, and open systems require powerful error checking and recovery methods. Web sites are no different. Strong security is a moving target. Today's expert might be tomorrow's victim. Welcome to the game...
Are you ready?
- Can you administer a dynamic, 24x7, world-accessible, database-driven, interactive, user-authenticated web server?
- Do you have the time and resources to respond to the flow of emerging Internet security issues? The Top 10 Stupidest Administrator Tricks is a comic/tragic look at what can go wrong. Don't learn these tricks the hard way! Depending on your recent experience, reading the Stupidest Tricks will either make you laugh or cry.
Stay informed of security issues
- Given the complexity of web servers, new vulnerabilities and conflicts are discovered all the time. To stay in the loop, subscribe to Joomla Security Announcements.
Check the FAQs.
- The most helpful posts in the Joomla! Security Forum are converted into Security and Performance FAQs. Many of the items on this list are explained in much greater detail in the FAQs.
Learn from the pros
- Hunt down the many nuggets of wisdom found in the Joomla! Forums.
Choose a Qualified Hosting Provider
The most important decision
- Probably no decision is more critical to site security than the choice of hosts and servers. However, due to the wide variety of hosting options and configurations, it's not possible to provide a complete list for all situations. Check this unbiased list of recommended hostswho fully meet the security requirements of a typical Joomla site. (FAQ)
- If you are on a tight budget and your site does not process highly confidential data, you can probably get by with a shared server, but you must understand the unavoidable risks. Most of the tips listed below are appropriate for securing sites on shared server environments.
Avoid sloppy server configurations
- For a real eye-opener, read this report on thousands of sites that allowed Google to index the results of phpinfo(). Don't make this mistake on your site! The report includes alarming statistics on the percentage of site that use depreciated settings such as register_globals ON or that don't have open_basedir set at all: By the way, if phpini and register_globals are unfamiliar terms you are probably not ready to securely manage your own site.
Set up a Testing and Development Environment
Develop locally, deploy globally
- Develop and test your site on a local machine first. Installing Joomla locally is not as hard as it may sound, and the exercise will greatly boost your confidence.
Use an IDE
- Consider using an Integrated Development Environment (IDE).
Use a versioning system
- Be able to roll back to an earlier version of your site using a modern version control system, such as CVS or Subversion.
More suggested tools
- Check out the Joomla! community's list of popular Developer Software and Tools.
Install official versions of Joomla!
- To avoid braking your site, search the forums for reports of incompatible extensions before upgrading to a new version of Joomla.
- Upgrade to the latest stable version of Joomla! as soon as possible.
- Download Joomla! from official sites only, such as JoomlaCode.org, and check the MD5 hash.
- Use Joomla Diagnostics to ensure that all files were installed correctly. (Note: the version of Joomla Diagnostics made for the initial release of 1.5 does not work for 1.5.3.)
Change the default administrator username
- Change the user name of the default admin user. This simple step greatly increases the security of this critical account by modifying one of the two variables attackers can use to gain admin access. The admin password is the other variable. Change it early and often.
Protect directories and files
- Increase the security of the critical configuration.php file by moving it outside of the public_html directory.
- Ensure that all configurable paths to writable or uploadable directories (document repositories, image galleries, caches) are outside of public_html. Check third party extensions such as DOCMan and Gallery2 for editable paths to writable directories. There is currently no easy way to move the Joomla! /image and /media directories. The best plan is to make sure open_basedir is properly set for all the user accounts on your server. Check with your host if unsure.
Adjust file and directory permissions
- Once your site is configured and stable, write-protect critical directories and files by changing directory permissions to 755, and file permissions to 644. There is a feature in Site --> Global Configuration --> Server to set all folder and file permissions at once. Test third party extensions afterwards, and carefully review the code of any extension that has trouble with such settings. Note: Depending on your server's permissions, you may need to temporarily reset to more open permissions when installing more extensions with the Joomla! installer.
Remove unneeded templates
- Remove all design templates not needed by your site. Never put security logic into template files.
- Delete leftover files. The installation process will require you to delete the installation directory and all its contents. Do this; do not simply rename it. If you upload files to your site as compressed archives (xxxx.zip for example), don't forget to remove the compressed file. In general, do not leave any unneeded files (compressed or otherwise) on a public server.
Turn Register Globals Emulation OFF
- Also turn Joomla's Register Globals Emulation OFF. Although this setting is somewhat safer than PHP register_globals by itself, you are much better off avoiding such settings (as well as any applications that require them). This setting is found in the Back-end, under Global Settings. This setting does not exist in Joomla 1.5.
- For more information on register_globals, please see the section on PHP register_globals.
Use Apache .htaccess
- Block typical exploit attempts with local Apache .htaccess files. This option is not enabled on all servers. Check with your host if you run into problems. Using .htaccess, you can password protect sensitive directories, such as administrator, restrict access to sensitive directories by IP Address, and depending on your server's configuration, you may be able to increase security by switching from PHP4 to PHP5.
- Consider following the "Least Privilege" principle for running PHP using tools such as PHPsuExec, php_suexec or suPHP. (Note: These are advanced methods that require agreement and coordination with your hosting provider. Such options are enabled or disabled on a server-wide bases, and are not individually adjustable on shared servers.)
Use Apache mod_security
- Configure Apache mod_security and mod_rewrite filters to block PHP attacks. See Google search for mod_security and Google search for mod_rewrite. (Note: These are advanced methods that usually require agreement and coordination with your hosting provider. Such options are enabled or disabled on a server-wide bases, and are not individually adjustable on shared servers.)
Secure the database
- Be sure MySQL accounts are set with limited access. The initial install of MySQL is insecure and careful configuration is required. (See the MySQL Manuals) Note: This item applies only to those administering their own servers, such as dedicated servers. Users of shared servers are dependent on their hosting provider to set proper database security.)
Understand how PHP works
- Understand how to work with the php.ini file, and how PHP configurations are controlled. Study the Official List of php.ini Directives at http://www.php.net, and the well-documented default php.ini file included with every PHP install. Here is the latest default php.ini file on the official PHP site.
- Currently, both PHP4 and PHP5 are maintained, and both are often available on servers. Before PHP4 becomes obsolete, upgrade your custom scripts to PHP5. Don't worry about core Joomla code; all current versions are PHP5 compatible. (See PHP News)
Use local php.ini files
- On shared servers you can't edit the main php.ini file, but you may be able to add custom, local php.ini files. If so, you'll need to copy the php.ini files to every sub-directory that requires custom settings. Luckily a set of scripts at B & T Scripts and Tips can do the hard work for you.
- There are a few important things to keep in mind.
- Local php.ini files only have an effect if your server is configured to use them. This includes a php.ini file in your http_root directory. You can test whether or not these file affect your site by setting an obvious directive in the local php.ini file to see if it affects your site.
- Local php.ini files only effect .php files that are located within the same directory (or included() or required() from those files). This means that there are normally only two Joomla! directories in which you would want to place a php.ini file. They are your http_root(your actual directory name may vary), which is where Joomla's Front-end index.php file is located, and the Joomla! administrator directory, which is where the Back-end administrator index.php file is located. Other directories that don't have files called via the Web do not need local php.ini files.
- If you have a php.ini file in every directory, some script probably did this for you. If you didn't intend it to happen, you probably should root them out, but given #2 above, you probably only have to panic about the php.ini files in http_root and the administrator directories.
Use PHP disable_functions
- Use disable_functions to disable dangerous PHP functions that are not needed by your site. Here is a typical setup for a Joomla! site:
disable_functions = show_source, system, shell_exec, passthru, exec, phpinfo, popen, proc_open
Use PHP open_basedir
- open_basedir should be enabled and correctly configured. This directive limits the files that can be opened by PHP to the specified directory-tree. This directive is NOT affected by whether Safe Mode is ON or OFF.
- The restriction specified with open_basedir is a prefix, not a directory name. This means that open_basedir = /dir/incl allows access to /dir/include and /dir/incls if they exist. To restrict access to only the specified directory, end with a slash. For more information, see PHP Security and Safe Mode Configuration Directives.
open_basedir = /home/users/you/public_html
- Adjust the magic_quotes_gpc directive as needed for your site. The recommended setting for Joomla! 1.0.x is ON to protect against poorly-written third-party extensions. The safest method is to turn magic_quotes_gpc off and avoid all poorly-written extensions, period.
- Joomla! 1.5 ignores this setting and works fine either way. For more information, see PHP Manual, Chapter 31. Magic Quotes.
magic_quotes_gpc = 1
Don't use PHP safe_mode
- Avoid the use of PHP safe_mode. This is a valid but incomplete solution to a deeper problem and provides a false sense of security. See the official PHP site for an explanation of this issue.
safe_mode = 0
Don't use PHP register_globals
- Automatically registering global variables was probably one of the dumbest decisions the developers of PHP made. This directive determines whether or not to register the EGPCS (Environment, GET, POST, Cookie, Server) variables as global variables where they become immediately available to all PHP scripts, and where they can easily overwrite your own variable if you're not careful. Luckily, the PHP developers long since realized the mistake and have depreciated this 'feature'.
- If your site is on a shared server with a hosting provider that insists register_globals must be on, you should be very worried. Although you can often turn register_globals off for your own site with a local php.ini file, this adds little security as other sites on the same server remain vulnerable to attacks which can then launch attacks against your site from within the server. For more information, see ZEND Chapter 29. Using Register Globals.
register_globals = 0
Don't use PHP allow_url_fopen
- Don't use PHP allow_url_fopen. This option enables the URL-aware fopen wrappers that enable accessing URL object like files. Default wrappers are provided for the access of remote files using the ftp or http protocol, some extensions like zlib may register additional wrappers. Note: This can only be set in php.ini due to security reasons.
allow_url_fopen = 0
Backup before installing
- Before installing new extensions, always do a quick backup of your site's files and database. This follows a very basic and key principle:
- Thou shalt at all times be able to return your site to a previous working state if something goes wrong.
- Therefore, it's smart to set up a simple and fast backup script to automated this task. If you don't setup a simple process in advance, you'll be sorely tempted at some point to do a quick upgrade without backing. This very understandable tendency is, however, one of the chief causes of premature developer death.
Check for extension vulnerabilities
- Most security vulnerabilities are caused by third party extensions. Before installing extensions, check the Official List of Vulnerable 3rd Party/Non Joomla! Extensions. There's an entire forum dedicated to vulnerable third part extensions. Subscribe to it.
Download from trusted sites
- The fully qualified and official definition of a "trusted site" is one that YOU trust.
User beware! Check the code quality
- Third party extensions come in all flavors of quality and age. Although Joomla! coding standards exist, third party developers are not required to follow them. Extensions listed on the official Joomla! site are not reviewed for compliance, however if verified vulnerabilities are reported, they will be removed from the list until they are fixed.
Test, test, test...
- Test all extensions on a development site before installing on a production site. Then test on the production site. Don't forget the check the logs for runtime errors and warnings.
Remove junk files
- Remove all unused extensions and double check that related folders and files were actually removed by uninstall scripts. Note that during uninstall, many third party extensions will leave related files on your site, and related database tables complete with data. This is either a feature or a bug depending on your point of view. Any files left on your server remain accessible from the Web via direct URLs, such as http://yousite.com/modules/bad_module.
Avoid encrypted code
- Joomla is (and dispite disinformation campaigns, always has been) a GNU GPL project. This means that all extensions to Joomla must also be free (as in freedom) and open (as in readable code). Encrypted code may be safe, but you can't determine this for yourself, and so you must trust the developers. Using others' encrypted code puts you back in the world of proprietary software where you must wait for security patches from the developer, hoping that attackers don't find your site first before a fix is released.
- You are often not free to modify, improve, or share encrypted code. These restrictions make encrypted code less valuable to the community as a whole, and reduce the overall viability of the Joomla project which depends on open sharing among all participants.
- Of course, code that is not distributed to others is exempt from GNU GPL distribution requirements. Thus you can encrypt Joomla-related code your own servers providing you do not share it with others.
Additional Joomla! hardening Tips and Tricks
- For maximum security, avoid a shared server on which you don't know or can't trust all the other users or their code quality.
Use an SSL server
- SSL servers are currently the only way to securely process confidential transactions and secure user authentication. SSL works by encrypting all HTTP communications between the Web server and Web clients. Thus, even if a transmission is intercepted, it can not be read.
- Joomla! 1.0.x does not allow you to assign an SSL server to individual sub-directories. Search the forums for "Tommy Hack" for one way to deal with this. Joomla! 1.5 has greatly improved SSL options.
Use Apache's .htaccess
- For an additional layer of password protection, you can use .htaccess to password protect critical directories. This is usually adequate for blocking the typical script kiddie, but be aware that .htaccess password protection alone is not a highly secure method. It MUST be combined with an SSL server for maximum protection. An SSL server is required for protecting your site from more sophisticated attacks, such as packet sniffing.
Switch to Joomla! 1.5
- The most significant upgrade in Joomla!'s history includes powerful security and performance enhancements.
Add Joomla! Security Announcements to your site
- The Joomla! Security Team supports and RSS feed that provides the latest Joomla security information. The following FAQ explains how to add this feed to your site.
Ongoing Site Administration
Use well-formed passwords
- Change passwords regularly and keep them unique. Use a random combination of letters, numbers, or symbols and avoid using single names or words found in a dictionary. Never use the names of your relatives, pets, etc. Search the forums for a script supplied by Wizzie that automatically changes passwords. This is a great tool for administrators or multiple sites.
Follow a password leveling scheme
- Most users may not need more than three levels of passwords and webmasters no more than five. Each level must be completely unrelated to the others in terms of which usernames and passwords are used.
Maintain a strong site backup process
- Never rely on others' backups. Take responsibility for your backup procedures. Many ISPs state in their contract that you can not rely solely on their backups.
Monitor crack attempts
- VPS and dedicated server users can run TripWire or SAMHAIN. These applications provide exhaustive file checking and reporting functionality, and can be installed in a stealthy manner to help protect themselves in the event of a serious infiltration. (Note: Users of shared servers can not use this technique.)
Perform automated intrusion detection
- Use an Intrusion Prevention/Detection Systems to block/alert on malicious HTTP requests.
Perform manual intrusion detection
- Regularly check raw logs for suspicious activity. Don't rely on summaries and graphs.
Stay current with security patches and upgrades
- Apply vendor-released security patches ASAP.
Proactively seek site vulnerabilities
- Perform frequent web scanning.
Proactively seek SQL injections vulnerabilities
- Use tools such as Paros Proxy for conducting automated SQL Injection tests against your PHP applications.
Use shell scripts to automate security tasks
- Search the forums for these popular scripts:
- Joomla! Version Checking
- Joomla! Component/Module Version Checking
- Exploit Checking
Learn about security software
- There is not a single tool that can protect your site. If there were, it would be so heavily targeted that it would probably become a liability.
Don't reinvent every wheel
- Every now and then hire a professional Joomla! security consultant to review your configurations. Do you remember the adage, "Anyone who acts as their own lawyer has a fool for a client." The same goes for Web development. Don't expect to catch all of your own security mistakes.
- Always have complete backups.
- Know how to find exploit attempts using the *NIX shell.
- Have a tested plan for how you will recover when your site's been compromised.
- If you discover a bug in Joomla! core files, report it here.