Make WordPress Core

Opened 5 weeks ago

Last modified 5 weeks ago

#64862 new defect (bug)

Application Passwords: Add rate limiting to prevent brute-force attacks

Reported by: vrutti22's profile vrutti22 Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.7
Component: Users Keywords: has-patch security needs-unit-tests
Focuses: Cc:

Description

Problem

wp_authenticate_application_password() in wp-includes/user.php
has no rate limiting. An attacker can make unlimited REST API
requests guessing application passwords with no lockout.

Unlike cookie login, there is no CAPTCHA, no lockout, and
wp_login_failed hook is not reliably triggered for plugins to hook into.

Proposed Fix

Add transient-based IP rate limiting inside
wp_authenticate_application_password(), with a filter
application_password_login_max_attempts so site owners
can configure the threshold.

Steps to Reproduce

  1. Create an Application Password for any user
  2. Send repeated REST API requests with wrong password
  3. No lockout occurs — requests continue indefinitely

Expected

After N failed attempts from same IP, return WP_Error with HTTP 429.

Actual

No rate limiting. Unlimited attempts allowed.

Attachments (1)

wp-app-password-rate-limit.diff (10.6 KB) - added by vrutti22 5 weeks ago.
== Steps to Reproduce == 1. Create an Application Password for any WordPress user 2. Make repeated REST API requests with wrong password using Basic Auth 3. Observe: no lockout, no 429, unlimited attempts == Expected Behavior == After N failed attempts from same IP, return WP_Error with HTTP 429 and a transient-based lockout. == Proposed Fix == Transient-based rate limiting inside wp_authenticate_application_password() with two filters for site owners to configure: - application_password_login_max_attempts (default: 5) - application_password_lockout_duration (default: 10 minutes) Patch + unit tests (6 test cases) attached.

Download all attachments as: .zip

Change History (3)

@vrutti22
5 weeks ago

Steps to Reproduce == 1. Create an Application Password for any WordPress user 2. Make repeated REST API requests with wrong password using Basic Auth 3. Observe: no lockout, no 429, unlimited attempts == Expected Behavior == After N failed attempts from same IP, return WP_Error with HTTP 429 and a transient-based lockout. == Proposed Fix == Transient-based rate limiting inside wp_authenticate_application_password() with two filters for site owners to configure: - application_password_login_max_attempts (default: 5) - application_password_lockout_duration (default: 10 minutes) Patch + unit tests (6 test cases) attached.

#1 @vrutti22
5 weeks ago

  • Component changed from General to Users
  • Keywords has-patch needs-unit-tests added; needs-patch removed

This ticket was mentioned in Slack in #core by vrutika_darji. View the logs.


5 weeks ago

Note: See TracTickets for help on using tickets.