My ‘Must Use’ plugins


So you know how almost every site that talks about WordPress will eventually do a top 10 WordPress plugin post? For some, that’s all they do. These posts basically consist of the following:

  • Either WP Total Cache and WP Super Cache so that you can screw your site by using a badly configured caching plugin
  • Some sort of spam catching device, probably Akismet (you know the thing bundled with WordPress)
  • A form plugin, normally Gravity Forms, Contact Form 7 or Ninja Forms
  • An E-Commerce plugin, normally WooCommerce, or some Membership software – it will be rubbish
  • An SEO plugin, either Yoast SEO or All in one SEO
  • A security plugin – WordFence, iThemes Security etc because security begins by installing a plugin
  • Jetpack because you know every site has to have Jetpack

Which is great and all, I mean some of those plugins are really useful and good. But it’s strange because with perhaps the exception of a couple I don’t think I have ever had the need for these essential top 10 plugins on most sites.

I thought it would be interesting to look at my Must Use plugins, by which I mean the plugins I have in an MU Folder. Wait never heard of MU plugins? Once upon a time there were two WordPress Cores, one for Single Site another for MultiSite aka WordPressMU. WordPress MU had the option to have a folder of plugins that activated for ALL sites by default, so the individual site in the network didn’t need to activate them, they were just on by default. When WordPress cores merged the MU Plugin stayed and was renamed to Must Use. Now it’s a useful place to store plugins that should always be on and called before any others.

I recently finished a site (not all of these are on, and thought it would be interesting to share what was in the MU folder. Some of the plugins are my own, and some are from other people. They all share a similar design philosophy of doing just one thing though often they are to support another plugin.

WP-Stack CDN

Developed by Mark Jaquith as part of a group of plugins, dropins and tools for professional deployments. WP-Stack CDN provides a simple way to swap all static assets URLs to be from a different base URL (in my case nearly always cdn.example). You can see how I use this little plugin with CloudFront to provide CDN services for this site in an article on using CloudFront with SSL.

Salt n Pepper

This is a simple plugin I developed originally for a client to provide both User Salt as well as Site Specific Pepper for passwords. If you haven’t come across the idea of pepper then a good read is Barking Iguana. A piece also worth reading is this Ircmaxell counter argument. Originally this used the existing WordPress system, storing the User Salt as an extra option in usermeta. However the current version removes the WordPress hashing functions entirely and replaces them with the default options for PHP5.5 Hashing API which has built in support for Salt and Pepper. This sits in the MU plugin as without it the system would use the default password hashing and no ones existing passwords would work! The plugin also introduces Password Versioning, which means if I change the password hashing algorithm or want to force password resets I can change the version numbers to seamlessly update people.

Job Queue Manager

This plugin is little more then a couple of classes to interact with Gearman Job Queues, but it allows other plugins to create queues and add jobs to queues. When writing custom plugins I tend to try and push as much processing to a queue where possible. While there are a whole heap of queue systems out there the big two you find in PHP development are Gearman and Beanstalkd. For WordPress I use Gearman over Beanstalkd even though I prefer Beanstalkd. Gearman however sits on top of Memcached which is my preferred Key Store Value system for using Transients and Caching. That said Redis + Beanstalkd is just as feasible, or even using Redis on its own and you can use Redis as a KSV system with WordPress object cache.

Custom Meta Boxes

Pretty much every project will at some point involve Custom Post Types and letting a user input some custom post meta. For custom post types the default WordPress functions are more then enough, but making custom meta boxes is a bit more work so I tend to use Human Made Custom Meta Boxes. CMB provides a simple API for creating custom meta boxes, allowing you to quickly build up a post type custom inputs. One of it’s big advantages is that it doesn’t modify the data, so it’s easy to retrieve by using the normal post meta calls. If you are a Developer and using Advanced Custom Fields or PODs to build meta boxes then you really should take a look at CMB.

Error Logger

You know when something just should be in core but no one but you seems to care? Yeah, welcome to the non-beautiful world of error logging. Sadly WordPress doesn’t provide a way to record errors; show them, yes, but not record them WordPress does support WP_DEBUG_LOG which will create a debug.log in your wp-content folder, this is hard coded to that location.

For error logging I use Monolog which I simply wrap in a WordPress plugin. In local development I tend to use it combined with the ChromePHP to throw errors to the console as well as to a log file. In production/staging I modified Idio Airbrake handler for Monolog to work with Codebase Exceptions (Which uses Airbrake) to allow me to be able to generate tickets, and associate commits with specific errors.


Not the plugin with same name in repo (which shoves fails to syslog because that’s sensible) but rather a simple plugin that just changes the HTTP header of failed logins to 401

function fail2ban_login_failed_401() {
    status_header( 401 );
add_action( 'wp_login_failed', 'fail2ban_login_failed_401' );

You can then create a filter in Fail2Ban that looks for 401 on wp-login.php in access log in Nginx and take appropriate action. For a step by step see Kovshenins post. This is a really simple way to block brute force attacks at a server level against both wp-login and xml-rpc login. I could use Monolog to throw the error to a dedicated error log but the access logs are already being monitored and it’s really what they are for.

HTML Comment Stripper

I’m not really bothered about my comments showing, but plugin developers have an annoying habit of putting a pile of rubbish in HTML comments so I tend to find it simpler to strip them out. Where possible I will have un-enqueued style sheets and javascript files so they can be included in the theme files or minified with other scripts. The stripper works exactly the same way as Stack CDN but with a regex to find and replace html comments. One issue is some Javascript wraps in HTML comments which can result in broken scripts.

Hard Coded Options

This small plugin takes a list of predefined config options, and then makes use of pre_option_optionname function to return the declared config option rather then looking at the database wp_options table. This is useful both from a security point of view, as we can make a set of read only options that even if they are overwritten in DB will be read from the config file, and also provides a performance boost assuming reading a static file is quicker then executing an SQL query, though the gain is minimal. It is also really handy for deployments and working on multiple servers allowing you to override certain options at a server level while sharing the same database.

Some further details and code for this can be found here

Asset Upload Manager

Users just don’t seem to be able to optimise images, check for viruses etc, so this plugin overrides the default upload location to a folder in tmp. then passes a job to the job queue. A python script then checks file type and passes to appropriate file crusher and to ClamAV to virus scan. It then moves the file to uploads folder. Nginx is set up to show a placeholder while this is happening, normally just a few seconds. This works well but has one potential issue, which is if the placeholder is picked up by Cloudfront and cached. To prevent this the Origin server doesn’t return the placeholder when CloudFront requests it. Not ideal but in reality the issue has come up maybe a handful of times. I really need to implement the Asset Upload Manager here on, as it contains multiple components which might make a good how to blog post.

Mandrill Support

Last one, I nearly always offload email management to services like Postmark and Mandrill. Both have good plugins but I prefer to override the wp_mail function, so I can send the email to a local queue and then run a second small python script to make the http requests to Mandrill. By pushing the email to a queue it means the user isn’t left hanging on things like approving comments. It also means under high load the box can wait to send the email.

In addition to the above I have a couple of Dropins. Like MU plugins they automatically install, but unlike MU plugins they are single files that are put in your wp-content folder. I have a couple running object-cache.php which is Memcached Object cache which puts transients into Memcached rather than in wp-options. It also means any use of the WordPress caching objects which the transients API is a layer uses Memcache for storage. The second one, DB.php, makes some minor changes to wpdb to make use of some of the features in HHVM in particular async options, and this is very much a work in progress.

So there you have it – my Must Use folder of my latest build. Guess the obvious question is, what’s in yours?

I incorrectly said WordPress doesn’t have a way to log debug messages, which is incorrect it does, not very usable but does. Time to open a ticket to see if we can get some additional functionality and flexibility into it.
4th August – Added Hard Coded WordPress Options example code link

Helping you and your customers stay safe

WordPress Security Consulting Services

Power Hour Consulting

Want to get expert advice on your site's security? Whether you're dealing with a hacked site or looking to future-proof your security, Tim will provide personalised guidance and answer any questions you may have. A power hour call is an ideal starting place for a project or a way to break deadlocks in complex problems.

Learn more

Site Reviews

Want to feel confident about your site's security and performance? A website review from Tim has got you covered. Using a powerful combination of automated and manual testing to analyse your site for any potential vulnerabilities or performance issues. With a comprehensive report and, importantly, recommendations for each action required.

Learn more

Code Reviews

Is your plugin or theme code secure and performing at its best? Tim provides a comprehensive code review, that combine the power of manual and automated testing, as well as a line-by-line analysis of your code base. With actionable insights, to help you optimise your code's security and performance.

Learn more

Or let's chat about your security?

Book a FREE 20 minute call with me to see how you can improve your WordPress Security.

(No Strings Attached, honest!)