Bots created specifically to penetrate websites are now powered by AI technology. This makes them more sophisticated, mimicking human-like behaviour. These AI-powered bots are capable of browsing websites like humans, can autofill simple CAPTCHA, and are fully capable to scrape content in bulk. WordPress-powered websites are prime targets of these bots. In this practical guide, we will learn all the methods and tricks to deter these AI-powered bots. You can apply these techniques to your WordPress site to easily block these bots. Let's get started and learn to secure our WordPress sites from these bad actors.
If you are already using an advanced and premium version of a security plugin, you may skip this tutorial, as such a plugin is fully capable of deterring these bots. If not, follow this guide and apply it.
You may need access to the shell environment of your hosting server to apply the techniques mentioned below. So make sure you have access to the same. Without wasting any time, let's dive in!
Steps to Combat AI-powered Bots
Before we learn about the methods to deter these bots, let's take a quick look at the tasks we need to accomplish to complete our goal.
- Login and authentication hardening.
- Blocking attack surfaces (unused endpoints, REST misuses, and XML-RPC).
- Application of rate-limiting and bot management.
- Detection of user behaviour (JS challenges, honeypots).
- Prevention of content scraping.
- Application of continuous monitoring and logging.
Although you can implement these steps in any order, we'll go through them exactly in the order they are listed here. Let's go!
1. Harden Authentication and Login Flow
The most common activity of these bots is to penetrate the login authentication system. First, you should harden and secure this passage. This is how you can do it.
Enforce Strong Passwords with Lockouts
A strong password significantly reduces any penetration attempts via the login channel. You must use a system to enforce extremely strong passwords. Add the following code to your theme's functions.php file.
<?php
// Enforce strong passwords for all users
function enforce_strong_passwords( $errors, $update, $user ) {
if ( isset( $_POST['pass1'] ) && ! empty( $_POST['pass1'] ) ) {
$password = $_POST['pass1'];
// Check minimum length
if ( strlen( $password ) < 12 ) {
$errors->add( 'weak_password', __( '<strong>ERROR</strong>: Password must be at least 12 characters long.' ) );
}
// Require at least one uppercase letter
if ( ! preg_match( '/[A-Z]/', $password ) ) {
$errors->add( 'weak_password_upper', __( '<strong>ERROR</strong>: Password must include at least one uppercase letter.' ) );
}
// Require at least one lowercase letter
if ( ! preg_match( '/[a-z]/', $password ) ) {
$errors->add( 'weak_password_lower', __( '<strong>ERROR</strong>: Password must include at least one lowercase letter.' ) );
}
// Require at least one number
if ( ! preg_match( '/\d/', $password ) ) {
$errors->add( 'weak_password_number', __( '<strong>ERROR</strong>: Password must include at least one number.' ) );
}
// Require at least one special character
if ( ! preg_match( '/[\W_]/', $password ) ) {
$errors->add( 'weak_password_special', __( '<strong>ERROR</strong>: Password must include at least one special character.' ) );
}
}
return $errors;
}
add_filter( 'user_profile_update_errors', 'enforce_strong_passwords', 10, 3 );
This function enforces a 12-character password with uppercase, lowercase, numbers, and a special character in the password. You can modify it as per your requirements.
I'd also recommend installing the Login Lockdown plugin to block IP addresses after a specific number of login attempt failures.
You can also apply rate limiting through an nginx server block in its configuration file. Here's an example.
# place in server block for your-domain.com
limit_req_zone $binary_remote_addr zone=login:10m rate=15r/m;
location = /wp-login.php {
limit_req zone=login burst=3 nodelay;
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
This server block allows 15 requests/min to the wp-login.php file. You can modify it as per your needs.
Add Two-Factor Authentication (2FA)
Another important security measure is to add 2FA for all admin users. One of the best options to implement it is the WP 2FA plugin.
Move or Hide wp-login (Change Login Slug)
Changing the login slug can significantly reduce login-related security issues. There are two approaches to apply this measure.
- Plugin approach: Use the WPS Hide Login to change the login slug. For example,
/wp-login.phpcan be changed to/secret-login-slug. - Manual: If you are an advanced user, rewrite rules or filtering can be used too. Here's the rule you can add to your
.htaccessfile.# Block direct access to wp-login.php and wp-admin for non-logged-in users <IfModule mod_rewrite.c> RewriteEngine On # Allow your custom login URL (e.g., /secret-login-slug) RewriteRule ^secret-login-slug/?$ /wp-login.php [QSA,L] # Deny access to wp-login.php if the request is not via /secret-login-slug RewriteCond %{THE_REQUEST} \s/wp-login\.php [NC] RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$ [NC] RewriteRule ^wp-login\.php - [R=403,L] # Deny access to wp-admin for non-logged-in users RewriteCond %{REQUEST_URI} ^/wp-admin [NC] RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$ [NC] RewriteRule ^.* - [R=403,L] </IfModule>
Feel free to use a highly complex slug to further strengthen this security measure.
Block Common Automation Headers and Suspicious User Agents
You can also block some of the obvious bad bots at the server level. Add the following directives to the .htaccess file.
# .htaccess directives to block some bad user agents
SetEnvIfNoCase User-Agent "Masscan" bad_bot
SetEnvIfNoCase User-Agent "curl" bad_bot
SetEnvIfNoCase User-Agent "python-requests" bad_bot
Order Allow,Deny
Allow from all
Deny from env=bad_bot
Note: Sophisticated bots can spoof UA; therefore, use UA blocking as a first filter only.
Remember, the blocking method given above is not foolproof. You may need to take additional measures to harden it further.
2. Close Attack Surfaces: XML-RPC, REST API, and Pingbacks
In this next step, we'll close several doors that may be used by these malicious bots to penetrate the website. Let's go through them one by one.
Disable XML-RPC
If you are not using XML-RPC, disable it altogether. This feature is used for massive pingback flooding and unsolicited remote posting. To disable this feature, either add the following filter to the functions.php file.
// Disable XML-RPC
add_filter( 'xmlrpc_enabled', '__return_false' );
Or, block it at the server level. Here's an example for the nginx server.
location = /xmlrpc.php { deny all; access_log off; log_not_found off; }
Limit REST API Access
Another door to close is limiting the use of the REST API to stop the exposure of user or email data. Here's how you can do it.
// Block REST API for non-logged-in users
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) return $result;
if ( ! is_user_logged_in() ) return new WP_Error( 'rest_forbidden', 'REST API restricted', array( 'status' => 401 ) );
return $result;
});
You can fine-tune it to allow specific endpoints you use on your website.
Disable Pingbacks/Trackbacks
To get rid of pesky pingback notifications, disable them altogether. You can either disable it through the WP Admin → Settings → Discussion page, where you can uncheck the 'Allow link notifications from other blogs (pingbacks and trackbacks) on new posts' option.
Or, you can use the following filter.
// Disable Pingbacks
add_filter( 'xmlrpc_methods', function( $methods ) {
unset( $methods['pingback.ping'] );
return $methods;
});
In fact, this is one of the first few configuration settings you must exercise on a new WordPress site.
3. Add Network and Application-Level Bot Management
Apart from WordPress-specific bot management measures, implementing the same at the network level can add an extra layer of security.
Use a Web Application Firewall (WAF) / CDN with Bot Management
Use content delivery and security services like Fastly, Cloudflare, and Sucuri that inherently support bot management. Clouflare's free plan can give you basic rate limiting and DDoS protection, out of the box.
Rate Limit Resource-Heavy Endpoints
Another important thing to consider is to rate-limit endpoints that are subject to overuse, generally for content scraping. Putting a check on these endpoints reduces load on your server significantly.
These endpoints are:
- REST API
- XML Sitemap
- Search Pages
- Author Archive Pages
Here's an Nginx example for rate-limiting usage of /wp-json/ endpoint, which is often used heavily for content scraping by these bots.
location ^~ /wp-json/ {
limit_req zone=api zone=api:10m rate=60r/m;
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
Use CAPTCHA Selectively
Instead of putting a sitewide CAPTCHA, apply it selectively at the critical points to avoid a bad experience for the site visitors. Here's where you should put it:
- After N number of login attempt failures.
- On the Registration forms.
- On the comment submission form.
The type of CAPTCHA used on your site matters too. Preferably, use a behavioral or invisible CAPTCHA for better UX. Both reCAPTCHA v3 and hCaptcha are good candidates for the same.
4. Behavior-Based Detection: Honeypots
Nowadays, smart AI bots use complex JavaScript code to mimic a web browser's behaviour. Implement all the checks and tests to ensure your website is dealing with a real web browser.
Simple Honeypot Field for Forms
For each web form on your WordPress site, add a hidden text field that human visitors cannot fill. If it is in a filled state on submission, block it.
Here's an example used in the functions.php file for the comment form.
// add honeypot field
function add_comment_honeypot() {
echo '<p style="display:none;"><label>Leave empty<input type="text" name="my_hp_field" value=""></label></p>';
}
add_action('comment_form', 'add_comment_honeypot');
// validate
function check_comment_honeypot($commentdata) {
if (!empty($_POST['my_hp_field'])) {
wp_die('Spam detected');
}
return $commentdata;
}
add_filter('preprocess_comment', 'check_comment_honeypot');
It works with most automated bot-powered comment form spam submissions.
5. Server & OS Level Defenses
A few of these bots turn to the server if WordPress penetration is unsuccessful. You have to prepare for that too. Here are some of the steps to harden the security of your web server.
Fail2ban for WordPress
At the server level, you can use the fail2ban filter to block continuous login failures, continuous 404 hits, and brute-force WP XML-RPC use.
Here's an example filter for repetitive failed logins:
[Definition]
failregex = ^<HOST> -.*"POST /wp-login.php
ignoreregex =
You can add this filter to the /etc/fail2ban/filter.d/wp-login.conf file.
6. Hardening Checklist
And finally, here's the checklist you can go through and apply to your WordPress site to ensure these malicious bots are deterred successfully.
- Take a full website backup to apply the changes mentioned above.
- Always enforce strong passwords and further harden them with 2FA authentication.
- Implement login rate limiting for failed attempts with lockouts.
- If you are not using XML-RPC, disable it altogether.
- Restrict access to REST-API endpoints.
- Without fail, add honeypot fields to all the web forms.
- Use anti-spam plugins.
- Set alerts for login events.
- Keep plugins, themes, and the WordPress core updated.
Conclusion
Autonomous bots are increasingly sophisticated each day, so your WordPress website requires more protection. There isn't a single magic bullet to prevent each attack, but a combination of clever security measures can do the trick.
Make sure your WordPress themes and plugins are up to date to the latest version. Utilize strong passwords and stop suspicious traffic. The majority of bots are hunting for easy prey, so closing those vulnerabilities will make your site much more difficult to breach.
Don't forget, website security is a continuing process, not a one-time installation. Taking just a bit of extra care now will spare you from larger issues later on.