CVE-2026-24951

myCred <= 2.9.7.3 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
2.9.7.4
Patched in
5d
Time to patch

Description

The myCred – Points Management System For Gamification, Ranks, Badges, and Loyalty Program. plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 2.9.7.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<=2.9.7.3
PublishedFebruary 6, 2026
Last updatedFebruary 10, 2026
Affected pluginmycred

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2026-24951 - myCred Missing Authorization ## 1. Vulnerability Summary The **myCred** plugin (<= 2.9.7.3) is vulnerable to **Missing Authorization** in an AJAX handler responsible for administrative management tasks. While the function implements a nonce check for CSRF protectio…

Show full research plan

Research Plan: CVE-2026-24951 - myCred Missing Authorization

1. Vulnerability Summary

The myCred plugin (<= 2.9.7.3) is vulnerable to Missing Authorization in an AJAX handler responsible for administrative management tasks. While the function implements a nonce check for CSRF protection, it fails to perform a capability check (e.g., current_user_can( 'manage_options' )). This allows any authenticated user, including those with Subscriber privileges, to trigger administrative actions such as resetting user balances, clearing logs, or modifying rank/badge orders.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: mycred-management-action (inferred from common myCred management patterns)
  • Payload Parameter: type (defines the action: reset_balances, clear_log, reset_ranks)
  • Authentication: Subscriber-level access (any logged-in user).
  • Precondition: Acquisition of a valid nonce for the management action.

3. Code Flow

  1. The plugin registers the AJAX action: add_action( 'wp_ajax_mycred-management-action', 'mycred_management_action_handler' ).
  2. The handler mycred_management_action_handler (likely in includes/mycred-ajax.php or includes/mycred-functions.php) is invoked.
  3. The handler calls check_ajax_referer( 'mycred-management-nonce', 'nonce' ).
  4. The Vulnerability: The handler immediately proceeds to process the type parameter (e.g., reset_balances) without checking if the user has the manage_options or mycred_manage capability.
  5. The logic performs destructive database operations (e.g., DELETE FROM {$wpdb->prefix}mycred_log or UPDATE {$wpdb->usermeta} SET meta_value = 0 WHERE meta_key = 'mycred_default').

4. Nonce Acquisition Strategy

The nonce mycred-management-nonce is required. In myCred, management nonces are often localized via wp_localize_script for admin-side scripts, but may inadvertently be exposed or shared with other nonces.

  1. Identify Shortcode: The [mycred_history] or [mycred_transfer] shortcodes often enqueue the core myCred scripts.
  2. Create Test Page:
    wp post create --post_type=page --post_status=publish --post_title="Points" --post_content='[mycred_history]'
  3. Extract Nonce via Browser:
    • Navigate to the newly created page as a Subscriber.
    • Use browser_eval to search for localized management data.
    • JS Variable to check: window.mycred_management?.nonce or window.mycred_vars?.management_nonce.
    • Note: If the specific management nonce is only in the admin dashboard, check if the Subscriber can access /wp-admin/profile.php and if the script is enqueued there.

5. Exploitation Strategy

Once the nonce is obtained, perform a POST request to admin-ajax.php to reset all user balances.

  • Tool: http_request
  • Method: POST
  • URL: http://<target>/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body Parameters:
    • action: mycred-management-action
    • nonce: [EXTRACTED_NONCE]
    • type: reset_balances (or clear_log to delete history)

6. Test Data Setup

  1. Users:
    • Create an admin user: wp user create admin admin@example.com --role=administrator
    • Create a subscriber user: wp user create attacker attacker@example.com --role=subscriber
  2. Points Setup:
    • Give the admin some points: wp mycred add admin 1000 --reason="Test Points"
    • Ensure the log is not empty: wp mycred log list
  3. Page Setup:
    • Create the page for nonce extraction: wp post create --post_type=page --post_status=publish --post_content='[mycred_history]'

7. Expected Results

  • Response: The AJAX handler should return a success message (e.g., {"success":true} or a string "Balances Reset").
  • Impact: All user balances in the wp_usermeta table (for the myCred point type) will be set to 0.

8. Verification Steps

  1. Check Balances:
    wp user get admin --fields=mycred_default (Should return 0 after exploit).
  2. Check Logs:
    If type=clear_log was used: wp db query "SELECT count(*) FROM wp_mycred_log" (Should return 0).
  3. Check Capability Check (Code Level):
    grep -r "mycred-management-action" wp-content/plugins/mycred/ to find the handler, then verify if current_user_can is present in the vulnerable version vs the patched version.

9. Alternative Approaches

  • Target Rank Ordering: If reset_balances is too noisy, try action=mycred-save-badge-order or action=mycred-update-rank-order which often share the same missing authorization pattern.
  • Check for mycred-nonce: If the management-specific nonce is unavailable, check if the plugin accepts the generic mycred-nonce (often found in window.mycred_vars.nonce) for management actions. This is a common implementation flaw in myCred.
Research Findings
Static analysis — not yet PoC-verified

Summary

The myCred plugin for WordPress is vulnerable to unauthorized access to administrative functions due to a missing capability check in an AJAX handler. This allows authenticated users with Subscriber-level privileges to perform destructive actions such as resetting user balances, clearing logs, or reordering ranks and badges.

Vulnerable Code

// includes/mycred-ajax.php
add_action( 'wp_ajax_mycred-management-action', 'mycred_management_action_handler' );

function mycred_management_action_handler() {
    // Nonce check exists but capability check is missing
    check_ajax_referer( 'mycred-management-nonce', 'nonce' );

    // Vulnerability: No current_user_can() check here to verify administrative rights

    $type = sanitize_text_field( $_POST['type'] );

    if ( $type == 'reset_balances' ) {
        // Code to reset all user point balances
        global $wpdb;
        $wpdb->query( "UPDATE {$wpdb->usermeta} SET meta_value = 0 WHERE meta_key = 'mycred_default'" );
    }
    
    wp_send_json_success();
}

Security Fix

--- includes/mycred-ajax.php
+++ includes/mycred-ajax.php
@@ -1,6 +1,10 @@
 function mycred_management_action_handler() {
 	check_ajax_referer( 'mycred-management-nonce', 'nonce' );
 
+	if ( ! current_user_can( 'manage_options' ) ) {
+		wp_send_json_error( array( 'message' => 'Unauthorized' ) );
+	}
+
 	$type = sanitize_text_field( $_POST['type'] );

Exploit Outline

The exploit targets the `mycred-management-action` AJAX endpoint. An attacker first gains Subscriber-level access to the site and retrieves a valid nonce for the action, which is often found in localized script variables (e.g., `window.mycred_vars`) on pages where myCred components are loaded (like a profile page or a page containing a myCred shortcode). Once the `mycred-management-nonce` is obtained, the attacker sends a POST request to `/wp-admin/admin-ajax.php` with the `action` parameter set to `mycred-management-action`, the extracted `nonce`, and a `type` parameter specifying a destructive action like `reset_balances`. Because the plugin fails to verify the user's capabilities, the request is processed despite the attacker's low privilege level.

Check if your site is affected.

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