WP Manifestindependent plugin directory
manifest / security / lostpassword-hardening

Lost Password Hardening

Hardens the WordPress "Lost Password" page against bots and account enumeration — adds rate limiting, a honeypot field, and generic error responses.

by John Mark Bondad · github.com/john-mark-bondad/lostpassword-hardening · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/john-mark-bondad/lostpassword-hardening/archive/refs/heads/master.zip

A lightweight WordPress plugin that hardens the default wp-login.php?action=lostpassword page against bots and brute-force / account-enumeration attacks — without requiring a full security suite.

Why

The default WordPress "Lost Password" page has a few weaknesses out of the box:

  • It reveals whether a username or email exists on the site (account enumeration).
  • It has no rate limiting, so bots can submit the form thousands of times per minute.
  • It has no bot filtering (CAPTCHA, honeypot, etc.).
  • Failed/suspicious attempts aren't logged anywhere.

This plugin patches those gaps using WordPress core hooks only — no external dependencies, no API keys required.

Features

  • Rate limiting — throttles repeated password reset attempts per IP address (default: 3 attempts per 15 minutes).
  • Honeypot field — adds an invisible field to the form that only bots fill in; real visitors never see it.
  • Generic responses — always shows the same message ("If an account exists...") regardless of whether the username/email is valid, so attackers can't use the form to discover real accounts.
  • Request logging — logs reset requests, rate-limit hits, and honeypot triggers (with IP and timestamp) to your PHP error log for monitoring.
  • Shorter reset link lifetime — reduces the password reset link validity window from the WordPress default of 24 hours down to 12 hours.
  • Fail-safe error handling — every custom check is wrapped in try/catch, so a failure in this plugin logs an error instead of breaking the password reset flow for legitimate users.

Installation

Option A — Regular plugin (recommended for most sites)

  1. Download the latest release or clone this repo.
  2. Zip the lostpassword-hardening folder (or use the provided .zip).
  3. In wp-admin, go to Plugins → Add New → Upload Plugin and upload the zip.
  4. Click Activate.

Option B — Must-use plugin (always-on, can't be accidentally deactivated)

  1. Copy just lostpassword-hardening.php (not the folder) into wp-content/mu-plugins/.
  2. Create the mu-plugins folder if it doesn't already exist.
  3. That's it — mu-plugins load automatically, no activation step needed.

Note: mu-plugins don't support subfolders being auto-loaded, so this file must sit loose directly inside mu-plugins/, not inside its own directory.

Verifying it works

  • Submit the lost password form more than 3 times in a row from the same IP — you should see "Too many password reset attempts" on the 4th try.
  • Check your PHP error log (or wp-content/debug.log if WP_DEBUG_LOG is enabled in wp-config.php) for entries prefixed with [LostPassword].

Configuration

All settings are constants inside lostpassword-hardening.php:

Setting Location Default
Max attempts before throttling Section 1 ($max_attempts) 3
Throttle window Section 1 ($window_seconds) 15 minutes
Reset link expiration Section 5 (password_reset_expiration filter) 12 hours

Edit these values directly in the file to adjust thresholds.

This plugin covers the application-level gaps in the lost password flow. For a fuller security posture, consider pairing it with:

  • A WAF or IP-level rate limiter (Cloudflare, Wordfence, Sucuri) in front of wp-login.php.
  • CAPTCHA (reCAPTCHA v3 / hCaptcha) on the login and lost-password forms.
  • Two-factor authentication for all user accounts.
  • Disabling XML-RPC if you don't need it.

License

GPL-2.0-or-later — see LICENSE or https://www.gnu.org/licenses/gpl-2.0.html

Author

John Mark Bondad GitHub