How to stop brute force and bots on WooCommerce without Wordfence
Wordfence is a WordPress security standard, but for a high-load WooCommerce store it creates more problems than it solves. I’ll tell you how to protect your store from brute force, bots and spam using built-in tools - without conflicts with caching and unnecessary costs.
COS / KNOWLEDGE BASE
Last week, an acquaintance wrote to me - the owner of an online auto parts store on WooCommerce. He writes: “Oleg, my site is slow, the hosting is complaining about the load, but I haven’t changed anything.” I go in to look and see a classic painting. Over the past 24 hours, sixty thousand requests to wp-login.php have been crammed into the access.log. Sixty thousand. From two hundred different IP addresses. Someone methodically tries passwords - admin, administrator, shop, manager, test, 123456 - in a circle, without stopping. Bots work like a Swiss watch: three to four requests per second, just enough to not fall under the hosting’s primitive rate-limit protection, but enough for the server to choke from processing PHP requests.
My first instinctive advice was “install Wordfence”. It's a reflex, right? WordPress security means Wordfence. I thought so myself for years. But then I stopped and asked myself a question that should have been asked a long time ago: is Wordfence really the only way to protect against brute force? And is it really the best way for a WooCommerce store with its specific workloads and requirements? Honestly, the deeper I dug, the more I became convinced that for commercial sites on WooCommerce, Wordfence is like shooting sparrows from a cannon. Yes, you will. But at the same time you will destroy half the wall.
Let me tell you what I came to after several years of struggling with bots and brute force on real WooCommerce projects - and why at some point I abandoned heavy universal security plugins in favor of point-based, built-in solutions. This is not a theoretical "top ten security plugins" comparison - this is experience with industrial stores that have sixteen thousand products, two thousand visitors a day, and zero tolerance for downtime.
Why Wordfence is no longer my default choice
I'm not going to say that Wordfence is a bad product. It wouldn't be fair. Wordfence is a powerful, mature, well-supported tool with a huge database of signatures. The problem is different: it was designed as a universal solution for any WordPress site, from a housewife's blog to a corporate portal. And WooCommerce is not “any site.” This is a store with dynamic pages, an AJAX shopping cart, checkout, API requests from payment systems, webhooks from delivery services and synchronization with 1C. And when in the middle of all this there is a plugin of more than a hundred megabytes in size, which, with each request, checks it against a database of several million signatures - the fun begins.
I first encountered this on a project for a client who sells industrial lubricants. He has a store on WooCommerce, sixteen thousand positions, synchronization with 1C: Trade Management via OData, search on Typesense, mega-menu with three-level navigation, B2B pricing with customer groups. Normal working store. Wordfence Premium cost one hundred and nineteen dollars a year, everything was as it should be. And then one day we noticed that the catalog pages began to load one and a half seconds longer after updating Wordfence. One and a half seconds is an eternity for an online store. We started digging and discovered that Wordfence conflicts with LiteSpeed Cache. Both plugins try to control HTTP headers, both get involved in request processing at an early stage, and as a result, caching works at times. Some pages are served from the cache, some are not, and the user sees either a fast or a slow site. Inconsistency is the worst thing that can happen in e-commerce.
We spent two days setting up exceptions. Added URL patterns for checkout, cart, API endpoints, AJAX handlers for WooCommerce. It seems to have worked. A month later, Wordfence was updated - and some of the exceptions stopped working because the config format had changed a little. We're wasting time again. And at some point I thought: wait, what exactly does Wordfence do for us that we can’t achieve more easily?
It turned out that out of the entire huge arsenal of Wordfence, we actually used four functions: brute force protection, blocking suspicious IPs, CAPTCHA on forms and file monitoring. A firewall with its WAF rules is useful. But our hosting already has ModSecurity with the OWASP ruleset. Malware scanner - ran once a month, never found anything (because we don’t install wrong plugins and themes). Two-factor authentication - configured only for the administrator. It turns out that we pay one hundred and nineteen dollars a year and suffer caching conflicts for the sake of functionality that can be implemented much easier.
Do you know what finally convinced me? I looked at the plugin size. Wordfence with its signature database, firewall, scanner and admin panel is more than a hundred megabytes. One hundred megabytes of PHP code, which is somehow loaded with every request to the site. For comparison, the entire WooCommerce is about forty megabytes. That is, a security plugin is larger than the platform it protects. This is tolerable for a blog. For a store with thousands of simultaneous sessions, no.
And one more point that is rarely discussed. Wordfence stores logs, statistics, scan data and firewall tables in the WordPress database. In the very database that the WooCommerce store is already overloaded with, wp_postmeta on our project weighs 937 megabytes. Adding several more tables with millions of rows from Wordfence to this means aggravating the already non-trivial situation with MySQL performance.
I'm not saying everyone should immediately uninstall Wordfence. This is a great choice for many sites. But if you have a WooCommerce store with a heavy load, server-level caching and specific integrations, it’s worth considering whether there is a way to get the necessary protection without this heavyweight. Spoiler: yes. And now I will tell you how we did it.
Anatomy of an attack: what exactly bots do and what they want
Before we defend ourselves, it is worth understanding what exactly we are defending against. I've noticed that many store owners perceive a "site attack" as something out of a Hollywood movie - a hooded hacker furiously tapping on the keyboard, green characters running across the screen. In reality, ninety percent of attacks on WordPress/WooCommerce sites are completely automated processes. Bots. Scripts. There is no person behind the screen. There is a botnet of several thousand compromised servers and IoT devices that methodically crawls millions of WordPress sites and tries standard logins with passwords from leaked databases.
The main goal is to gain access to the admin area. Not to steal your products or customer base (although that does happen). Most often, hacked WordPress is used as an intermediate link: they host phishing pages, send spam through your email, install cryptocurrency miners, and redirect your visitors to third-party sites. For a WooCommerce store, the consequences are catastrophic: Google marks the site as dangerous within hours, customers see a red warning screen in the browser, sales drop to zero. Restoring your search engine reputation can take weeks.
The number one attack vector is brute force via wp-login.php. The standard WordPress login page, which is accessible to the world by default. The bot sends a POST request with a login-password pair, receives a response, and sends the next request. At a speed of three to five requests per second, the bot can sort through tens of thousands of combinations in a day. If your password is “shop2024”, the question is not whether you will be hacked, but when. Moreover, even if the bot does not guess the password, it still causes harm: each request to wp-login.php is a full-fledged PHP session with a connection to the database, verification of credentials, and recording in the log. Sixty thousand such requests per day is a serious load even for a good server.
Vector number two is XML-RPC. This is a WordPress remoting protocol that was invented back in the days when people published blog posts through desktop applications. In 2026, approximately zero percent of WooCommerce store owners use XML-RPC. But it is actively used by bots, because via XML-RPC you can send the system.multicall method with hundreds of login-password pairs in one request. That is, instead of knocking on the door a hundred times, the bot knocks once and hands over a hundred keys at the same time. Many security plugins restrict login attempts through wp-login.php, but forget about XML-RPC - and the bots simply switch to this channel.
Vector number three - registration and checkout forms. On a WooCommerce store, unlike a regular blog, there are open forms that are available to unauthorized users: registering an account, placing an order, a feedback form, and sometimes requesting a commercial offer. Bots use these forms for two purposes: spam registration (creating thousands of fake accounts) and checking the validity of email addresses from leaked databases. The checkout form is especially vulnerable because through it you can check stolen bank cards in small transactions - the so-called card testing. PayPal, Stripe, YooKassa all combat this, but if you don't have a CAPTCHA on checkout, you're essentially giving the bots a free card verification tool.
Understanding these three vectors determines the defense strategy. We don't need a universal firewall with millions of rules. We need to close three specific doors - and close them securely.
Brute force protection: smart blocking instead of brute force
When I started designing a brute force protection module, the first thing I did was look at how Wordfence does it. And you know what I understood? The approach is actually simple. You count the number of unsuccessful login attempts from one IP address over a certain period. If you exceed the limit, you block the IP for a while. This is not rocket science. But the devil, as always, is in the details, and it is the details that distinguish a good implementation from a bad one.
The first detail is progressive locking. The naive implementation of “five attempts - block for fifteen minutes” does not work against serious botnets. The bot simply waits fifteen minutes and starts again. Or switches to another IP. We implemented exponential blocking: the first series of unsuccessful attempts - blocking for fifteen minutes, the second - for an hour, the third - for four hours, the fourth - for a day. An IP that consistently tries to guess a password after several cycles ends up being blocked for twenty-four hours. During this time, the botnet usually switches to other targets.
The second detail is to count attempts not only by IP, but also by username. If someone tries passwords for the admin account from a thousand different IP addresses, it is still an attack, even if there was only one request from each IP. We count separately: attempts from the same IP and attempts to the same login. Exceeding any of the limits will activate the blocking. For IP, the address is blocked. For a login, the ability to log in under this name is blocked for a certain period, regardless of IP.
The third detail is instant notifications. When the blocking is triggered, the administrator receives an email. Not in an hour, not in the daily digest - right away. The letter indicates the blocked IP, the country, the number of attempts and the login that they tried to find. This is important not only for reacting, but also for understanding patterns. When you see that for a week there have been attempts to log in under the “manager” login from IP addresses from one block, you understand that someone is purposefully attacking your site, and not conducting a mass scan. And then you take other measures.
The fourth detail is the whitelist. If you have a fixed IP in the office, you need to add it to the white list so as not to accidentally block yourself. It sounds obvious, but I know of two cases where a store administrator blocked his own IP with unsuccessful login attempts (forgot the password, tried five times) and then could not log into the admin area. This will not happen with a white list. We also added automatic detection of the administrator’s IP address during the first setup - so that he does not forget to add himself manually.
All this works at the PHP level, without external dependencies, without calls to cloud APIs, without gigabyte signature databases. Data about login attempts is stored in the activity log table, which is already needed for auditing. No additional database load - one row written for each login attempt. Compared to Wordfence, which checks the IP against the cloud reputation base with each request (which is a DNS request or an HTTP request to their API), the difference in performance is significant.
I've been thinking for a long time about adding integration with external IP reputation databases, like Wordfence does with its Threat Intelligence Feed. I decided not. In practice, ninety-five percent of attacks are stopped already at the stage of limiting login attempts. The remaining five percent are targeted attacks, from which the IP reputation database will still not save you, because the attacker uses pure proxies that are not in any database. And the cost for integration with an external service is dependence on a third-party API, additional latency on each request and potential problems if the API is unavailable.
Hidden URL and CAPTCHA: two simple tricks that solve eighty percent of problems
Do you know the easiest way to stop automated attacks on wp-login.php? Remove wp-login.php. More precisely, not remove it, but hide it behind another URL. Instead of the standard example.com/wp-login.php, your login page will be accessible at, say, example.com/my-secret-door. And when accessing wp-login.php, the bot will receive a 404. This is such a simple technique that many people underestimate it. But in vain.
The fact is that the vast majority of bots that attack WordPress are stupid scripts that are hard-coded to access wp-login.php and xmlrpc.php. They don’t parse your page looking for a login form, don’t analyze JavaScript, and don’t look for the “Login” link in the menu. They simply send a POST request to wp-login.php and that’s it. If a 404 is returned at this address, the bot moves to the next site from the list. That's it, the attack ended before it even began.
We implemented the custom login URL quite elegantly. When the function is activated, the administrator sets his own slug - for example, academic, entrance, my-login, whatever. The plugin intercepts all requests to wp-login.php and wp-admin (for unauthorized users) and returns 404. At the same time, all internal WordPress links - the “Logout” button, links in letters about changing the password, redirect after the session has expired - are automatically rewritten to the new URL. The user does not notice anything, for him everything works as before, only the login address is different.
On our combat project - an industrial oils store - we enabled a custom login URL and within 24 hours we saw that the number of requests to wp-login.php dropped from sixty thousand to zero. Literally to zero. The bots kept knocking on wp-login.php, received a 404 and left. The load on the server has decreased noticeably - the same one-and-a-half second delay that we observed earlier has disappeared. And this without a single firewall rule, without a signature database, without a cloud service.
But a hidden URL is a defense against automated bots. What about semi-automated attacks where a person finds your login page and launches a targeted brute-force attack? Or with spam registrations via WooCommerce form? Or with card testing through checkout? This is where CAPTCHA comes into play.
We support three options: Google reCAPTCHA v2 (classic “I'm not a robot” with pictures), Google reCAPTCHA v3 (invisible, evaluates user behavior) and hCaptcha (alternative from Cloudflare, without Google dependency). Each option has its own strengths and weaknesses, and the choice depends on the specifics of the store.
reCAPTCHA v2 is the most reliable in terms of blocking bots. If the bot cannot click on pictures with buses, it will not pass. The downside is that it annoys live users. During a WooCommerce store checkout, this could cost you a conversion. The buyer has already entered the delivery address, chosen the payment method, and then he is shown ten blurry photographs with the question “select all pictures with fire hydrants.” Some will decide that the site is broken, others will simply go to competitors.
reCAPTCHA v3 solves this problem - it is invisible. The user does not click anything, does not solve any pictures. Google analyzes user behavior on the page - mouse movements, form filling speed, browser history - and assigns a score from zero to one. Above 0.5 - most likely a person. Below is most likely a bot. We allow you to customize the score threshold in the admin panel because different forms require different levels of severity. To enter the admin panel, you can set the threshold to 0.7 - it’s better to be on the safe side. For checkout - 0.3, in order not to lose legitimate buyers with non-standard behavior (for example, those who fill out a form using a keyboard without a mouse).
hCaptcha is an interesting alternative for those who fundamentally do not want to give user data to Google. Works in a similar way, but the data is processed by Cloudflare. For European clients with GDPR requirements, this may be critically important.
The key point is where exactly to place the CAPTCHA. Many security plugins install it only on wp-login.php and consider the task completed. But there are three more critical forms in a WooCommerce store that are often forgotten. Registration form - through it, bots create thousands of fake accounts. Password recovery form - through it you can check whether a specific email exists in the database (the form responds differently for existing and non-existent addresses). And the form of checkout is card testing, which I already talked about. We put CAPTCHA at all four points: login, registration, password recovery, checkout. It is configured separately for each form - you can enable v3 at checkout (invisible) and v2 at input (explicit).
This is where I want to make an important point. CAPTCHA is not a silver bullet. Advanced botnets can bypass reCAPTCHA v2 using services like 2Captcha or Anti-Captcha, where real people click on pictures for pennies. reCAPTCHA v3 can be tricked by emulating human behavior in a headless browser. But all this requires significant effort and resources from the attacker. A massive bot that crawls millions of sites won't spend a dime on your CAPTCHA - it will simply move on to the next site without protection. But a targeted attack is a completely different level of threat, and you need to protect yourself from it by other means. CAPTCHA in this case is the first line that cuts off ninety-nine percent of automated garbage.
These two techniques together - hidden login URL and CAPTCHA on forms - solve the vast majority of problems with bots on a WooCommerce store. Without a single line of firewall configuration, without cloud subscriptions, without a hundred-megabyte plugin. Just pure, targeted protection on specific vulnerable points.
XML-RPC: WordPress' Most Underrated Hole
I remember the moment when I learned about XML-RPC amplification attack. This was about five years ago, and I was sincerely surprised - how is this even possible in the modern world? XML-RPC is a legacy WordPress protocol that allows you to remotely manage your site via XML requests. Publishing posts, managing comments, uploading files - all this can be done through xmlrpc.php. The problem is that this file supports the system.multicall method, which allows you to combine multiple calls into one request. And the attackers quickly figured out how to use it.
Instead of sending a thousand separate requests with different passwords (which is easy to track and block), the bot sends one request with the system.multicall method, inside of which there are a thousand calls to wp.getUsersBlogs, each with a unique login-password pair. WordPress honestly processes all thousand calls and returns the result. One HTTP request means a thousand password checks. Not a single login attempt counter on wp-login.php will see this, because the attack comes through a completely different channel.
But brute force is not so bad. XML-RPC is also used for another type of attack - DDoS amplification. The bot sends an XML-RPC pingback request to your site with a fake victim's return address. Your WordPress honestly sends a pingback request to the victim’s address. If a bot does this simultaneously from thousands of compromised WordPress sites, the victim receives a DDoS attack, and your site becomes an unwitting member of the botnet. Nice prospect, right? Your domain gets blacklisted, your hosting receives abuse complaints, and you don’t even know what’s going on until an angry hoster writes to you.
Solution? Completely disable XML-RPC. In 2026, no WooCommerce store needs this protocol. WordPress REST API has long replaced all XML-RPC functions - and does it more securely, faster and with normal authentication. WordPress mobile app? Works via REST API since version 5.0. Jetpack? I switched to REST a long time ago. Publishing through third party apps? REST API. There is no legitimate reason to keep xmlrpc.php open.
We disable XML-RPC at two levels. At the WordPress level - through the xmlrpc_enabled filter, which returns false. This disables XML-RPC request processing inside WordPress. And at the HTTP level - we intercept requests to xmlrpc.php and return 403 before WordPress even starts processing them. The second level is important because even after being disabled by the filter, the xmlrpc.php file itself remains accessible and can handle some requests before the filter is triggered. Double protection is more reliable.
After disabling XML-RPC on a production project, I looked at the logs and saw that the number of blocked requests to xmlrpc.php averaged three to five thousand per day. Three to five thousand requests that were previously handled entirely by WordPress - XML parsing, connecting to the database, verifying credentials - are now cut off at a very early stage with minimal resource consumption. It's not just security - it's performance optimization.
IP management: when you need heavy artillery
Hidden URL, CAPTCHA, and disabling XML-RPC are three basic milestones that solve ninety percent of bot problems. But sometimes you need to act tougher. Sometimes you see in the logs that from a certain range of IP addresses there are not just login attempts, but systematic scanning of vulnerabilities - requests to wp-config.php.bak, .env, .git/HEAD, debug.log. Or you see that a particular subnet is generating anomalous traffic to catalog pages - not bots trying to log in, but scrapers copying your product catalog with prices. In such cases, IP management is needed.
We implemented it in the form of two lists - black and white. The blacklist blocks IP addresses or entire subnets (in CIDR format) completely - the server returns 403 to any request. The white list, on the contrary, exempts the specified addresses from any checks - no restrictions on login attempts, no CAPTCHA, no delays. The white list usually contains IP addresses of office, home connections of administrators and addresses of trusted services (1C servers, payment systems, delivery services).
But manually maintaining a blacklist is a Sisyphean task. Today you will block ten addresses, tomorrow the attack will come from another botnet, and you will have to block twenty more. That's why we added automatic blocking based on behavior patterns. If an IP address generates more than a certain number of 404 requests within an hour (which indicates a vulnerability scan), it is automatically blacklisted. If the IP exceeds the limit of login attempts three times, automatic blocking occurs. If requests come from the IP containing typical payload lines of SQL injections or XSS - immediate blocking. All this can be configured, thresholds can be changed, because normal behavior looks different for different stores.
Here I want to warn you about a pitfall that I myself stepped on. Automatic IP blocking can block legitimate users who are sitting behind a NAT or corporate proxy. In a large company, hundreds of employees can access the Internet through one IP address. If one of them unsuccessfully tries to enter your store several times, the entire office will be blocked. Therefore, automatic blocking must be configured carefully: high thresholds, short blocking time for the first operation, mandatory notifications to the administrator. And a whitelist for the IP addresses of large clients, if you know them.
A separate topic is geo-blocking. If your store operates only in Russia and the CIS, does it make sense to accept traffic from Indonesia, Nigeria or Brazil? Statistics show that a significant portion of botnets are based in countries in Southeast Asia, Africa and South America. Blocking entire countries is a crude but effective tool. We support blocking by country based on the MaxMind GeoIP database. You can block specific countries, or you can invert it - allow only certain countries and block all others. For a B2B store that works exclusively with Russian legal entities, the “allow only Russia and Belarus” option cuts off a huge amount of junk traffic.
But I have to be honest: geo-blocking is not about security in its purest form. It's more about hygiene. A serious attacker will rent a VPS in the desired country for five dollars and bypass your geo-blocking in a minute. Geo-blocking is good against massive botnets that do not adapt to a specific site. And these are the majority.
Activity log: know everything that happens on the site
There is one thing that I consider even more important than all the protection mechanisms listed above. This is the activity log. A complete audit trail of everything that happens on the site. Who logged in, when, from what IP. Who changed the settings. Who updated the plugin? Who edited the product. Who changed the price? Who deleted the user.
Why is this so important? Because security is not just about preventing attacks. It's also discovery. And an investigation. If you are nevertheless hacked (and there is no 100% protection), the activity log allows you to understand: exactly when the penetration occurred, through what vector, what the attacker managed to do, what data was compromised. Without a log, you will act blindly - change all passwords, reinstall all plugins, check all files. With a log - you specifically correct what was affected.
I'll tell you a real example from practice. On one project, we discovered that someone had changed the email of the order recipient in the WooCommerce settings. Orders continued to arrive on the site, but notifications were sent to a third-party email - someone literally intercepted orders with customer contact information. Without the activity log, we might not have noticed the problem for months. With a log - we saw a record of the setting change, time, IP address and even the user-agent of the browser from which it was made. It turned out that one of the employees used a weak password, his account was compromised, and the settings were changed through him. We reset the password, enabled two-factor authentication, returned the correct email - and all this took an hour, not a week.
Our activity log module records events in separate custom tables - wpaic_activity_log and wpaic_activity_log_contexts. Separate tables, not wp_options or wp_postmeta, which are already overloaded. Each entry contains an action type, an action object (post, product, user, setting), old and new value, IP address, user-agent and timestamp. All critical actions are logged: logins and logouts, user and role changes, plugin and theme updates, WooCommerce settings changes, product and price changes, order actions, file changes.
An important detail is storing logs. If you log everything forever, the table will grow to obscene sizes. We store logs for a configurable period—ninety days by default. Entries older than this period are automatically deleted via Action Scheduler. It can be increased to a year, or reduced to thirty days - it depends on your audit requirements. For companies that work with personal data (and this is any online store), ninety days is a reasonable balance between security requirements and resource savings.
And one more point that I want to emphasize. The activity log is not only about security. It's also about management. When you have several managers working with a store, you want to know who changed what. Did the manager accidentally reset the price of a popular product? Visible in the log. Did your intern delete an important page? Visible in the log. Did the contractor update the plugin that broke the checkout? Visible in the log. This is not a tool for paranoia, but for normal business process management.
When I show store owners the activity log for the first day after switching on, the reaction is usually the same: “I didn’t know that so much was happening on the site.” And it's true - most people don't even realize how many automated processes WordPress and WooCommerce run in the background. Transient updates, cron tasks, Action Scheduler, webhooks - all this generates events that remain invisible without a log.
Everything without a separate plugin: why built-in protection is better
Now let's talk about what all of these mechanisms have in common and what makes this approach fundamentally different from installing Wordfence. All these functions - brute force protection, hidden URL, CAPTCHA, disabling XML-RPC, IP management, geo-blocking, activity log - are implemented as modules of one plugin, which simultaneously manages your catalog, B2B pricing, search, delivery and synchronization with 1C. This is not “another security plugin on top of ten others.” This is built-in protection that knows everything about your store.
Why is this important? Because modules of the same plugin do not conflict with each other. The security module knows about the CSS caching module and does not interfere with its work. The CAPTCHA module knows about Quote Request forms and automatically adds verification. The activity log module knows about the actions of the B2B module and logs changes in customer groups, price tiers, and subaccounts. This is a single ecosystem, and not a set of disparate tools that need to be configured separately and hope that they don’t fight.
The second advantage is size and performance. The security module is several PHP classes with a total volume of about one hundred kilobytes. Not a megabyte - a kilobyte. It doesn’t carry around an encyclopedia-sized signature database, doesn’t scan the file system with every request, and doesn’t send data to the cloud. It does exactly what it needs to do and not an ounce more. On a WooCommerce store with LiteSpeed Cache, Redis and Typesense, every megabyte and every millisecond counts. A security module that adds one or two milliseconds to request processing is a completely different story than Wordfence with its twenty to thirty milliseconds.
The third advantage is cost. Wordfence Premium costs one hundred and nineteen dollars per year for one site. Sucuri Firewall - two hundred dollars. iThemes Security Pro - about a hundred dollars. If you have several stores, multiply. Built-in protection is already included in the price of the plugin that you already use to manage your store. No additional subscriptions, no separate licenses.
The fourth plus is a single point of configuration. Instead of jumping between the Wordfence admin, Cloudflare panel, .htaccess settings and server config - you configure everything in one place. The “Security” tab in the already familiar plugin admin panel. Brute force protection, CAPTCHA, custom URL, XML-RPC, IP lists, activity log - all under one roof, with a single interface style and uniform documentation.
I hear the objection: “But Wordfence has a WAF with thousands of rules to protect against SQL injection, XSS, and other application-level attacks!” Right. And we also have WAF - a Web Application Firewall module with rules for detecting SQL injections, XSS, path traversal and other common attacks. But we're not trying to replace ModSecurity or compete with Cloudflare WAF. We are closing the application layer - the one that sees WordPress-specific attacks that the server-side WAF might miss. This is complementary protection, not a replacement for a server firewall.
I also want to talk about one aspect that almost no one talks about. When you have Wordfence on your website, you essentially trust the security of your store to a third-party company, Defiant Inc. If tomorrow they decide to raise the price to three hundred dollars a year, you will pay because your entire security configuration is tied to their plugin. If they close the free version, you will pay. If they allow a vulnerability in their plugin (and this has happened), your store will suffer. Built-in security as part of your core store management plugin is control. You know what it costs, how it works, and you are not dependent on the pricing policy of an individual vendor.
I like the car analogy. Wordfence is like installing a separate, hinged security system on your car: a third-party alarm system, a separate immobilizer, an external GPS tracker, additional locks on the door. Each component is good in itself, but together they sometimes conflict - the alarm is triggered by the immobilizer, the GPS tracker drains the battery, an additional lock jams the standard one. Built-in safety is like a factory system: ABS, ESP, airbags, immobilizer - everything is designed together, everything works as a whole, nothing conflicts. Not so fancy? May be. But for ninety-five percent of situations on the road, it’s more than enough. And for the remaining five percent, there are specialized solutions at the Cloudflare Enterprise level, which work at a different level and do not conflict with anything.
I don't want you to take this article as "Wordfence is evil, delete it immediately." No. Wordfence is a good tool for certain scenarios. But if you have a serious WooCommerce store with high load, server-level caching and the need to save every millisecond, think about whether you are paying too high a price (both in money and in performance) for functionality that can be obtained much cheaper and easier. Pointed protection at the level of specific attack vectors - brute force, XML-RPC, spam registrations, card testing - combined with a full audit of actions provides real security without side effects.
Try enabling the security module, setting up a custom login URL, adding CAPTCHA to forms, disabling XML-RPC - and look at the logs in a day. I bet you will see tens of thousands of bots blocked and a noticeable reduction in server load. And then open the activity log and see what’s really happening on your site. It will be both scary and rewarding. Scary - because you will see how much you did not notice before. Helpful - because now you are in control.
And finally, one piece of advice that is not related to plugins. The most reliable protection against brute force is a strong password. Twenty characters, letters in both cases, numbers, special characters, no dictionary words. It sounds trivial, but I regularly see stores with a turnover of tens of millions of rubles, where the administrator password is the name of the company with the year it was founded. All the technical protection measures that I described are barriers that slow down the attacker and weed out bots. But if your password is “admin2024”, no hidden URL and no CAPTCHA will save you, because it will be guessed in the first hundred attempts. A strong password plus two-factor authentication plus a custom login URL plus limiting login attempts are four layers of protection, each of which makes the attacker’s task much more difficult. Hitting all four at the same time is a task that no massive botnet would waste resources on. It will simply go to the next site where the password is “123456” and xmlrpc.php is open. Don't be this site.