Building a WordPress Security Plugin: The Basics

WordPress is open source, which means that everyone, including hackers with a malicious intent, can scour the source code looking for holes in its security. In this set of tutorials, we will be going through the process of creating a WordPress plugin to detect and fix any security flaws that may lie in your WordPress installation.


Step 1 Setup & Metadata

Go ahead and make a new folder in your plugins directory called safe, then create a file called safe.php inside it. The first few lines of code for a plugin are just telling WordPress that it is a plugin, what it's called and other information of that nature. This section is similar to the metadata of a theme or template.

Update: As per Christopher's comment below, there is no longer any need to define WP_CONTENT_URL, WP_CONTENT_DIR, WP_PLUGIN_URL, and WP_PLUGIN_DIR as WordPress defines them for us in the file includes/default-constants.php.


Step 2 Action & Filter Systems

Next we have to put in place some action hooks, which are functions triggered after a certain event happens, such as the admin_menu function being called. Actions are typically used for modifying database data, email messages, and modifying what is displayed on the screen. Filters, on the other hand, are hooks that are launched prior to rendering text or sending data. You can also remove actions if you want, such as the wp_generator function.


Step 3 Define the Actual Functions

First, before adding any of our text into the plugin, we are going to essentially embed a stylesheet using the wp_enqueue_style function. This function is just a safe way to add CSS files to a WordPress generated page. For more information on enqueuing, check out Japh's tutorial on including javascript and css.

Now, in order for the user to be able to open the plugin page, we need to add a menu page for our plugin. Also, the security plugin should only be available to administrators (you can change this if you want).


Step 4 Metaboxes

In order to display information on the plugin page, we use metaboxes to make it look consistent with the WordPress admin theme. We are going to want to display the system/server information and also run some basic, quick security checks.

Now, let's check if there is an account with the default setting of admin which is the first guess of most hackers and therefore an easy way into your admin panel. Also, I recommend you configure an .htaccess file in your wp-admin directory that blocks all IP addresses other than yours. In our next article, we will set up a way to configure the .htaccess from the plugin page.

Let's add another column/box for the right side of the screen, where we can display all of the server's information and settings.


Step 5 Main Functions

Just for organizational purposes, create a new directory named inc inside your safe directory, where you will create a file called functions.php to hold our main functions. These functions will be responsible for running the tests, checking file permissions, database settings, etc. It's better just to separate these from the main plugin file so that it's easier to navigate and read.

First, start off by initiating a connection to the database and retrieving the MySQL version and MySQL information array. Also, let's check to see if PHP safe mode is turned on, as it may cause some headaches with other plugins and settings.

In order to accept incoming pingbacks, allow_url_fopen has to be set to "on" in your php.ini. However, it also makes your code susceptible to code injection, because the file_get_contents() can retrieve data from remote locations such as an FTP or web server.

Memory limitations and execution times will play a major role in the next part of the tutorial for the plugin to suggest possible solutions to security flaws while taking the system's limits into account.

Now, we just spit out all of the data that we just collected about the server.

Another major flaw in most generic WordPress installs is the use of the default table prefix: wp_. In our next article, we will set up a way to backup and rename the tables which is where the safe_check_table_prefix and safe_errorsoff functions will come into play.

If you have an older version of WordPress, then first upgrade. Regardless of how good you are of how keeping track of upgrades, there is always the possibility that you might fall behind. Once the security flaws of a previous version are listed in the change log for the new version, your installation's security is now compromised. Most themes do it by default but just to be sure, we removed it earlier using the remove_action filter and now we'll just make sure the end-user knows too.

With the newer versions of WordPress, the security of the wp-config.php shouldn't be a problem, but it's better to be safe than sorry. If someone with malicious intent were to get their hands on your wp-config.php, they could access your database access credentials, authorization keys and database salts. We'll just check if we can get the file, write to the file or if it exists in that directory at all. If it does, we'll show an urgent notice and, in our next article, a method to fix the issue easily.

Now, we have to go back to the safe.php file and add our new functions.php, above the action and filter hooks.


Step 6 Rendering

Back to the safe.php, the last addition is the safe_main() function which is called when the page is loaded. Here we need to add the metaboxes we defined earlier and add some styling.

Lastly, make a CSS file named safe.css in a directory called css under our safe directory. You can style the boxes however you want, or you can just use the following CSS code for the error and success text:


Conclusion

By now, you should know how to add a menu page for your plugin, apply action and filter hooks, and programatically check for any security flaws in WordPress.

If you have any additional suggestions or questions regarding security plugins, feel free to leave a comment! Also, this plugin is on GitHub, so go ahead, fork the repository and customize it however you want.

Update: this article has been updated as per Christopher's suggestions below.

Tags:

Comments

Related Articles