Hacked Drupal Site: Cleanup and Recovery

By · Updated · 4 min read

Drupal has a strong security team and a good disclosure process, which cuts both ways: vulnerabilities get found and patched promptly, and the patch announcement tells the entire internet exactly what to attack on every site that has not applied it yet. Historically, the serious Drupal compromises have not been subtle zero-days — they have been sites that were a few weeks late.

How Drupal sites get compromised

Unpatched core is the classic. Drupal's highly critical advisories have historically been followed by mass automated exploitation within days, and the sites that got hit were overwhelmingly the ones that had not updated. If your site was compromised and you are behind on core updates, that is almost certainly your answer.

Contributed modules are the other major route, particularly ones that are unmaintained or that you installed years ago for a feature you no longer use. After that come the usual suspects: weak administrator credentials, over-permissive file permissions, and an unsupported major version receiving no security coverage at all.

Where to look

The sites/default/files directory is the writable one and the first place to check — it holds uploads and generated files, and it should not contain executable PHP. The sites/all tree, or the modules and themes directories in newer layouts, is where contributed code lives and where a malicious module can hide among legitimate ones.

Check settings.php carefully, since it holds your database credentials and is a natural place to append code. Check your active theme's template files. And check the database, where Drupal stores a great deal more configuration than WordPress does — injected content can sit in node bodies, in block content, and in configuration that gets rendered into pages.

Check accounts and permissions

Drupal's permission system is granular, which is a strength normally and a complication during cleanup. Look for accounts you did not create, and look at the roles they hold — an attacker may create a plausible-looking account with an existing role rather than an obvious administrator.

Also check the role definitions themselves, because an attacker can quietly grant a dangerous permission to an existing low-privilege role rather than creating a new account at all. Permissions like administering modules, executing PHP, or managing users effectively confer full control, and a change there is easy to miss if you are only auditing the user list.

Cleaning it

Preserve evidence first, then replace core with a clean copy of the same version, and reinstall contributed modules and themes from their official sources. Do not try to repair modified files individually — replacing wholesale is faster and leaves nothing behind.

Then sweep the database for injected content, remove unrecognized accounts and reset the permission changes you found, and clear all caches, since Drupal caches rendered output aggressively and stale cached pages can keep serving injected content after you have cleaned the source. Rotate database credentials, the hash salt in your settings, and all administrator passwords.

Then update, properly

Cleaning a Drupal site while leaving it on the version that was exploited achieves nothing — automated scanning will find it again within days. Getting to a supported, fully patched version is the actual fix, and it is not optional.

If you are on a major version that has reached end of life, that is a bigger project than a cleanup and it needs planning rather than a weekend. It is also the only durable answer, because an unsupported version will never receive another security fix no matter how carefully you clean it today. Subscribe to Drupal's security advisories so the next one reaches you on the day it is published.

Handling the consequences

The downstream cleanup is the same as for any platform. Search warnings go through Search Console security issues and, if there is a manual action, a reconsideration request. Browser and antivirus blocks are cleared through the vendor delisting forms.

If the compromise reached user data — and on a Drupal site that often means a membership or customer database — my guide on breach notification obligations covers what follows. And if the site matters and you want it dealt with properly, my cleanup service covers Drupal as well as WordPress.

Related reading: legacy Drupal and Drupalgeddon. See also every platform I clean.

Common questions

Why do Drupal sites get hit in waves?

Because Drupal's security team publishes detailed advisories when a serious flaw is fixed, which is good practice — but it also tells attackers precisely what to exploit on every site that has not updated. Mass automated scanning follows within days, and late sites get caught.

Which directory should I check first?

sites/default/files, the writable directory holding uploads and generated files. It should contain no executable PHP at all, so anything there is immediately suspect. Then your contributed modules tree, settings.php, and your active theme's templates.

I am on an unsupported Drupal version. What now?

Clean the site, but understand that cleaning does not make it safe — an end-of-life version receives no further security fixes, so it is permanently exposed. Upgrading to a supported version is the only durable answer, and it is a project to plan rather than a task to squeeze in.

Could an attacker change permissions rather than add a user?

Yes, and it is easy to overlook. Granting a dangerous permission to an existing low-privilege role gives broad control without a new account appearing in your user list. Audit role permissions as well as accounts, paying particular attention to anything that allows module administration or user management.

Why does the malicious content persist after I cleaned the files?

Very often it is the cache. Drupal caches rendered output aggressively, so pages generated while the site was infected can keep being served from cache after the source is clean. Clear all caches after cleaning, then verify again.