| 开发者 | michael.damoiseau |
|---|---|
| 更新时间 | 2026年6月15日 18:24 |
| 捐献地址: | 去捐款 |
| PHP版本: | 3.5.1 及以上 |
| WordPress版本: | 7.0 |
| 版权: | GPLv2 or later |
| 版权网址: | 版权信息 |
IP only or IP + username to reduce false positives on shared networks/wp-login.phpwp wp-login-delay unlock-ip <ip> and wp wp-login-delay flush-lockoutswp-login-delay folder to the /wp-content/plugins/ directoryWhen a bot attempts a brute-force attack, it tries thousands of passwords as fast as possible. By adding a delay (even just 1 second) after each failed attempt, the attack becomes impractical. A one-second delay is barely noticeable to legitimate users but makes a huge difference when multiplied across thousands of attempts.
Go to Settings > Login Delay Shield
Protection profiles are guided presets in the Security Setup Wizard. Applying a profile updates the main delay, progressive delay, lockout, email alert, and authentication endpoint settings, while still leaving every individual control editable.
Progressive delay increases the wait time with each consecutive failed attempt from the same IP address. For example, the first failure might delay 1 second, the second failure 2 seconds, and so on. This makes repeated attacks increasingly slow.
After a configurable number of failed attempts (default: 10), login attempts are temporarily blocked. You can choose whether attempts are counted by IP only or by IP + username (recommended for shared office/mobile IPs). Lockout duration is configurable (default: 60 minutes).
When lockout is enabled, failed logins show how many attempts remain before temporary lockout. If lockout is triggered, the error message includes a countdown (for example, "try again in 2 minutes") so users know when to retry.
Enable the IP whitelist feature and add your IP address (or a range using CIDR notation like 192.168.1.0/24). Whitelisted IPs bypass all delays and lockouts, ensuring you never lock yourself out.
You can always get back in. Lockouts are temporary by design (24 hours maximum — there are no permanent bans), so waiting always works. To recover immediately:
wp wp-login-delay unlock-ip <ip> or wp wp-login-delay flush-lockouts.define( 'WLDELAY_SAFE_MODE', true ); to wp-config.php — this safe mode disables all delays and lockouts until you remove the line (a warning shows in the admin while it is active).No. Login Delay Shield is completely free: no ads, no upsells, no premium tier, no account, and no API keys. Every admin notice is dismissible.
Some plugins that move the login page can lock you out behind a 404 with no way back. Login Delay Shield ships an emergency bypass: add define( 'WLDELAY_DISABLE_CUSTOM_LOGIN', true ); to wp-config.php and the standard wp-login.php works again immediately — no need to disable the plugin. The custom slug also uses raw path matching, so it keeps working even with stale rewrite rules or plain permalinks.
Yes: enable "Trust proxy headers" under Advanced settings. Behind a proxy or CDN, every visitor reaches your server from the proxy's IP address — without this setting, one attacker's failed logins would count against everyone and could lock out all users. With it enabled, the plugin reads the visitor's real IP from CF-Connecting-IP (accepted only when the connection actually comes from Cloudflare's published IP ranges, so it cannot be spoofed), X-Sucuri-ClientIP, Client-IP, X-Real-IP, or X-Forwarded-For. The settings page shows a warning when it detects a proxy while this setting is off — and the reverse warning if it is on without a proxy in front, since that would allow IP spoofing.
If you don't use the WordPress mobile app or remote publishing tools like Windows Live Writer, blocking XML-RPC authentication removes a common attack vector. You can also choose to just apply delays without blocking it entirely.
Yes, for most sites. Attackers can abuse password reset forms to probe accounts or create noise during credential attacks. Password reset protection applies the same delay and lockout behavior used for login attempts, logs the source as password-reset, and keeps messages generic so the form does not reveal whether a username or email exists.
When enabled, the plugin tracks failed login attempts per IP address. Once the threshold is reached (default: 5 attempts), an email is sent to alert you. The counter resets after one hour of no failed attempts from that IP.
A dashboard widget shows the 10 most recent failed login attempts, including the time, username attempted, IP address, and source. It also includes a lightweight 7-day trends panel with daily totals, top sources, top IPs, and top targeted usernames. The widget is only visible to administrators (manage_options). Note: because the log records whatever was typed into the username field, a user who accidentally types their password there will have it shown in the widget and stored in the log — treat the log as sensitive.
Enable fail2ban logging under Settings > Login Delay Shield > Login Log. If the log path is empty, Login Delay Shield writes to login-delay-shield-fail2ban/login-delay-shield-fail2ban.log in a plugin-owned temporary directory outside the WordPress uploads tree and adds basic .htaccess/index.html protections. Custom paths are restricted to the protected default directory by default; use the wldelay_fail2ban_allowed_log_dirs filter only for server-protected directories. If a custom path is rejected, logging is disabled instead of silently writing somewhere else. If lockout-event logging is enabled, an attempt that triggers a lockout may produce both a failed login line and a lockout line, so tune your jail's maxretry accordingly. The log is rotated to a single .log.1 backup once it reaches 5 MB so it cannot grow without bound; adjust or disable this with the wldelay_fail2ban_max_log_bytes filter (return 0 to rely on system logrotate instead).
Log lines include an ISO-8601 timestamp, stable prefix, and fields such as:
2026-05-04T12:00:00+00:00 Login Delay Shield: failed login source=wp-login ip=203.0.113.10 username=admin
A fail2ban filter can match the IP with the exact canonical failregex:
failregex = ^\s*\S+ Login Delay Shield: (?:failed login|lockout) source=\S+ ip=<HOST> username=\S+$
The Download fail2ban config button on the settings page generates the exact filter and jail files — prefer it over copying by hand.
Yes! Login Delay Shield follows WCAG 2.1 accessibility guidelines. All settings are fully keyboard navigable, screen reader compatible, and include proper ARIA attributes. Collapsible sections can be toggled with Enter or Space keys, tooltips appear on focus (not just hover), and all dynamic changes are announced to assistive technologies.
For high-traffic sites or sites experiencing frequent attacks, we recommend using a persistent object cache like Redis or Memcached. The plugin uses WordPress transients to track failed login attempts and lockouts per IP address. By default, transients are stored in the database. During a distributed brute-force attack (many IPs), this can create additional database queries. With an object cache installed:
Login Delay Shield is translated into 18 languages:
wldelay_help_base_url) and can be disabled.
Improvements:
.distignore so automated deploys ship only runtime files.uninstall.php; the uninstall cleanup routine itself always shipped correctly.CF-Connecting-IP (accepted only when the connection comes from Cloudflare's published IP ranges, so it cannot be spoofed), X-Sucuri-ClientIP, and X-Real-IP.WLDELAY_SAFE_MODE emergency constant — define it as true in wp-config.php to disable all delays and lockouts while you recover access. A persistent admin warning shows while it is active.wldelay_send_custom_login_email filter).
Security:
WLDELAY_DISABLE_CUSTOM_LOGIN emergency bypass and prompts you to bookmark the new URL before enabling.
.log.1 backup once it reaches 5 MB, preventing unbounded growth on installs without external log rotation. Configure or disable via the new wldelay_fail2ban_max_log_bytes filter..htaccess, index.html, index.php) are now written to every fail2ban log directory, including custom directories added via the wldelay_fail2ban_allowed_log_dirs filter.
Maintenance:
password-reset).get_option() calls in fail2ban and sanitization test suites.
wp plugin check failing in CI because the plugin-check plugin was not activated before use.wldelay_normalize_username filter hook for LDAP, email-as-login, and SSO backends.username column for faster GROUP BY queries at scale.
wldelay_get_login_log_summary() with full nested array structures.wldelay_get_top_ips(), wldelay_get_top_usernames(), and wldelay_get_daily_attempts() for dashboard trend data.
Bug Fixes:
wp_unslash() on login username that could corrupt usernames with literal backslashes.
wp_login_url filter name (was wp_login_url, should be login_url) preventing URL rewriting./wp-login.php is accessed through the front controller.login_init blocking internal WordPress paths (e.g. /wp/wp-login.php) used for legitimate auth redirects.
Improvements:
wp-json, wp-content, wp-includes, wp-signup, wp-activate, xmlrpc, feed, robots, sitemap.
wldelay_unlock_current_ip_should_exit filter with WP_TESTS_DOMAIN constant check — no longer exposes a testability surface in production.esc_html__() for i18n completeness.wp_unslash() before sanitize_user() in login username extraction to correctly handle WordPress magic-quote slashes.__() for full i18n/l10n support.admin.js file, loaded via wp_enqueue_script().wp_localize_script() to pass PHP-side translatable strings to JavaScript (Enabled/Disabled badge labels).<label> association across all settings field callbacks.data-section attributes from settings card elements./my-login). When enabled, direct access to wp-login.php is blocked and all auth flows (login, logout, lost password, password reset) are routed through the custom slug.WLDELAY_DISABLE_CUSTOM_LOGIN in wp-config.php to restore access to wp-login.php without disabling the plugin.wp_login_url, logout_url, lostpassword_url) and password-reset emails are transparently updated to use the custom slug.
Improvements:
wldelay_2fa_providers filter hook for adding custom 2FA provider detection.
Improvements:
wldelay-health-notice for clearer semantics.1=1 WHERE sentinel from query builder in favour of conditional clause construction.wldelay_2fa_providers filter callback with type validation to guard against malformed return values.source column for faster filtered queries.$wpdb->prepare() for defense-in-depth.wldelay_log_* keys only.wp wp-login-delay unlock-ip <ip>wp wp-login-delay flush-lockoutsrest) and application-password (application-password) auth failures.IP only and IP + username to reduce false positives on shared networks.