Starting from this article, we’ll develop an object-oriented WordPress plugin.
Our first goal is to define its requirements and, since we’re rewriting an existing plugin, we’ll need to break its current version down and fully understand how it works.
Our example, like we said, will be based on the Limit Login Attempts plugin by Johan Eenfeldt.
Here, we’ll thoroughly examine version 1.7.1 of the “Limit Login Attempts” open source WordPress plugin, which was last updated 9 years before the time this article is written. Then, we’ll rewrite it following an object-oriented approach.
Now, without any further ado, let’s dive into this! We’ll take a closer look at the current version of the plugin.
If you want to follow along, you can download, install and activate version 1.7.1 of the plugin.
NOTE: If you’re a Pressidium customer, you can immediately go to wp-admin → Settings → Limit Login Attempts, as we use an adapted built-in version in our installations.
This is what the admin page of the plugin looks like:
The current version we use as a starting point already provides some great functionality.
- Limits the number of retries when logging in (for each IP address), also providing a customizable limit
- Limits the number of attempts to log in using auth cookies in the same way
- Informs the user about their remaining retries or lockout time on the login page
- Notifies administrators when a user gets locked out
- Supports both direct and reverse proxy connections
- Offers a WordPress filter to whitelist IP addresses
Now we already know what the plugin is supposed to do and what features it offers, let’s take a closer look into its flow.
Breaking it down
You don’t have to know much about the current version of Limit Login Attempts to read the rest of this article series. However, we’ll briefly explain what it does, so if you want to take a look at the GitHub repository of the object-oriented version, it will hopefully be easier to understand what’s going on.
Studying the main plugin file, almost line by line, we thought a simplified diagram, grouping similar functionality together, might help you wrap your head around the plugin’s code flow.
Basically, the plugin handles login attempts, determines whether a user can be authenticated, keeps track of failed attempts, locks IP addresses out if necessary, and provides an administration menu.
Here’s a flow chart showing how the plugin handles a login attempt:
This is made possible by hooking into various parts of WordPress during the authentication of a user.
Upon further inspection of the plugin’s code, we listed all of the actions and filters it hooks into:
As we’ve already mentioned, the plugin also provides an administration menu to allow you to configure its options.
These options are:
- Client type: Whether the site can be reached directly or through a proxy server (defaults to direct)
- Allowed retries: Lockout user after that many retries (defaults to 4 retries)
- Lockout duration: Lockout user for that many minutes (defaults to 20 minutes)
- Allowed lockouts: Allow that many lockouts before increasing the lockout duration (defaults to 4 lockouts)
- Long duration: Lockout user for that many hours when the lockout duration is increased (defaults to 24 hours)
- Valid duration: Reset the failed login attempts after that many hours (defaults to 12 hours)
- Cookies: Whether to limit malformed/forged cookies (enabled by default)
- Lockout notify: Notify administrator on lockout (logging, sending an email, both, or none)
- Notify email after: If notify by email is selected, send an email after that many lockouts (defaults to 4 lockouts)
The plugin also customizes the error messages that will be displayed when a login fails.
If a user isn’t currently locked out, it will display the remaining number of allowed retries. Otherwise, if a user is already locked out, it will display the time remaining till their lockout gets lifted.
It also omits any information indicating the existence of the provided username which is intentional in order to prevent username enumeration.
NOTE: Avoiding inconsistent error messages that might accidentally tip off an attacker whilst and ensuring that they only contain minimal details is important to help maintain site security. Otherwise, a potential attacker might be able to discover (or confirm) valid usernames by trying different values until the wrong password error message is displayed. You can read more about that at “CWE-204: Observable Response Discrepancy”.
Host your website with Pressidium
60-DAY MONEY BACK GUARANTEE
There are more than a thousand lines of code in that single PHP file. Going through all of them, line by line, explaining what each line does would be extremely cumbersome and you wouldn’t learn much about object-oriented programming.
This article is all about object-oriented programming. The rewritten version of the plugin will provide the exact same features the current one does, while taking advantage of what OOP has to offer. That is, our code will (hopefully) be reusable, extensible and readable.
Next up, we’ll discuss how we came up with the design of our new and improved plugin!
- WordPress and Object-Oriented Programming – An Overview
- Part 2 – WordPress and Object Oriented Programming: A Real World Example
Host your Website with Pressidium!