Table of Contents
This document addresses the steps you need to perform if you suspect that your site has been compromised (hacked). Moreover, it will let you know what you should do to prevent this problem from manifesting itself again.
We strongly recommend reviewing this information in advance, not after a suspected or confirmed compromise of your site.
If you suspect that your site has been compromised DO NOT rush into restoring the last known good backup. Even if that temporarily fixes your site it has two obvious drawbacks. First, the attacker may have left a backdoor script behind that restoring your last backup does not remove. Second, the attacker compromised your site at the state it was at or after your last known good backup. Since the vulnerability they exploited to compromise your site is still there you are likely to get hacked again.
If your site has been compromised you should assume that the hacker has access to it and could undo your mitigation measures, lock you out, extract information or otherwise make a bad situation worse. Therefore, the first thing you need to do is to get your site into emergency off-line mode (use Admin Tools Core or Professional for that). Do not trust Joomla!'s off-line mode, it's not designed to guarantee that your site will not keep on getting hacked by, e.g. a blind SQL injection attack or an attack targeting an ad-hoc entry point PHP file.
Proceed to immediately change your hosting account and FTP password. Do not use passwords you come up yourself, chances are they can be brute forced (guessed). Instead, use truly random passwords generated with a password manager application or the Random.org site. The idea here is that if an attacker got to your site they might have either done so by compromising your hosting / FTP account or, conversely, they might have found information to get to these credentials by gaining access to your site through a vulnerability in Joomla or its extensions.
At this point it's a good idea to also change your database password for the same reason. Remember to edit your configuration.php file and update the database password there. You are looking for a line similar to this:
public $password = '
Put your new database password between the single quotes.
Moreover, you need to change your Super User password as well. If you do not have access to your site's backend the Joomla! Documentation site has instructions for doing that through your database.
Once in your site's administrator back-end go through your site users. Are there any privileged users (Super User, Administrator etc) that you don't know about? If so, remove them. Attackers will very frequently create a privileged user account for themselves so they can have unfettered access to your site while possibly locking you out. If you have to reset your Super User password through the database changes are that there are unauthorised Super Users on your site you need to remove.
If you still have access to your site take and download a full backup of your site (files and database) with Akeeba Backup. If you do not have access to your site use the hosting control panel to take backup copies of your site's files and database. This can help you dissect the attack later on.
When you're done working on your site, do not forget to remove the emergency off-line mode from your site!
The rest of the article assumes you are trying to undo the hack yourself. If you feel out of your depth, there are people and services who'll do that work for you for a reasonable fee. You might want to take a backup of your site, let a professional clean your site and then compare the hacked and cleaned versions to understand what a hack looks like and how to spot it.
You should always identify the source of the attack. This will tell you a lot about what just happened to your site and help you defend against similar attacks in the future. Download your Apache access log files to your local PC. It's not necessary to download the whole lot, just the records for the last X days, where X is the number of days since you know that your site was definitely not hacked.
If the log files have a .gz extension they are compressed. You need to extract them first. On Windows you can use 7-Zip. On macOS you can use The Unarchiver. On Linux you can usually double-click or right-click on them and choose Extract.
The resulting log files are plain text files but rather large. You should an application that can work efficiently with searching into large text files. On Windows you can use Notepad++. On macOS you can use Cot Editor. On Linux you can use the built-in text editor of your desktop, such as Kate on KDE or gEdit on GNOME.
Here are some ideas on what to look for in the log files. Look for “insert”, “update” and “replace” as these signify a SQL injection attack. If it looks like a SQL command (possibly with comments like /**/ all over the place) it's most likely a SQL injection attack. Look for accesses to your administrator/index.php or index.php files which came from an IP other than yours, as these signify a brute force password cracking attempt or an unauthorized login to your site's back-end. Also look for access to PHP files except index.php in your site's root and administrator directories.
If you run into something which looks like a SQL injection attack, take a look at the component's name (if it occurs in a URL with index.php in it). That's a potentially vulnerable component. Check if the component is listed in the Joomla Vulnerable Extensions List (VEL) and, if so, make sure you have a newer version than the affected one. All developers had a vulnerability at some point and released an update to “plug the holes”.
If you have requests to a stray PHP file, check with the developer of the component it's stored in that the file is indeed legitimate (shipped with the extension) and required for correct operation of the component – or look at the component's installation ZIP file and make sure that the file exists in there. If the file should not be there, it's a malicious script placed in there by the hacker and must be removed at once. Do not assume that a vulnerable or malicious file placed in an extension's directory is a sure-fire sign that the extension itself is vulnerable. We've seen plenty of sites where the attacker "hides" their malicious .php file in a legitimate, popular extension such as Akeeba Backup or Joomla Content Editor (JCE) despite the installed version of the extension not being vulnerable itself. Remember, once an attacker compromises your site they have full control and they will try to muddy the waters to avoid detection, cast doubts and deflect suspicion.
If you see repeated requests to the same PHP file (other than
Joomla!'s index.php files), this could be a warning sign that something's
wrong. If the file is placed in an awkward directory that should not have
.php files directly accessible from the web, such as
cache, examine its
contents. If it's just CSS, there's nothing to worry about. If you see a
lot of complicated code, it's very likely hacking tool and should be
Using this tedious, time-consuming process you know how you got hacked and if the hacker left “back door” hacking scripts behind and remove them. If you skip this step, you can bet that your site will be hacked again in no time.
Some hackers modify core Joomla! files to install a backdoor to your site or automatically carry out malicious actions such as sending spam or attacking another site (essentially using your site as an unwitting springboard for their criminal activity). This is more tricky, as you don't get to see the results of the hack immediately and it's hard to know what was affected.
Ideally, you're using Admin Tools Professional and run its PHP File Change Scanner regularly. Run it again before unhacking your site. Its report will tell you which files have changed since the last scan.
While the PHP File Change Scanner -- or any other file change and malware detection script running inside your site -- will give you good quality results in most cases, a sophisticated attacker can circumvent detection by them. For example, they could have modified the code of these tools or tampered with their configuration or stored data in such a way that prevents detection of the attacker's changes. We have not seen this in real world sites but it is a possibility that cannot be discounted as implausible, especially if there is justified suspicion that the attack has been elaborate and targeted.
To be perfectly sure, if you have a last known good backup of your site (from a point in time you can bet your life that the site wasn't hacked) you can extract it and compare its contents (except the installation directory, if present) to an extracted backup of the hacked site. You will need to use a third party directory comparison utility for that. Take a look at the modified and added files. If you see PHP files in that list which are not the result of you updating an extension or Joomla itself it could be a sign of an attacker's activity.
If you do not have a last known good backup or can not perform a directory comparison for any reason, please proceed with all of the following steps regardless.
If you have PHP files added since your last known backup you need to delete them manually, one by one. Restoring a backup or reinstalling extensions (or Joomla) will not help with .php files added to your site. Restoring a backup or reinstalling Joomla and its extensions will only overwrite existing files, it won't delete any added files.
If you have modified files, it's easy to fix them. For core Joomla! files, simply download a fresh full installation Joomla! ZIP package and extract it on your local hard disk. Remove the installation directory and upload the rest of the files to your site, overwriting all existing ones. It will take a while.
For extensions with modified files, simply reinstall the latest version of each component, module, plugin and template you have. If you have modified some files yourself (e.g. template CSS files) make sure you have backup copies of those files before following the above procedure so that you can redo your changes after reinstalling the latest versions. Once you go through the pain of this process you will realize why all developers argue against modifying files.
If you have a backup from not too long ago and you are fairly certain it's not compromised you can avoid unhacking your site yourself. Do note that this method has two major drawbacks.
First, it is possible that your site was compromised days, months or years ago but the attacker didn't take any obvious actions. In this case restoring your site from a backup will also restore the attacker's backdoor to it. This has happened in the past.
Second, this method involves removing all files and database data before restoring your backup. You will lose all your site's modified or added files and data since your last known good backup.
Start by removing everything from your site, i.e. all files, directories and database tables. Then, restore your backup.
If you are experienced enough, you can try merging back modified data from a locally extracted backup of the compromised site to the site you are rebuilding. This process is well outside the scope of this document but let it be said that it involves manually moving non-PHP files and carefully examining database contents.
As it becomes apparent reading this section, having frequent, tested backups is of paramount importance. The frequency is subjective and can be mostly described as the answer to the question "How much data / work am I willing to lose if my site breaks or becomes compromised?". Depending on the site it could be as frequent as several times a day or as infrequent as once in a few weeks or months. Consider your use case carefully before designing a backup and disaster recovery strategy for your site.
There is no such thing as an unhackable site. When we first wrote this document in 2010 this sounded borderline alarmist. A decade later compromised sites have reached mainstream news. The sites of some very big companies, politicians and even government agencies have been compromised. The object lesson from this is that sites do get compromised. Therefore our approach should be two-pronged. One one hand we need to make it harder for the attacker to compromise our sites, ideally making it costlier for them to compromise the site than the value they will get from compromising it. On the other hand we should have a disaster recovery plan should things go awry.
First and foremost, keep everything up to date. This means Joomla! itself as well as its extensions: components, modules, plugins, templates and template frameworks or other libraries. It's easy to forget that modern templates and the frameworks they are based on have a lot of PHP code running on your server. There are often security issues which are addressed in newer releases. When building a site keep in mind that you must be ready to do the maintenance work required to update Joomla! and all of its extensions. Never modify .php files, even view templates, in Joomla, its extensions and its templates (this is called a "core hack" in common Joomla! parlance). Use Joomla features such as template overrides to achieve your goal. If you ever find yourself in a position where you cannot update the software running on your site because you modified a .php file to make your site work you should understand that you will be hacked and it was something you could have easily prevented.
Likewise, you should never find yourself in a position that you cannot update Joomla or its extensions because your version of PHP is too old. Joomla and most of its extensions support a wide range of PHP versions, going back to rather old and obsolete ones. If you have something even older it's unsafe for use in a production environment.
There is a common myth that if you're using your favorite Linux distribution's LTS (Long Term Support) release you can and should stay with the (already old and halfway obsolete at the time of publishing) version of PHP it ships with. This myth hides many falsehoods in it. An obsolete PHP version has known vulnerabilities. Even though your Linux distribution will attempt to backport most security fixes, some of these require changes in the internal architecture of PHP and are available only on actively supported versions of PHP. For example, some security fixes in PHP 7 could not be backported to PHP 5.6. Moreover, obsolete versions of PHP have known functionality issues (bugs) which affect the operation of software written in PHP, such as Joomla and its extensions. Developers may not be able to work around these issues which could lead to security issues. For example, this has been the case with session serialisation in PHP 5. Finally, developers cannot support obsolete, dead versions of PHP forever. Sooner rather than later they will drop support because they need to make their software compatible with newer versions of PHP or need to use features added to PHP to make it possible to maintain an ever-expanding code base without introducing new bugs.
Whether you agree with this or not is irrelevant. It is a fact of life. As an analogy, it doesn't matter if you agree that newer cars are safer; if you get in a car crash with your old car hitting a newer car you'll probably end up dead and the other person survive with minor to moderate injuries. It's ultimately your responsibility as the site owner to keep up with necessary security updates, including PHP versions.
PHP core developer publish a Supported Versions page which tells you when each version of PHP will or has become end of life. Even older versions are listed in the Unsupported Branches page. Use the information on these pages to understand the life cycle of PHP versions and plan your PHP version upgrades accordingly. It is safe to assume that about 3 to 6 months after a PHP version goes end of life you will have problems updating some of your site's software.
Some may be accounts belonging to people who should no longer have access to your site, e.g. someone who has quit the company, the developer who helped you troubleshoot something last year and so on and so forth. You should disable these users: block them and change their passwords to something random and their email address to something invalid (so that it's impossible to reset their passwords - a random email address ending with @example.com is enough).
Despite what the movies and popular press wants you to believe, attackers are not superhuman and usually don't even go through the trouble of writing an elaborate hack to attack your site. They will first go after the weakest link: your passwords. If you have used the same password in more than one place, you have an "unbeatable" method for deriving a password for each site or you can remember the password of all of your sites and accounts by heart it can easily be proven that an attacker can and will brute force (guess them). No, your pet's, significant other's or kid's name, birthday or social security number are not good password components. No, the name of that obscure Vietnamese place you used to hang out in college is most definitely not a good password either. And, really, your favorite movie or book quote is absolutely the worst password. This includes misspellings, using languages other than English, pidgin or [email protected] All of these are more or less easily identifiable, follow a convenient pattern or can be outright found verbatim with minimal effort on the part of the attacker.
Always use truly random, long passwords. An ideal password is at least 32 characters long and consists of a truly random mix of lowercase and uppercase English letters, numbers, punctuation and special characters. If it looks like an accident happened on your keyboard it's a decent password. Use a decent password manager with good reviews such as 1Password or LastPass and use it to generate and store your passwords.
Protecting your site login beyond a username and password is a great idea. This way you put even more hurdles in the way of an attacker who's trying to guess your password or, worse, has already managed to get hold of it e.g. by social engineering or by a targeted attack against you or one of the other people who have access to your site.
Several plugins and security components, such as Admin Toools, allow
you to set a secret query parameter to access the administrator back-end
login page. In this case accessing your site's administrator login page as
https://www.example.com/administrator will not work. You will
need to use something like
https://www.example.com/administrator?my_secret where my_secret
is your secret query parameter. This is a simple way to prevent
unauthorized access to your site's administrator.
Even better, you can password-protect the entire administrator directory. This is a protection applied at the web server level, meaning that it occurs before Joomla or even PHP itself get the chance to load. This offers the best performance against attackers. You can enable that through your hosting control panel or with a third party security extensions such as Admin Tools (even the free of charge version).
While these measures were enough until circa 2016 this is no longer the case. A Super User can log into Joomla's frontend and have a lot of tools available to them to manage the site and its content. Moreover, with the introduction of Shared Sessions (though disabled by default) in 2016 it's now possible for a Super User to login in the front-end and automatically have access in the administrator back-end of the site. This poses an additional challenge for protecting the front-end user log in as well.
You can always use a security extension, such as Admin Tools Professional, to prevent Super Users from logging into the front-end of your site. This means that Super Users have to go through the back-end login page which can be protected against brute force attacks. Moreover, you can set up additional protections such as preventing the creation or modification of new Super Users from the front-end of the site, meaning that a vulnerable extension cannot be exploited to give the attacker Super User access to your site.
On top of that you should enable a form of Two Factor Authentication. Joomla comes with built-in Two Factor Authentication using either Google Authenticator or YubiKey; that's a feature our lead developer contributed to Joomla 3.2. Alternatively and more securely you can use our free of charge Akeeba LoginGuard extension to add Two Step Verficiation with a plethora of alternative methods including Google Authenticator, YubiKey, FIDO U2F (Universal Second Factor hardware-based security), W3C Web Authentication (hardware-based security), codes send by email or text etc.
The drawback to all these security measures is that they make logging in a rather involved process. If you want to have ease of use without compromising the security of your site you can set up Akeeba Passwordless for passwordless login using W3C Web Authentication or Akeeba SocialLogin to login into your site with your Facebook, Microsoft, Google, Twitter etc account. The former uses secure hardware devices to log you in without typing a password, just your username. The latter lets you use a social network account to log into your site; the security is managed by Facebook, Microsoft, Google etc. They are both very fast and very secure. You should still use Two Factor Authentication or Two Step Verification and secure passwords on your account to prevent attackers from compromising your accounts; it's just that you're rarely if ever going to use them, instead relying on a secure and much easier authentication process.
Using HTTPS on your site is not a sufficient condition for security but a required one. That is to say, just having HTTPS does not make your site secure but NOT having it makes it insecure.
Back in the olden days, when this document was first written, getting and installing an HTTPS certificate (also known as "SSL certificate") was expensive and cumbersome. Moreover, enabling HTTPS on a site would slow it down. Fast forward a decade. Getting an HTTPS certificate is free of charge using Let's Encrypt, an industry-backed non-profit which literally gives away free HTTPS certificates once you prove ownership of the site. Most hosting control panels integrate with them, making it dead simple to acquire and install an HTTPS certificate in a matter of a few seconds. Performance issues are long gone now that servers have CPUs which include hardware acceleration for cryptographic functions. According to Google, the performance impact of HTTPS is less than 1%. To put this in perspective, you have an impact five to ten times higher just by adding a Latest Articles module to your site. Don't think about it twice, use HTTPS.
After enabling HTTPS on your site you should go to your Global Configuration and set Use SSL to Entire Site. This makes Joomla require HTTPS access everywhere. That's a great idea. You don't want any login, sensitive or personally identifiable information going over the network unencrypted, using plain old HTTP. As a bonus your site no longer appears as "insecure" in modern browsers.
It is also a good idea enabling HTTP Strict Transport Security (HSTS) on your site. This tells browser to never use plain old HTTP, even if the user explicitly asks for it. This prevents a whole class of attacks which can trick users into divulging information an attacker can use to attack your site. You can enable HSTS by editing your .htaccess / web.config / NginX configuration file yourself or by using a security extension such as Admin Tools Professional.
Do not use plain old FTP. It's insecure. It sends your username and password unencrypted over the network. Use SFTP whenever possible. SFTP uses an encrypted connection to your server.
Do not login to your site or your hosting service provider from a shared or public computer. You don't know if it's compromised. Even if it's not compromised you don't know if the data you enter is logged somewhere, how these logs are used or what happens if they are compromised.
Do not connect to your site or your hosting service provider from your device using public WiFi such as the hotspots in coffee shops, airports, malls etc. If you absolutely have to make sure you are using HTTPS to connect to your site or SFTP to access your site's files.
Do not connect to your site when traveling abroad to a country with suspicious or adversary network environments. If at all possible do not even have your regular devices with you. If you absolutely need connectivity and can afford it use a cheap laptop and phone you purchase before your trip and that you dispose of after coming back. You're not paranoid when it's proven that in some countries they are coming to get you the moment you land.
Do not give away your regular Super User, hosting account and FTP / SFTP username and password to people and companies who are helping you solve an issue with your site. Create a new user account for them and remove it as soon as they are done.
NEVER, EVER USE THE SAME ACCOUNT FOR EVERYONE HELPING YOU! We've had two people in the last ten years who accused us of hacking them because their site got compromised months after they had asked us to help them. As it became apparent they were sending the same Super User account with the same password to all developers they asked to help them. We had immediately removed their access information from their ticket and encrypted it, then trashed the encrypted information after we were done. The password was easily guessable too, something along the lines of "thanksforthehelp". Did some developer have lax security practices and got compromised? Did an attacker simply brute forced the easily guessable username and password? We will never know. What we do know is that their site got hacked, it was entirely preventable and by kicking an unwarranted fuss they irreparably damaged their relationship with the developers who wrote the software that powers and protects their business site. Please don't be that person.
There's an old saying among system administrators. There are two kinds of people: those who take regular backups and those who will wish they did.
Frequent, tested backups are extremely important for the well-being of your site and preserving your sanity. To err is human and its result is usually a broken site. Host technicians sometimes screw up, server hard drives fail and hosting companies go out of business overnight. Or your site could get compromised. Having frequent, tested backups stored outside of your server can help alleviate the consequences of such mishaps.
Even Akeeba Backup Core can help you with that. It comes with basic scheduling support for your convenience.
Stay alert. If your site get hacked again, you have a backup to restore from and you can narrow down your Apache log search in a day's worth of log files – hence easy to figure out what went wrong and how to resolve the issue.
Better yet, use Akeeba Backup Professional to make sure that backup is stored outside of your site.
There is a multitude of things which could be used to compromise a site. It's hard to keep track of everything and even harder trying to keep up on top of everything. Luckily, there is help -- though for a price. The items in this section do cost money but we'd also say that they make most sense for higher value sites. These sites already generate income for their owners, making it feasible for them to spend a little more to get the additional peace of mind.
Start with good, reputable hosting. Don't go for the cheapest offer. Cheap hosts tend to cram many sites onto a single server. Depending on the security consciousness and cost-cutting of the cheap host it is possible that a compromised site can be used to subvert all other sites on the same server. That is to say, even if your site is not vulnerable it might be hacked because of someone else's lax security practices. More expensive hosts tend to use adequate isolation between sites as well as include proactive security measures against common attacks.
Security extensions can be used to address potential issues in Joomla and its extensions which could be used to attack your site. It is advisable that you use one, such as Admin Tools Professional. Security extensions run inside your site, they have a better view of the system state and are in an ideal position to step some attacks that from the outside look legitimate. The downside is that if the site does get compromised through a vulnerability that the security extension is not configured to address or which completely bypasses it (e.g. a compromised site on the server wrote directly to your site's files, your FTP credentials got stolen etc) they won't help.
Conversely, security services run from outside of your site. While they can't catch some attacks, as explained above, they also cannot be bypassed or subverted by a successful attack. There are different approaches to these services. They can either run in front of your site (e.g. CloudFlare) or they can scan your site's files periodically (e.g. Sucuri). There are Joomla-specific services as well from various vendors. Consider your use case before comiting to a specific service.
Security is not an arcane ritual. It's all about applying common sense. Think about what you do, why you do it and what its results are. Don't cut corners. Don't try to save a couple of minutes at the expense of security. And, for whatever is dear to you, don't use pirated extensions. Surely, those pirates don't put these extensions they paid for out for free for the love of their mother. They have loaded them with backdoors to hack your site. Use your common sense and stay safe.