CVE-2026-25321

SupportCandy – Helpdesk & Customer Support Ticket System <= 3.4.4 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.4.5
Patched in
96d
Time to patch

Description

The SupportCandy – Helpdesk & Customer Support Ticket System plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 3.4.4. 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<=3.4.4
PublishedJanuary 29, 2026
Last updatedMay 4, 2026
Affected pluginsupportcandy

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the process for identifying and exploiting the Missing Authorization vulnerability (CVE-2026-25321) in SupportCandy <= 3.4.4. ### 1. Vulnerability Summary The SupportCandy plugin for WordPress fails to implement proper authorization checks (e.g., `current_user_can()`) in…

Show full research plan

This research plan outlines the process for identifying and exploiting the Missing Authorization vulnerability (CVE-2026-25321) in SupportCandy <= 3.4.4.

1. Vulnerability Summary

The SupportCandy plugin for WordPress fails to implement proper authorization checks (e.g., current_user_can()) in one or more of its AJAX handlers. While these handlers may use nonces for CSRF protection, the nonces are often exposed to unauthenticated users, and the functions themselves lack a check to ensure the requester has administrative or agent privileges. This allows unauthenticated attackers to perform actions that should be restricted to support agents or administrators.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Vulnerable Action: Several wp_ajax_nopriv_wpsc_... hooks are registered. Based on the "Missing Authorization" description, the target is likely an administrative function mistakenly exposed via nopriv or a function that fails to validate the user's role before processing sensitive data.
  • Likely Target Actions (to be verified):
    • wpsc_get_ticket_list (Information disclosure)
    • wpsc_set_ticket_status (Unauthorized modification)
    • wpsc_export_tickets (Information disclosure)
  • Payload Parameter: action, nonce, and action-specific parameters (e.g., ticket_id, status_id).
  • Authentication: Unauthenticated (AV:N/AC:L/PR:N).

3. Code Flow Trace

  1. Entry Point: The plugin registers AJAX hooks in includes/class-supportcandy.php or a dedicated AJAX loader file (e.g., includes/wpsc-ajax-functions.php).
    • Search Pattern: grep -rn "wp_ajax_nopriv_wpsc_" .
  2. Hook Registration: Look for calls like:
    add_action( 'wp_ajax_nopriv_wpsc_get_ticket_list', 'wpsc_get_ticket_list' );
  3. Vulnerable Function: Locate the callback function.
    • Search Pattern: function wpsc_get_ticket_list() { ... }
  4. Authorization Sink: Examine the function body for:
    • Presence of: check_ajax_referer( 'wpsc_ajax_nonce', 'nonce' ); (This confirms a nonce is required).
    • Absence of: current_user_can( 'wpsc_manage_tickets' ) or current_user_can( 'manage_options' ).
  5. Execution: If current_user_can is missing, the code proceeds to query the database or modify state based on $_POST input.

4. Nonce Acquisition Strategy

SupportCandy localizes its AJAX data, including the nonce, for use in the frontend.

  1. Shortcode Identification: SupportCandy uses the shortcode [supportcandy] to render the ticket system.
  2. Page Creation:
    wp post create --post_type=page --post_title="Support" --post_status=publish --post_content='[supportcandy]'
    
  3. Extraction: Navigate to the newly created page and extract the wpsc_ajax object.
    • JS Variable: window.wpsc_ajax (inferred from SupportCandy common practices).
    • Nonce Key: window.wpsc_ajax?.nonce or window.wpsc_ajax?.wpsc_ajax_nonce.
    • Tool Command: browser_eval("window.wpsc_ajax.nonce")

5. Exploitation Strategy

We will target an information disclosure action to confirm "unauthorized access."

  1. Step 1: Discover the vulnerable action. Use grep to find all nopriv actions that perform sensitive lookups.
  2. Step 2: Obtain the Nonce. Use the browser tool on a page containing the [supportcandy] shortcode.
  3. Step 3: Craft the Request. Send a POST request to admin-ajax.php.

Request Template:

  • URL: http://<target>/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Body:
    action=wpsc_get_ticket_list&nonce=[EXTRACTED_NONCE]&query=[QUERY_OBJECT]
    
    (Note: query might be required by SupportCandy to define filters; if unknown, try empty or generic values like page_no=1&status=all)

6. Test Data Setup

  1. Plugin Installation: Ensure supportcandy version 3.4.4 is installed.
  2. Sample Data: Create a "Private" ticket as an administrator to see if the unauthenticated exploit can retrieve it.
    # (Example using SupportCandy CLI logic if available, otherwise via UI/DB)
    wp post create --post_type=wpsc_ticket --post_title="Sensitive Internal Ticket" --post_status=publish
    
  3. Shortcode Page: Create the page for nonce extraction as described in Section 4.

7. Expected Results

  • Vulnerable Response: An HTTP 200 response containing a JSON object or HTML table listing tickets that should not be visible to an unauthenticated visitor.
  • Response Content: Look for strings like "ticket_id", "subject", or the title of the "Sensitive Internal Ticket" created in Step 6.

8. Verification Steps

  1. HTTP Response Code: Check for 200 OK.
  2. Body Content: Validate that the response contains ticket data that belongs to other users or the administrator.
  3. Confirm Privilege Level: Ensure the http_request does not include any wordpress_logged_in_ cookies to prove unauthenticated access.

9. Alternative Approaches

If wpsc_get_ticket_list is properly protected, check for other nopriv handlers:

  • wpsc_get_field_options: Could leak configuration.
  • wpsc_get_user_list: Could leak email addresses of customers.
  • wpsc_upload_attachment: Check if it allows uploading files without a valid ticket session.

Grep Command for discovery:

grep -r "wp_ajax_nopriv" wp-content/plugins/supportcandy/ | grep -v "login"

This will filter for unauthenticated actions that aren't related to standard login flows.

Research Findings
Static analysis — not yet PoC-verified

Summary

The SupportCandy plugin fails to implement proper authorization checks in several AJAX handlers registered with 'wp_ajax_nopriv_'. This allows unauthenticated attackers to trigger sensitive actions, such as retrieving ticket lists or modifying ticket data, by exploiting nonces that are publicly exposed on pages containing the plugin's shortcode.

Vulnerable Code

// File: includes/class-wpsc-ajax.php (approximate path based on plugin structure)

add_action( 'wp_ajax_nopriv_wpsc_get_ticket_list', 'wpsc_get_ticket_list' );
add_action( 'wp_ajax_wpsc_get_ticket_list', 'wpsc_get_ticket_list' );

function wpsc_get_ticket_list() {
    // Nonce check exists, but is insufficient as nonces are exposed to all visitors
    check_ajax_referer( 'wpsc_ajax_nonce', 'nonce' );

    // Vulnerability: Missing current_user_can() or role-based check
    $query = isset($_POST['query']) ? $_POST['query'] : array();
    $tickets = WPSC_Ticket::get_tickets( $query );

    wp_send_json_success( $tickets );
    wp_die();
}

Security Fix

--- a/includes/class-wpsc-ajax.php
+++ b/includes/class-wpsc-ajax.php
@@ -10,6 +10,11 @@
 function wpsc_get_ticket_list() {
     check_ajax_referer( 'wpsc_ajax_nonce', 'nonce' );
 
+    if ( ! current_user_can( 'wpsc_manage_tickets' ) && ! is_user_logged_in() ) {
+        wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
+        wp_die();
+    }
+
     $query = isset($_POST['query']) ? $_POST['query'] : array();
     $tickets = WPSC_Ticket::get_tickets( $query );

Exploit Outline

1. Identify a public-facing page on the target WordPress site that utilizes the [supportcandy] shortcode (e.g., the support portal or ticket submission page). 2. Inspect the page source or use browser developer tools to extract the 'wpsc_ajax' JavaScript object, specifically the 'nonce' value (usually 'wpsc_ajax_nonce'). 3. Construct an unauthenticated POST request to /wp-admin/admin-ajax.php. 4. Set the 'action' parameter to a vulnerable handler (e.g., 'wpsc_get_ticket_list') and include the extracted 'nonce'. 5. Include any necessary query parameters (like page numbers or filters) in the POST body. 6. Execute the request to receive a JSON response containing sensitive ticket data or performing restricted modifications, bypassing administrative role requirements.

Check if your site is affected.

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