Skip to main content
mySites.guru
New features added last monthRelease RadarFile ManagerImpostor FilesUpdate QueueRogue AdminsMCP & APIJoomla VELCVE Index

Must-Use Plugins and Drop-ins

Must-Use Plugins and Drop-ins

WordPress loads PHP from two places that never appear on the Plugins screen and cannot be switched off from the admin. An inventory of both, read from disk.

What this check and mySites.guru tool looks at on your site

There are two places WordPress loads PHP from without ever showing it on the Plugins screen, and neither can be switched off from the admin.

Must-use plugins

Every top-level PHP file in wp-content/mu-plugins/ is loaded on every request, always, with no Deactivate link. WordPress does not look inside subdirectories there, so a folder on its own runs nothing unless there is a loader file beside it.

Drop-ins

A short list of filenames WordPress loads by name straight out of wp-content/: object-cache.php, advanced-cache.php, db.php, db-error.php, install.php, maintenance.php, php-error.php, fatal-error-handler.php, sunrise.php and the three multisite ones. Some of them run only when a matching setting is switched on, which mySites.guru checks and shows per file.

Both are read by listing the directory rather than by asking WordPress what is there. On a site that has been broken into, whatever is loaded is already running inside the request that asks the question, so a list produced by WordPress is a list the attacker can edit. A directory listing cannot be filtered.

Having these is normal, which is why the badge is neutral

Managed WordPress hosts install must-use plugins as standard, and caching plugins install drop-ins on purpose. Colouring “this site has must-use plugins” as a problem would light up a very large share of perfectly healthy sites and teach everybody to ignore the row. So the count here is inventory. Only a row that can actually be justified, something hidden, or a file the malware scanner has already flagged, is coloured.

sunrise.php gets special handling: it only runs on a multisite network and only when a setting in wp-config.php switches it on. The tool reports whether the file is present and whether it is actually being loaded, because a leftover copy on a single-site install does nothing at all. WP_CACHE is read the same way, as a mechanism rather than guessed from a filename, because the constant being true with the drop-in absent is inert.

Why a must-use plugin is the most durable place to hide code

A must-use plugin is loaded before the ordinary plugins, runs on the front end and the admin alike, and the Plugins screen offers no way to turn it off. Deactivating every plugin on the site, the standard first move when something is wrong, changes nothing about it.

Drop-ins are the same idea with a shorter list of names. object-cache.php and advanced-cache.php are what your caching plugin installs, and they are loaded extremely early. fatal-error-handler.php is the one worth knowing about: WordPress loads it whenever the site hits a fatal error, which makes it a quiet place to keep code and a hard one to notice.

On the compromise this check was built from, the loader was a two megabyte must-use plugin and three drop-ins were hijacked alongside it, with a line appended to wp-config.php purely to force WordPress to load one of them. None of it appeared in any plugin list, because none of it is a plugin as far as WordPress is concerned.

None of this goes into your plugin inventory in mySites.guru, on purpose. Reporting a drop-in as an installed plugin would put it in your update list and your vulnerability checks, where it does not belong, and it would make a planted must-use plugin look like ordinary installed software.

Every forced-load file named

You can name every line in both lists: your host’s own must-use plugin, your caching plugin’s drop-in, your security plugin’s loader. Nothing in either location begins with a dot, and nothing in either is a file you cannot account for.

How to fix it

  1. Read the list once, properly. Once you know what belongs on a site, you will know straight away when something new turns up.
  2. Name every line. If you cannot account for one, that is the one to investigate.
  3. Anything hidden was hidden on purpose. A file or folder whose name begins with a dot is being kept out of ordinary listings, and there is no good reason for one to be here.
  4. Do not delete your host’s files. Managed hosts use must-use plugins for real work, and removing one can break caching, backups or the control panel integration. Ask your host before removing anything you did not install.
  5. Check this alongside your scheduled events. When malware plants a must-use plugin, it usually plants a scheduled event to put it back.

What mySites.guru does about it

On every snapshot, twice a day, mySites.guru lists both locations from disk and shows you what is loaded, how big it is and when it changed. Every path links straight into the web file manager at the folder rather than at the file, so you see it among its siblings, which is what you want when three of five entries are hidden dot-files from one campaign.

No viewer was built into this page on purpose. The file manager already has the connector jail, the CSRF token, the audit trail and an editor, and a second reader here would be a second path to the same files with none of it.

This check reports rather than accusing. A steady non-zero count is fine and trends as fine; what is worth your attention is an increase.

Must-Use Plugins and Drop-ins

mySites.guru checks every connected site for this automatically and flags it the moment it appears. These run twice a day on every connected site.

Further Reading

  • Five New Checks for WordPress Hacks a File Scan Cannot See - why a planted must-use plugin and three hijacked drop-ins were invisible to every file-level check on a compromised site
  • Must-use plugins in the WordPress documentation - why a file in that folder loads before every normal plugin and cannot be disabled except by deleting it
  • _get_dropins() in the WordPress code reference - the authoritative list of every drop-in WordPress will load by name, since no prose documentation page for them exists

Frequently Asked Questions

What is a WordPress drop-in?
A file with a name WordPress recognises, placed directly in wp-content. object-cache.php, advanced-cache.php, db.php and fatal-error-handler.php are the ones you will meet most. WordPress loads them by name, automatically, before plugins and before the theme, and they appear in no plugin list. There is no entry anywhere in the admin interface to switch one off or even to reveal that it exists.
Why is the badge on this check grey rather than green or red?
Because having must-use plugins and drop-ins is normal. Managed WordPress hosts install must-use plugins as standard, and caching plugins install drop-ins on purpose. Colouring their presence as a problem would light up a very large share of perfectly healthy sites and teach everybody to ignore the row, so the count here is inventory. Only a row that can be justified, something hidden or already flagged by the file scanner, is coloured.
Why does deactivating every plugin not stop a must-use plugin?
Because the Plugins screen has no control over it. Every top-level PHP file in wp-content/mu-plugins is loaded on every request, always, with no Deactivate link. Deactivating every ordinary plugin on the site, the standard first move when something is wrong, changes nothing about it. The only way to stop one is to delete or rename the file.
I have a file in mu-plugins whose name starts with a dot. Is that normal?
No. A file or folder whose name begins with a dot is kept out of ordinary directory listings on purpose, and there is no good reason for one to be in the must-use plugin directory. That is the one condition in this check that colours a row on its own.
EU icon: AI MODIFIEDWritten and edited by a human, with AI assistance. Our approach to AI

What our users say

Kees van D.
Kees van D.Van Dongen Design
★★★★★

I manage 80+ websites for my clients. It's such a relief to manage all services from one platform. Wish I had discovered this a long time ago :) Great services, unmissable if you manage more websites, it is saving me so much time and gives much more secure feeling. Thanks Phil!

Read more reviews
Laurent
LaurentToonet Création
★★★★★

The tool is truly comprehensive and packed with features. The system is very stable and works really well. The security and audit capabilities are a real plus. Phil is very responsive and updates the tool regularly. Everything is closely monitored, which is really appreciated. It is a truly professional-grade tool.

Read more reviews

Read all 282 reviews →

See where your own sites stand

This check, and every other one, run automatically on a free audit. No credit card required.

Get Your Free Site Audit