CVE-2025-49978
Executive Summary
CVE-2025-49978 is an Authorization Bypass Through User-Controlled Key vulnerability in the Eyecix JobSearch WordPress plugin (versions prior to 3.0.6). This flaw allows an unauthenticated attacker to manipulate a user-controlled key (likely a parameter such as job_id, user_id, or a nonce) to access or modify resources that should be protected by access control checks. The vulnerability is classified as CWE-639: Authorization Bypass Through User-Controlled Key.
Given that this is a WordPress plugin vulnerability, the attack surface is broad, as JobSearch is a popular recruitment plugin. The CVSS score of 4.3 (Medium) reflects the low complexity and network-based attack vector, but the impact is limited to confidentiality (low) with no integrity or availability impact. The EPSS score of 0.0% indicates very low exploitation activity in the wild, but the lack of a vendor patch makes this a ticking time bomb for unpatched sites.
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 resides in a WordPress plugin ecosystem. The plugin is distributed via the official WordPress plugin repository and third-party marketplaces. Since no patch is available, site administrators must treat this as a supply chain risk: any site running JobSearch < 3.0.6 is vulnerable. The plugin’s update mechanism may not push a fix, so manual intervention (e.g., disabling the plugin or applying a virtual patch via WAF) is required.
CVSS Breakdown & Threat Level
| Metric | Value |
|---|---|
| Attack Vector (AV) | Network (N) |
| Attack Complexity (AC) | Low (L) |
| Privileges Required (PR) | None (N) |
| User Interaction (UI) | None (N) |
| Scope (S) | Unchanged (U) |
| Confidentiality (C) | Low (L) |
| Integrity (I) | None (N) |
| Availability (A) | None (N) |
| Base Score | 4.3 (Medium) |
Threat Level: Medium. The vulnerability is easy to exploit but only allows limited information disclosure (e.g., viewing other users’ job applications, candidate details, or internal IDs). It does not allow data modification or privilege escalation.
Deep Dive & Mechanics
The vulnerability stems from the plugin’s failure to validate that the user-controlled key (e.g., job_id, application_id, or user_id) belongs to the authenticated user or is authorized for the current session. In WordPress plugins, such keys are often passed via GET or POST parameters to fetch or modify resources. Without proper authorization checks, an attacker can enumerate or manipulate these keys to access data belonging to other users.
Example Attack Flow:
- An authenticated user (or even an unauthenticated user if the endpoint is public) submits a job application. The plugin generates a unique application ID.
- The attacker intercepts the request and changes the
application_idparameter to another value (e.g., incrementing by 1). - The plugin returns the details of another user’s application, including personal data (name, email, phone, resume URL).
The root cause is the lack of a current_user_can() or wp_verify_nonce() check on the affected endpoints. The plugin likely uses a direct database query without verifying ownership.
Vulnerable vs. Patched Code
Since no official patch is available, the following is a hypothetical comparison based on common fixes for CWE-639.
Vulnerable Code (JobSearch < 3.0.6):
// In a REST endpoint or AJAX handler
$application_id = $_GET['application_id'];
$application = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}job_applications WHERE id = %d", $application_id));
echo json_encode($application);
Patched Code (Hypothetical fix):
$application_id = intval($_GET['application_id']);
$current_user_id = get_current_user_id();
$application = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}job_applications WHERE id = %d AND user_id = %d",
$application_id,
$current_user_id
));
if (!$application) {
wp_die('Unauthorized', 403);
}
echo json_encode($application);
The patched version adds a user_id check to ensure the application belongs to the current user.
Exploitation & Lab Setup
Red Team (Exploitation)
Since no public exploit code exists, the following is a conceptual proof-of-concept.
Prerequisites:
- A WordPress site with JobSearch plugin version < 3.0.6.
- A valid (or no) user session.
Exploit Steps:
- Identify the vulnerable endpoint. Common endpoints include:
/wp-admin/admin-ajax.php?action=jobsearch_get_application&application_id=X/wp-json/jobsearch/v1/application/{id}
- Send a GET request with a manipulated
application_id:curl -v "http://target.com/wp-admin/admin-ajax.php?action=jobsearch_get_application&application_id=1" - Iterate through IDs to extract data:
for i in {1..100}; do curl -s "http://target.com/wp-admin/admin-ajax.php?action=jobsearch_get_application&application_id=$i" | jq '.' done
Expected Output: JSON containing applicant details (name, email, phone, resume URL).
Blue Team (Detection & Hardening)
Detection:
- Monitor for sequential ID enumeration in access logs:
grep "admin-ajax.php" /var/log/nginx/access.log | grep "application_id" | awk '{print $1, $7}' | sort | uniq -c | sort -nr - Look for spikes in 200 responses to the same endpoint with different
application_idvalues.
Hardening:
- Apply a virtual patch using a Web Application Firewall (WAF) rule to block requests with manipulated
application_idparameters. - Disable the plugin until an official patch is released.
- Implement server-side rate limiting on AJAX endpoints.
Indicators of Compromise (IOCs)
- Network IOCs:
- Repeated GET requests to
/wp-admin/admin-ajax.phpwith varyingapplication_idparameters. - Requests to
/wp-json/jobsearch/v1/application/{id}with sequential IDs.
- Repeated GET requests to
- File IOCs:
- Unusual entries in WordPress debug log (
wp-content/debug.log) showingUndefined array keyorUnauthorizederrors.
- Unusual entries in WordPress debug log (
- Log IOCs:
- Apache/Nginx access logs showing patterns like:
192.168.1.100 - - [10/May/2025:12:00:00 +0000] "GET /wp-admin/admin-ajax.php?action=jobsearch_get_application&application_id=1 HTTP/1.1" 200 1234 192.168.1.100 - - [10/May/2025:12:00:01 +0000] "GET /wp-admin/admin-ajax.php?action=jobsearch_get_application&application_id=2 HTTP/1.1" 200 1234
- Apache/Nginx access logs showing patterns like:
Detection Engineering
YARA Rule
rule CVE_2025_49978_JobSearch_AuthBypass {
meta:
description = "Detects exploitation attempts of CVE-2025-49978 in Eyecix JobSearch plugin"
author = "Valters IT"
date = "2025-05-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-49978"
strings:
$ajax_action = "admin-ajax.php"
$action_param = "action=jobsearch_get_application"
$id_param = "application_id="
condition:
all of them
}
Sigma Rule
title: CVE-2025-49978 JobSearch Authorization Bypass
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects sequential ID enumeration attempts against JobSearch plugin
author: Valters IT
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'GET'
cs-uri-query|contains: 'admin-ajax.php'
cs-uri-query|contains: 'action=jobsearch_get_application'
cs-uri-query|contains: 'application_id='
condition: selection
falsepositives:
- Legitimate use of the plugin by administrators
level: medium
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-49978 JobSearch Authorization Bypass Attempt"; flow:to_server; content:"GET"; http_method; content:"admin-ajax.php"; http_uri; content:"action=jobsearch_get_application"; http_uri; content:"application_id="; http_uri; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the plugin if it is not critical to business operations.
- Apply a virtual patch using a WAF (e.g., ModSecurity, Cloudflare) to block requests with manipulated
application_idparameters. - Monitor logs for the IOCs listed above.
Long-term Fix:
- Since no official patch exists, consider forking the plugin and adding authorization checks (as shown in the patched code example).
- Contact the vendor (Eyecix) for an update or timeline.
- Evaluate alternative job board plugins that are actively maintained.
Workaround:
- Restrict access to the vulnerable endpoints via
.htaccess:
(Note: This will break legitimate AJAX functionality; use with caution.)<Files "admin-ajax.php"> Require all denied </Files>
Valters IT
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.