CVE-2026-2720

Hr Press Lite <= 1.0.2 - Missing Authorization to Authenticated (Subscriber+) Sensitive Employee Information Exposure

mediumMissing Authorization
6.5
CVSS Score
6.5
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
High
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=1.0.2
PublishedMarch 20, 2026
Last updatedApril 15, 2026
Affected pluginhr-press-lite
Research Plan
Unverified

# 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) or GET.
  • 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)

  1. Registration: The plugin registers the AJAX hook in a file like includes/class-hrp-ajax.php or the main plugin file:
    add_action( 'wp_ajax_hrp-fetch-employees', array( $this, 'hrp_fetch_employees' ) );
    
  2. Handler Entry: The function hrp_fetch_employees() is called when the admin-ajax.php request is processed.
  3. Missing Check: The handler likely checks for a nonce (for CSRF) but fails to call current_user_can().
  4. Data Retrieval: The function queries a custom table (e.g., {$wpdb->prefix}hrp_employees) using $wpdb->get_results().
  5. Sink: The results, including sensitive columns like salary, pay_rate, and phone, are passed to wp_send_json_success() or echo 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, or hrp-fetch-employees (inferred).
  • Localization Key: The plugin likely uses wp_localize_script to pass the nonce to the frontend.
  • Strategy:
    1. Log in as a Subscriber user.
    2. 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.
    3. If no public/subscriber page enqueues the script, check the main dashboard (/wp-admin/index.php).
    4. JS Variable Search: Use browser_eval to search for localized objects. Common prefixes: hrp_ajax, hrp_obj, or hrp_vars.
    5. 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_eval to 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:
    POST /wp-admin/admin-ajax.php HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    action=hrp-fetch-employees&security=[NONCE_VALUE]
    
    (Note: The nonce parameter name might be security, _wpnonce, or nonce—this must be verified during the research phase via grep on 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_name
  • email
  • phone
  • salary / 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:

  1. Create Employee: Use the WordPress admin (as Administrator) to navigate to the Hr Press Lite menu and add an employee.
  2. Create Attacker: Create a user with the subscriber role.
    • 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

  1. Confirm Role: Use wp user get attacker to verify the user is only a Subscriber.
  2. 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 via wp db tables).
  3. Verify Lack of Auth: Check the plugin source code for the hrp_fetch_employees function to confirm there is no current_user_can() call.

9. Alternative Approaches

  • Parameter Brute-forcing: If action=hrp-fetch-employees returns 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 (the false third argument prevents die(), allowing potential bypass).
Research Findings
Static analysis — not yet PoC-verified

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

--- a/includes/class-hrp-ajax.php
+++ b/includes/class-hrp-ajax.php
@@ -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.