Limit comment spam and password resets in WordPress
To limit comment spam bursts and password reset abuse in WordPress, put a ceiling on how many times one connection can use the three forms anyone can reach without signing in. BetterShield does this with Request protection, which counts comments, password reset requests and sign-ups separately from sign-in, and holds, slows or refuses a connection that goes past the number. This guide covers what each limit does, the defaults, how to preview new numbers before you save them, and how to undo it.
It sits next to limiting login attempts, which covers the sign-in form. This post adds the three forms that need no account at all.
Quick summary
- Request protection limits comments, password resets and sign-ups, the three public forms, and is on by default under BetterShield › Protection › Login & Access.
- A held comment goes to moderation as pending and is never discarded. A slowed password reset sends no email. A refused sign-up shows a plain message.
- The forms are counted apart from sign-in, so activity on a public form can never lock you out of your own dashboard.
- Defaults: 10 comments in 10 minutes, 8 password resets in 15 minutes, 8 sign-ups in 60 minutes.
- A sentence under any number you change replays it against the last two days of attempts before you save.
Why public forms need a limit
A sign-in form asks for a password. These three forms ask for nothing. Anyone can post a comment, ask for a password reset email for any username, or register where sign-ups are open. That makes them easy to repeat: a script can submit a comment form hundreds of times, fill your moderation queue, or send a stream of reset emails to someone who never asked for them.
A limit does not need to guess who is a person. It counts how many times one connection used a form in a short window, and acts when the count passes a number that a person doing a normal thing quickly would not reach. The general idea is called rate limiting: a ceiling on how often one source may repeat a request.
What each limit does
Every submission from a connection counts, whether it succeeds or not. When the count within Counted within (minutes) reaches Closes at this many, that submission and the ones after it are answered as below until Closed for (minutes) has passed.
| Form | What happens while closed | Never counted |
|---|---|---|
| Comments | The comment goes to the moderation queue as pending instead of publishing. Nothing is discarded, and a comment already marked as spam stays spam. | People who can moderate comments |
| Password resets | No reset email is sent. The form shows the same confirmation page a successful request gets, so it never reveals whether an account exists. | Reset links sent from the dashboard by people who can edit users |
| Sign-ups | The sign-up is refused with “Too many sign-ups have come from your connection recently. Please try again a little later.” Only where registration is open. | Accounts created at the WooCommerce checkout, and accounts created by people who can create or list users |
A few rules apply to all three:
- Only a verified connection is ever closed. One BetterShield cannot verify, such as several people sharing one address behind a proxy, is recorded and never closed. See Proxies and Cloudflare.
- Addresses on Always allowed are not counted.
- A closure lasts exactly Closed for (minutes). It does not grow with repeats, and nobody is emailed.
- Reset requests and sign-ups sent while closed still count, so a connection that keeps going is closed again as soon as a closure ends. Comments held while closed are not counted.
- Safe mode stands all three down.
Accounts are never affected. A person whose reset email was not sent can still reset from any other connection, or wait for the closure to end.
Set it up
- Open BetterShield › Protection › Login & Access and find Request protection.
- Turn each form on or off, and change its numbers if you need to.
- Read the replay sentence under any number you changed, then press Save.
| Option | What it does | Default |
|---|---|---|
| Hold a burst of comments for moderation | Holds comments from a connection once it reaches the limit, that one included. | On: 10 within 10 minutes, closed for 30 minutes |
| Slow repeated password reset requests | Answers reset requests once the limit is reached, that one included, without sending anything. | On: 8 within 15 minutes, closed for 15 minutes |
| Slow repeated sign-ups | Refuses sign-ups once the limit is reached, that one included. | On: 8 within 60 minutes, closed for 60 minutes |
| Closes at this many | The submission from one connection that closes the form to it: 3 to 100. | As above |
| Counted within (minutes) | How far back submissions are counted: 1 to 1440. | As above |
| Closed for (minutes) | How long the form stays closed to that connection: 1 to 1440. | As above |
Preview new numbers before you save
As soon as a form’s numbers differ from the saved ones, a sentence under them replays the new numbers against that form’s attempts from the last two days, beside what the saved numbers did. For example: “Against the 120 attempts recorded since (a date), these numbers would have held 14, from 2 connections. The saved numbers held 0, from 0.”
The replay treats every connection as verified, so it shows the most the numbers could have done. Attempts are only recorded while the form’s switch is on, and comments held while the form was closed were never recorded, so they are not in the replay. With nothing recorded, it says there is nothing to replay the numbers against.
How this fits with the hidden bot check
The hidden bot check and these limits do different jobs. The bot check turns away simple scripts on the sign-in, registration and comment forms by looking at how a submission arrives. The limits count how often one connection comes back. A script that gets past the first still meets the second. See the hidden bot check doc for what it covers.
What it can break, and how to undo
- A shared network. Everyone behind one public address, such as a school, an office or some mobile networks, shares one count. Their comments wait in moderation, their sign-ups are refused for a while, or their reset email does not arrive. Press Release now on the row under Lockouts, raise the number, or add the address to Always allowed. See Allow and block lists, and allowlisting an office without locking yourself out for how to keep that list short.
- “My reset email never came.” If the person asked many times from one connection, the request that reached the limit and those after it are answered without an email. They can wait for Closed for (minutes) to pass, or ask from another network.
- Turning a form off. Switch it off and press Save. With password confirmation on, a looser limit or a form switched off asks for your password.
Check it is working
- The Lockouts list. A closure shows as a row naming Comments, Password resets or Registration, with the network, the number of attempts and how long it lasts. Release now reopens the form for that connection.
- The activity log. “Form closed to a network” when a form closes, then “Comment held for moderation”, “Password reset requests slowed” or “Sign-up refused” for what it held or refused.
- The comments screen. Held comments wait under Pending, where you approve or remove them as usual.
Recommended settings
We recommend the defaults. They are set so that a person doing a normal thing quickly does not reach them. Use the replay before raising or lowering anything.
| Site | What we recommend |
|---|---|
| Blog or brochure site | Defaults. If readers often comment together from one school or office network, raise Closes at this many for comments; held comments are never lost. |
| Store (WooCommerce) | Defaults. Checkout account creation is never counted, so first-time orders are not affected. |
| Membership or course site | If a class or team signs up together from one network, raise Closes at this many for sign-ups, or add that network’s fixed address to Always allowed. |
For a blog with several writers, WordPress blog security: authors, editors, comments and visitors sets these limits beside two-factor for the roles that publish and the fixes that show visitors less.
On a multisite network, each site keeps its own counts and closures, so a connection closed out of one site’s forms can start again on another’s. An account is the same on every site, which matters most for password resets.
Frequently asked questions
Does the comment limit delete comments?
No. A comment sent while the form is closed goes to the moderation queue as pending, and a comment already marked as spam stays spam. You approve or remove held comments on the comments screen as usual.
Can this lock me out of my own dashboard?
No. These three forms are counted apart from sign-in, so activity on a public form cannot lock anyone out of the dashboard. Sign-in has its own sign-in lockouts.
Does a slowed password reset tell a stranger that an account exists?
No. On WordPress’s own reset form the request gets the same confirmation page a successful one gets, and on the WooCommerce My Account form it lands on the store’s own confirmation, so the form never reveals whether an account exists.
Are logged-in editors and shop managers counted?
People who can moderate comments are never counted on the comment form, and reset links sent from the dashboard by people who can edit users are never counted either.
What if several visitors share one network?
They share one count. Press Release now on the Lockouts row, raise the number, or add the network’s fixed address to Always allowed.
Conclusion
Comments, password resets and sign-ups are the three forms anyone can reach, so they are the three that get repeated. Request protection holds a burst of comments for moderation, answers repeated reset requests without sending email and refuses repeated sign-ups, all without touching accounts or your own dashboard. Keep the defaults, preview any change, and use Release now if a shared network is caught.
BetterShield is free on WordPress.org. The docs cover the forms in full: Public form limits and Login & Access.