RepairBuddy – Repair Shop CRM & Booking Plugin for WordPress <= 4.1132 - Missing Authorization
Description
The RepairBuddy – Repair Shop CRM & Booking Plugin for WordPress plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 4.1132. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=4.1132Source Code
WordPress.org SVNThis research plan outlines the methodology for exploiting **CVE-2026-39584**, a Missing Authorization vulnerability in the **RepairBuddy – Repair Shop CRM & Booking Plugin**. ### 1. Vulnerability Summary The RepairBuddy plugin (<= 4.1132) fails to implement adequate authorization checks on its AJA…
Show full research plan
This research plan outlines the methodology for exploiting CVE-2026-39584, a Missing Authorization vulnerability in the RepairBuddy – Repair Shop CRM & Booking Plugin.
1. Vulnerability Summary
The RepairBuddy plugin (<= 4.1132) fails to implement adequate authorization checks on its AJAX handlers. While these handlers are registered for authenticated users (wp_ajax_), they lack internal capability checks (e.g., current_user_can( 'manage_options' )). This allows any authenticated user, including those with the Subscriber role, to execute privileged actions such as modifying business settings, managing inventory, or altering customer records.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Method: POST
- Action Parameter:
repairbuddy_save_business_settings(inferred) orrb_save_options(inferred). - Authentication: Subscriber-level credentials or higher.
- Vulnerable Component: The AJAX callback function fails to verify that the user has administrative permissions before processing the update request.
3. Code Flow
- Registration: The plugin registers AJAX hooks in the main plugin file or an admin controller:
add_action( 'wp_ajax_repairbuddy_save_business_settings', array( $this, 'save_business_settings' ) ); - Dispatch:
admin-ajax.phpreceives a POST request withaction=repairbuddy_save_business_settings. - Execution: WordPress calls the callback
save_business_settings(). - The Flaw: The callback function checks for a valid nonce but fails to perform a capability check:
public function save_business_settings() { // Potential check for nonce (often bypassed or easily obtained) check_ajax_referer( 'repairbuddy_nonce', 'nonce' ); // MISSING: if (!current_user_can('manage_options')) { wp_die(); } $settings = $_POST['settings']; update_option('repairbuddy_settings', $settings); wp_send_json_success(); }
4. Nonce Acquisition Strategy
The plugin typically localizes a nonce for its admin interface. Since Subscribers can access wp-admin/profile.php and many plugins enqueue their global admin scripts on all admin pages, the nonce is likely retrievable from the page source of the profile page.
- Identify Localized Variable: Look for
wp_localize_scriptin the source code. Common identifiers in this plugin:- Variable Name:
repairbuddy_ajax_obj(inferred) orrb_admin_vars(inferred). - Nonce Key:
nonceorrb_nonce.
- Variable Name:
- Creation of Page (If needed): If scripts only load on specific pages, use WP-CLI to place the
[repairbuddy_booking_form](inferred) shortcode on a public page. - Extraction:
- Navigate to
/wp-admin/profile.phpas a Subscriber. - Use
browser_eval:browser_eval("window.repairbuddy_ajax_obj?.nonce || window.rb_admin_vars?.nonce")
- Navigate to
5. Exploitation Strategy
The goal is to modify the shop's business name to prove unauthorized data modification.
Request Details:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Parameters:
action:repairbuddy_save_business_settings(inferred)nonce:[EXTRACTED_NONCE]business_name:HACKED_BY_SUBSCRIBERbusiness_email:attacker@example.com
Note: The exact parameter structure (e.g., whether settings are nested in an array) must be verified by the agent by checking the plugin's admin/assets/js/admin.js or equivalent.
6. Test Data Setup
- Install Plugin: Ensure RepairBuddy <= 4.1132 is active.
- Create Attacker User:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123 - Set Initial State: Configure a default business name:
wp option update repairbuddy_settings '{"business_name":"Original Shop Name"}'(Structure inferred).
7. Expected Results
- Response: A JSON success message:
{"success":true}or1. - Status Code: 200 OK.
- Side Effect: The plugin's business settings in the database are updated with the attacker-supplied values.
8. Verification Steps
- Check Database via WP-CLI:
wp option get repairbuddy_settings - Verify UI:
Navigate to the plugin's settings page as an admin and confirm the "Business Name" has changed to "HACKED_BY_SUBSCRIBER".
9. Alternative Approaches
If repairbuddy_save_business_settings is not the exact action name:
- Identify via Grep:
grep -r "wp_ajax_" wp-content/plugins/computer-repair-shop/ - Target Inventory/Items:
Look for actions likerepairbuddy_add_itemorrepairbuddy_delete_customer. - Check for Nonce-less Actions:
Some older versions of this plugin may have forgottencheck_ajax_refererentirely on specific handlers, making them exploitable even without a nonce. - Check for Settings API:
If the plugin usesregister_setting, try sending a POST towp-admin/options.phpusing the Subscriber session to see if the option group is unprotected.
Summary
The RepairBuddy plugin for WordPress fails to implement capability checks in its AJAX handlers, allowing any authenticated user (including Subscribers) to perform administrative actions. By exploiting this, an attacker can modify business settings, manage inventory, or alter customer records through the admin-ajax.php endpoint.
Vulnerable Code
// In computer-repair-shop/classes/repairbuddy_admin.php or similar add_action('wp_ajax_repairbuddy_save_business_settings', array($this, 'save_business_settings')); public function save_business_settings() { // Only checks nonce, not user capabilities check_ajax_referer('repairbuddy_nonce', 'nonce'); // The lack of current_user_can('manage_options') check here allows unauthorized access $settings = $_POST['settings']; update_option('repairbuddy_settings', $settings); wp_send_json_success(); }
Security Fix
@@ -10,6 +10,10 @@ public function save_business_settings() { check_ajax_referer('repairbuddy_nonce', 'nonce'); + + if (!current_user_can('manage_options')) { + wp_send_json_error(__('You do not have permission to perform this action.', 'repairbuddy')); + wp_die(); + } + $settings = $_POST['settings']; update_option('repairbuddy_settings', $settings); wp_send_json_success();
Exploit Outline
The exploit targets the AJAX interface in WordPress. An attacker with a Subscriber-level account logs into the WordPress dashboard and extracts a valid AJAX nonce (usually 'repairbuddy_nonce') from the HTML source or localized script variables on pages like /wp-admin/profile.php. The attacker then sends a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'repairbuddy_save_business_settings' (or other administrative actions) and the extracted nonce. Because the server-side callback function only verifies the nonce and not the user's role/capabilities, the attacker can successfully update plugin settings or perform other administrative functions by providing the corresponding POST parameters.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.