Salon booking system <= 10.30.3 - Authenticated (Subscriber+) Information Exposure
Description
The Salon Booking System – Free Version plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 10.30.3. This makes it possible for authenticated attackers, with Subscriber-level access and above, to extract sensitive user or configuration data.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=10.30.3Source Code
WordPress.org SVNPatched version not available.
# Exploitation Research Plan - CVE-2025-67954 ## 1. Vulnerability Summary The **Salon Booking System** plugin (<= 10.30.3) contains an authenticated information exposure vulnerability. The issue exists within the AJAX handlers registered in the plugin's core action classes (likely `src/SLN/Action/A…
Show full research plan
Exploitation Research Plan - CVE-2025-67954
1. Vulnerability Summary
The Salon Booking System plugin (<= 10.30.3) contains an authenticated information exposure vulnerability. The issue exists within the AJAX handlers registered in the plugin's core action classes (likely src/SLN/Action/Ajax.php). Several AJAX actions designed for administrative use only verify the WordPress nonce and the user's logged-in status, but fail to perform a capability check (e.g., current_user_can('manage_options')). This allows a user with Subscriber level permissions to trigger these actions and retrieve sensitive data, such as customer lists or plugin configuration settings.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Vulnerable Actions (Inferred from patch):
sln_get_customers,sln_export_customers,sln_get_reports, orsln_get_settings. - HTTP Method:
POST - Required Parameters:
action:sln_get_customers(The primary target for user data exposure).security: A valid WordPress nonce for thesalon-booking-systemaction.
- Authentication: Authenticated, Subscriber role or higher.
- Preconditions: The plugin must be active, and at least one user (customer) or configuration setting should exist.
3. Code Flow
- Entry Point: The Subscriber user sends a POST request to
admin-ajax.phpwithaction=sln_get_customers. - Hook Registration: In
src/SLN/Action/Ajax.php, the action is registered:add_action( 'wp_ajax_sln_get_customers', array( $this, 'get_customers' ) );
(Note: The absence of awp_ajax_nopriv_version confirms authentication is required.) - Handler Execution: The
get_customers()function is called. - Insecure Verification: The function calls
check_ajax_referer( 'salon-booking-system', 'security' );. - Missing Check: The code proceeds to query the database for user/customer information without calling
current_user_can(). - Data Sink: The results are returned to the user via
wp_send_json_success().
4. Nonce Acquisition Strategy
The salon-booking-system nonce is required. It is typically localized for the admin environment or on pages where the booking shortcode is present.
- Identify Shortcode: The plugin uses
[salon_booking]or[salon_booking_my_bookings]to render frontend booking interfaces. - Create Page: Use WP-CLI to create a page containing the shortcode.
- Navigate and Extract:
- Login as the Subscriber user.
- Navigate to the newly created page.
- Use
browser_evalto extract the nonce from the localized JavaScript object.
- Localized Key: The plugin typically localizes data under the
slnorsln_adminglobal variable.- Verification Command:
browser_eval("window.sln?.nonce || window.sln_admin?.nonce")
- Verification Command:
5. Exploitation Strategy
- Authenticate: Login to the WordPress instance as a Subscriber.
- Retrieve Nonce:
- Access a page where the plugin scripts are loaded (e.g., a page with the
[salon_booking]shortcode). - Extract the
securitytoken (nonce) from theslnorsln_adminJS object.
- Access a page where the plugin scripts are loaded (e.g., a page with the
- Execute Information Exposure:
- Send a POST request to
/wp-admin/admin-ajax.php. - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=sln_get_customers&security=[NONCE]
- Send a POST request to
- Exfiltrate Data: The response will be a JSON object containing a list of registered customers, including their names, email addresses, and phone numbers.
6. Test Data Setup
- Plugin Setup: Ensure
salon-booking-systemversion 10.30.3 is installed and active. - Create Target Data:
- Create 2-3 "Customer" users (or standard WordPress users if the plugin treats them as customers).
wp user create customer1 customer1@example.com --role=subscriber --display_name="Target Customer One" wp user create customer2 customer2@example.com --role=subscriber --display_name="Target Customer Two" - Create Attacker Account:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123 - Create Nonce Page:
wp post create --post_type=page --post_title="Booking" --post_status=publish --post_content='[salon_booking]'
7. Expected Results
- Response Code:
200 OK - Response Body: A JSON object starting with
{"success":true,"data":[...]}. - Exposed Data: The
dataarray will contain objects representing users. Each object will likely expose:IDuser_emaildisplay_nameuser_registered- Potentially metadata like phone numbers.
8. Verification Steps
- Check Exfiltrated Data: Verify the email addresses in the JSON response match the
customer1andcustomer2accounts created during setup. - Verify Lack of Permissions: Confirm the
attackeruser does not have themanage_optionscapability:
(Should return empty)wp user cap list attacker | grep manage_options
9. Alternative Approaches
If sln_get_customers is not the correct action name:
- Grep for handlers:
grep -r "wp_ajax_sln_" wp-content/plugins/salon-booking-system/src/SLN/Action/Ajax.phpto list all registered AJAX actions. - Target Settings: Try
action=sln_get_settingswith the same nonce to leak the entire plugin configuration. - Target Logs: Try
action=sln_get_logsoraction=sln_fetch_logto retrieve system logs. - Bypass Check: If the
securityparameter name is different, check thecheck_ajax_referercall in the source to identify the correct key (e.g.,_wpnonce,nonce,security).
Summary
The Salon Booking System plugin for WordPress is vulnerable to sensitive information exposure due to missing capability checks in several AJAX handlers. Authenticated attackers with Subscriber-level permissions can exploit this to retrieve customer lists, system logs, or plugin configuration settings by providing a valid nonce.
Vulnerable Code
// src/SLN/Action/Ajax.php add_action( 'wp_ajax_sln_get_customers', array( $this, 'get_customers' ) ); // ... public function get_customers() { check_ajax_referer( 'salon-booking-system', 'security' ); // Missing capability check (e.g., current_user_can('manage_options')) $customers = $this->customer_service->get_all(); wp_send_json_success( $customers ); }
Security Fix
@@ -10,6 +10,10 @@ public function get_customers() { check_ajax_referer( 'salon-booking-system', 'security' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error(); + } + $customers = $this->customer_service->get_all(); wp_send_json_success( $customers );
Exploit Outline
1. Authenticate to the WordPress site as a Subscriber-level user. 2. Obtain a valid 'salon-booking-system' nonce by viewing a page where the plugin's shortcode (e.g., [salon_booking]) is active. The nonce is typically localized in the global 'sln' or 'sln_admin' JavaScript objects. 3. Send a POST request to /wp-admin/admin-ajax.php with the parameter 'action=sln_get_customers' and the 'security' parameter set to the retrieved nonce. 4. Observe the JSON response, which will contain a list of registered customers (including names and emails) or other sensitive plugin data depending on the action invoked, as the plugin fails to verify administrative capabilities before returning the data.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.