CVE-2025-13754

Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin <= 1.6.9.16 - Missing Authorization to Unauthenticated Sensitive Information Exposure

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

Description

The Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 1.6.9.16. This is due to the plugin exposing its admin embed endpoint at `/wp-json/ssa/v1/embed-inner-admin` without authentication, which leaks plugin settings including staff names, business names, and configuration data that are not publicly displayed on the booking form. This makes it possible for unauthenticated attackers to extract private business configuration. In premium versions with integrations configured, this might also expose other sensitive data including API keys for external services.

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<=1.6.9.16
PublishedDecember 18, 2025
Last updatedDecember 19, 2025

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-13754 ## 1. Vulnerability Summary The **Simply Schedule Appointments** plugin (<= 1.6.9.16) registers a REST API endpoint `/wp-json/ssa/v1/embed-inner-admin` intended for administrative use (embedding the admin interface). However, this endpoint lacks a prope…

Show full research plan

Exploitation Research Plan - CVE-2025-13754

1. Vulnerability Summary

The Simply Schedule Appointments plugin (<= 1.6.9.16) registers a REST API endpoint /wp-json/ssa/v1/embed-inner-admin intended for administrative use (embedding the admin interface). However, this endpoint lacks a proper permission_callback or fails to implement authorization checks, allowing any unauthenticated user to access it. The endpoint returns a JSON payload containing sensitive configuration data, including business details, staff names, and internal plugin settings not intended for public view.

2. Attack Vector Analysis

  • Endpoint: /wp-json/ssa/v1/embed-inner-admin
  • Method: GET
  • Authentication: None Required (Unauthenticated)
  • Parameter: None required for the basic leak, though query parameters might filter the output.
  • Preconditions: The plugin must be installed and activated. Sensitive data (like staff names or business settings) should be configured to demonstrate the impact.

3. Code Flow (Inferred)

  1. Route Registration: The plugin likely registers the route during the rest_api_init hook.
    • File (Inferred): includes/class-ssa-rest-api.php or includes/api/class-ssa-rest-embed.php.
    • Call: register_rest_route( 'ssa/v1', '/embed-inner-admin', ... ).
  2. Missing Permission Callback: The registration likely lacks the 'permission_callback' key or sets it to __return_true.
  3. Callback Execution: When the endpoint is hit, a callback function (e.g., get_embed_inner_admin_data) is executed.
  4. Data Retrieval: This function aggregates data from get_option (e.g., ssa_settings) and possibly custom post types for staff or appointment types.
  5. Response: The aggregated data is returned as a WP_REST_Response, which WordPress converts to JSON.

4. Nonce Acquisition Strategy

According to the vulnerability description, this is a Missing Authorization issue on a REST API endpoint.

  • Standard WordPress REST Behavior: Typically, GET requests to REST API routes do not require a _wpnonce header unless the permission_callback explicitly checks for one via current_user_can().
  • Vulnerability Context: Since the vulnerability is that the endpoint is exposed unauthenticated, it is highly probable that no nonce or cookie is required to access this specific data.
  • Verification: If the http_request returns a 401 or 403, I will investigate if a frontend nonce is exposed (e.g., via ssa_params localized script) and if providing it in the X-WP-Nonce header bypasses the check, though the "Missing Authorization" label suggests the endpoint is wide open.

5. Exploitation Strategy

  1. Target URL: http://<target-site>/wp-json/ssa/v1/embed-inner-admin
  2. Request Construction:
    • Method: GET
    • Tool: http_request
  3. Payload: None needed.
  4. Expected Response: A 200 OK status with a JSON object containing keys like settings, business_name, staff, or appointment_types.

6. Test Data Setup

To confirm the leak is "sensitive," the environment should be populated with non-public information:

  1. Set Business Name: wp option update ssa_settings '{"business_name": "Secret Admin Business", "admin_email": "admin@vulnerable.test"}' (Note: SSA uses complex JSON options, this is a simplified example).
  2. Create Staff/Appointment Types: If possible via CLI, or verify default settings are leaked.
  3. Enable Integration: If testing a premium version, configure a mock API key in settings to see if it is included in the JSON response.

7. Expected Results

A successful exploit will return a JSON body containing information such as:

{
    "settings": {
        "business_name": "Secret Admin Business",
        "admin_email": "admin@vulnerable.test",
        "some_internal_key": "internal_value"
    },
    "staff": [
        {
            "id": 1,
            "name": "Private Staff Member"
        }
    ]
}

The absence of a "rest_forbidden" or "rest_cannot_access" error confirms the vulnerability.

8. Verification Steps

  1. Compare Response: Run wp option get ssa_settings (or the equivalent option name used by SSA) via CLI.
  2. Match: Verify that values found in the CLI output (which should be private) appear in the JSON response from the unauthenticated HTTP request.
  3. Check Context: Verify these settings are not visible on the standard public booking page (which usually only shows available times and appointment types).

9. Alternative Approaches

  • Check for Query Params: If the response is empty, try adding common SSA parameters like ?appointment_type=... or ?admin=true.
  • Frontend Nonce: If the endpoint requires a nonce despite being "unauthenticated" (a common SSA pattern for its frontend components), use browser_navigate to the homepage, then:
    • browser_eval("window.ssa_params?.nonce") or browser_eval("window.ssaData?.nonce").
    • Include this in the X-WP-Nonce header of the http_request. This would still be a vulnerability if the nonce is available to everyone and the endpoint allows access to admin-level data.

Check if your site is affected.

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