CVE-2026-59523

Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin <= 1.6.11.11 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
1.6.12.0
Patched in
6d
Time to patch

Description

The Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.6.11.11. This makes it possible for unauthenticated attackers to perform an unauthorized action.

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<=1.6.11.11
PublishedJuly 9, 2026
Last updatedJuly 14, 2026

What Changed in the Fix

Changes introduced in v1.6.12.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

Notices_Api` routes use `get_items_permissions_check`. If this function is NOT defined in `SSA_Notices_Api` and NOT in `WP_REST_Controller`, what happens? WordPress will try to call it and fail if it doesn't exist. However, the class `SSA_Notices_Api` is truncated. It *likely* contains: …

Show full research plan

Notices_Apiroutes useget_items_permissions_check. If this function is NOT defined in SSA_Notices_Apiand NOT inWP_REST_Controller, what happens? WordPress will try to call it and fail if it doesn't exist. However, the class SSA_Notices_Api` is truncated. It likely contains:
php public function get_items_permissions_check( $request ) { return true; }
This would be the "Missing Authorization" (it exists, but it doesn't authorize).

Let's look at `SSA_Notices_Api::update_item`:
```php
public function update_item( $request ) {
    $params = $request->get_params();
    $notice_name = sanitize_text_field( $params['id'] );
    // ...
    update_option( 'ssa_dismissed_notices', $dismissed_notices, false );
}
```
It's a perfect sink.

1. Summary
2. Attack Vector: `POST /wp-json/ssa/v1/notices/pinned/`
3. Code Flow: `SSA_Db_Model::whitelist_ssa_rest_api` -> `SSA_Notices_Api::update_item_pinned_notices`.
4. Nonce: Explain why it'
Research Findings
Static analysis — not yet PoC-verified

Summary

The Simply Schedule Appointments plugin for WordPress is vulnerable to unauthorized access and modification of administrative notice settings due to improper permission checks and a global REST API authentication bypass. Unauthenticated or low-privileged attackers can trigger REST endpoints to dismiss or pin administrative notices site-wide, as the plugin whitelists all /ssa/ routes from core WordPress REST authentication.

Vulnerable Code

// includes/class-db-model.php line 31
public function whitelist_ssa_rest_api( $result ) {
	if ( isset( $GLOBALS['wp']->query_vars['rest_route'] ) ) {
		$route = untrailingslashit( $GLOBALS['wp']->query_vars['rest_route'] );
		if ( 0 === strpos( $route, '/ssa/' ) ) {
			return true;
		}
	}

	return $result;
}

---

// includes/class-notices-api.php line 308
public function get_items_permissions_check( $request ) {
	return TD_API_Model::nonce_permissions_check( $request );
}

// includes/class-notices-api.php line 320
public function update_item_permissions_check( $request ) {
	if ( is_user_logged_in() ) {
		return true;
	}
}

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/simply-schedule-appointments/1.6.11.11/includes/class-notices-api.php /home/deploy/wp-safety.org/data/plugin-versions/simply-schedule-appointments/1.6.12.0/includes/class-notices-api.php
--- /home/deploy/wp-safety.org/data/plugin-versions/simply-schedule-appointments/1.6.11.11/includes/class-notices-api.php	2024-02-20 19:37:14.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/simply-schedule-appointments/1.6.12.0/includes/class-notices-api.php	2026-06-05 10:42:28.000000000 +0000
@@ -302,47 +302,39 @@
 	}
 
 	/**
-	 * Check if a given request has access to get items
+	 * Plugin admin notices and dismissed/pinned state are admin UI surface, not
+	 * public-facing data, and reads/writes affect site-wide options. Gate every
+	 * notices route on the SSA admin floor (`ssa_manage_appointments`).
 	 *
 	 * @param WP_REST_Request $request Full data about the request.
-	 * @return WP_Error|bool
+	 * @return bool
 	 */
 	public function get_items_permissions_check( $request ) {
-		return TD_API_Model::nonce_permissions_check( $request );
+		return current_user_can( 'ssa_manage_appointments' );
 	}
 
 	/**
-	 * Check if a given request has access to get a specific item
-	 *
 	 * @param WP_REST_Request $request Full data about the request.
-	 * @return WP_Error|bool
+	 * @return bool
 	 */
 	public function get_item_permissions_check( $request ) {
-		return TD_API_Model::nonce_permissions_check( $request );
+		return current_user_can( 'ssa_manage_appointments' );
 	}
 
 	/**
-	 * Check if a given request has access to update a specific item
-	 *
 	 * @param WP_REST_Request $request Full data about the request.
-	 * @return WP_Error|bool
+	 * @return bool
 	 */
 	public function update_item_permissions_check( $request ) {
-		if ( is_user_logged_in() ) {
-			return true;
-		}
+		return current_user_can( 'ssa_manage_appointments' );
 	}
 
 	/**
-	 * Check if a given request has access to delete a specific item
-	 *
 	 * @param WP_REST_Request $request Full data about the request.
-	 * @return WP_Error|bool
+	 * @return bool
 	 */
 	public function delete_item_permissions_check( $request ) {
-		if ( is_user_logged_in() ) {
-			return true;
-		}
+		return current_user_can( 'ssa_manage_appointments' );
 	}

Exploit Outline

1. An attacker identifies a REST API endpoint belonging to the notices functionality, such as POST /wp-json/ssa/v1/notices/pinned/{id} or POST /wp-json/ssa/v1/notices/{id}. 2. The attacker sends a request to this endpoint without valid administrative credentials or a valid nonce. 3. The plugin's global whitelist in SSA_Db_Model::whitelist_ssa_rest_api instructs WordPress to bypass standard REST authentication for this route. 4. The vulnerable permission_callback in SSA_Notices_Api (either get_items_permissions_check or update_item_permissions_check) fails to adequately verify administrative capabilities, checking only for basic login or a weak legacy nonce condition. 5. Upon successful request, the plugin executes update_option(), allowing the attacker to modify site-wide settings such as ssa_dismissed_notices or ssa_pinned_notices.

Check if your site is affected.

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