Hr Press Lite <= 1.0.2 - Missing Authorization to Authenticated (Subscriber+) Sensitive Employee Information Exposure
Description
The Hr Press Lite plugin for WordPress is vulnerable to unauthorized access of sensitive employee data due to a missing capability check on the `hrp-fetch-employees` AJAX action in all versions up to, and including, 1.0.2. This makes it possible for authenticated attackers, with Subscriber-level access and above, to retrieve sensitive employee information including names, email addresses, phone numbers, salary/pay rates, employment dates, and employment status.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=1.0.2# Exploitation Research Plan: CVE-2026-2720 (Hr Press Lite) ## 1. Vulnerability Summary The **Hr Press Lite** plugin (<= 1.0.2) is vulnerable to sensitive information exposure due to a missing authorization check (capability check) in the AJAX handler for the action `hrp-fetch-employees`. While the…
Show full research plan
Exploitation Research Plan: CVE-2026-2720 (Hr Press Lite)
1. Vulnerability Summary
The Hr Press Lite plugin (<= 1.0.2) is vulnerable to sensitive information exposure due to a missing authorization check (capability check) in the AJAX handler for the action hrp-fetch-employees. While the handler is registered via wp_ajax_, which restricts access to authenticated users, it fails to verify if the authenticated user has the necessary permissions (e.g., manage_options or hrp_manage_employees) to view sensitive employee data. This allows any user with a Subscriber role or higher to retrieve a full list of employees, including private details like salary, phone numbers, and employment status.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
hrp-fetch-employees - Method:
POST(typically for AJAX actions in this plugin) orGET. - Vulnerable Parameter: The action itself triggers the data dump. There may be optional pagination or search parameters (e.g.,
length,start,search[value]) if the plugin uses DataTables. - Authentication: Authenticated user session (Subscriber role is sufficient).
- Preconditions: At least one employee record must exist in the plugin's database to demonstrate data exposure.
3. Code Flow (Inferred)
- Registration: The plugin registers the AJAX hook in a file like
includes/class-hrp-ajax.phpor the main plugin file:add_action( 'wp_ajax_hrp-fetch-employees', array( $this, 'hrp_fetch_employees' ) ); - Handler Entry: The function
hrp_fetch_employees()is called when theadmin-ajax.phprequest is processed. - Missing Check: The handler likely checks for a nonce (for CSRF) but fails to call
current_user_can(). - Data Retrieval: The function queries a custom table (e.g.,
{$wpdb->prefix}hrp_employees) using$wpdb->get_results(). - Sink: The results, including sensitive columns like
salary,pay_rate, andphone, are passed towp_send_json_success()orecho json_encode().
4. Nonce Acquisition Strategy
The AJAX handler likely implements a nonce check using check_ajax_referer or wp_verify_nonce.
- Nonce Action: Likely
hrp-nonce,hrp_ajax_nonce, orhrp-fetch-employees(inferred). - Localization Key: The plugin likely uses
wp_localize_scriptto pass the nonce to the frontend. - Strategy:
- Log in as a Subscriber user.
- Navigate to a page where the Hr Press Lite scripts are loaded. If the scripts only load on admin pages, check if the plugin adds a menu item for subscribers (unlikely) or if it enqueues scripts on the profile page.
- If no public/subscriber page enqueues the script, check the main dashboard (
/wp-admin/index.php). - JS Variable Search: Use
browser_evalto search for localized objects. Common prefixes:hrp_ajax,hrp_obj, orhrp_vars. - Execution Command:
browser_eval("window.hrp_ajax_obj?.nonce")(inferred name).
5. Exploitation Strategy
Step 1: Authentication
Authenticate as a Subscriber user and maintain the session cookies.
Step 2: Nonce Extraction
Navigate to the WordPress dashboard as the Subscriber and extract the nonce.
- URL:
/wp-admin/index.php - Tool:
browser_evalto find the nonce in the global JS scope.
Step 3: Data Extraction Request
Send a POST request to the AJAX endpoint with the identified action and nonce.
- Tool:
http_request - Request Details:
(Note: The nonce parameter name might bePOST /wp-admin/admin-ajax.php HTTP/1.1 Content-Type: application/x-www-form-urlencoded action=hrp-fetch-employees&security=[NONCE_VALUE]security,_wpnonce, ornonce—this must be verified during the research phase viagrepon the source code.)
Step 4: Response Parsing
Analyze the JSON response. A successful exploit will return a JSON object containing an array of employee records with keys like:
first_name,last_nameemailphonesalary/pay_rate(The critical sensitive data)joining_date
6. Test Data Setup
To ensure a successful PoC, the environment must be seeded with employee data:
- Create Employee: Use the WordPress admin (as Administrator) to navigate to the Hr Press Lite menu and add an employee.
- Name: "John Doe"
- Email: "john@example.com"
- Salary: "50000"
- Phone: "555-0199"
- Create Attacker: Create a user with the
subscriberrole.wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
7. Expected Results
- Status Code: 200 OK
- Response Body: A JSON string containing the full list of employees.
- Example:
{ "success": true, "data": [ { "id": "1", "first_name": "John", "last_name": "Doe", "email": "john@example.com", "phone": "555-0199", "salary": "50000", ... } ] }
8. Verification Steps
- Confirm Role: Use
wp user get attackerto verify the user is only a Subscriber. - Compare Data: Compare the JSON output from the exploit with the actual database content:
wp db query "SELECT * FROM wp_hrp_employees;"(or the appropriate table name found viawp db tables).
- Verify Lack of Auth: Check the plugin source code for the
hrp_fetch_employeesfunction to confirm there is nocurrent_user_can()call.
9. Alternative Approaches
- Parameter Brute-forcing: If
action=hrp-fetch-employeesreturns nothing, try adding DataTables parameters:draw=1&start=0&length=10. - Direct Database ID: If the endpoint requires a specific ID, try
action=hrp-fetch-employees&id=1. - Search Query: Try
action=hrp-fetch-employees&search[value]=@to force a wildcard search if the default response is empty. - Bypassing Nonce: If the nonce is required but hard to find, check if
check_ajax_referer( '...', '...', false )is used (thefalsethird argument preventsdie(), allowing potential bypass).
Summary
The Hr Press Lite plugin for WordPress is vulnerable to sensitive information exposure due to a missing authorization check in the `hrp-fetch-employees` AJAX handler. This allows authenticated users with Subscriber-level permissions or higher to retrieve private employee data, including salary details, contact information, and employment status.
Vulnerable Code
// Inferred from registration hook in plugin source add_action( 'wp_ajax_hrp-fetch-employees', array( $this, 'hrp_fetch_employees' ) ); --- // Likely handler logic without capability checks public function hrp_fetch_employees() { check_ajax_referer( 'hrp-nonce', 'security' ); global $wpdb; $table_name = $wpdb->prefix . 'hrp_employees'; $results = $wpdb->get_results( "SELECT * FROM $table_name" ); wp_send_json_success( $results ); }
Security Fix
@@ -10,6 +10,10 @@ public function hrp_fetch_employees() { check_ajax_referer( 'hrp-nonce', 'security' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Unauthorized' ) ); + } + global $wpdb; $table_name = $wpdb->prefix . 'hrp_employees'; $results = $wpdb->get_results( "SELECT * FROM $table_name" );
Exploit Outline
The exploit involves authenticating as a low-privileged user (Subscriber) and triggering the vulnerable AJAX action. 1. Log in to the WordPress site as a Subscriber. 2. Extract the AJAX security nonce from the global JavaScript scope (commonly localized under objects like hrp_ajax_obj). 3. Send a POST request to /wp-admin/admin-ajax.php with the action parameter set to 'hrp-fetch-employees' and the extracted nonce in the security parameter. 4. The server returns a JSON object containing full employee records, including sensitive fields such as salary, phone numbers, and joining dates.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.