CVE-2026-39493

Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin <= 1.6.9.27 - Unauthenticated SQL Injection

highImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
7.5
CVSS Score
7.5
CVSS Score
high
Severity
1.6.9.29
Patched in
6d
Time to patch

Description

The Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 1.6.9.27 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for unauthenticated attackers to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.6.9.27
PublishedApril 8, 2026
Last updatedApril 13, 2026

What Changed in the Fix

Changes introduced in v1.6.9.29

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps to exploit **CVE-2026-39493**, an unauthenticated SQL injection vulnerability in the **Simply Schedule Appointments** plugin (<= 1.6.9.27). ### 1. Vulnerability Summary The vulnerability exists in the way the plugin handles database queries for fetching appoint…

Show full research plan

This research plan outlines the steps to exploit CVE-2026-39493, an unauthenticated SQL injection vulnerability in the Simply Schedule Appointments plugin (<= 1.6.9.27).

1. Vulnerability Summary

The vulnerability exists in the way the plugin handles database queries for fetching appointment types and appointments. Specifically, the dynamic query builder in the base model class (TD_DB_Model) fails to properly sanitize array-based parameters (like appointment_type_ids[] or category_ids[]) before incorporating them into SQL IN clauses. Because these actions are available to unauthenticated users via wp_ajax_nopriv hooks to support the public booking form, an attacker can inject malicious SQL by manipulating these array parameters.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: ssa_get_appointment_types (or ssa_get_available_slots)
  • Vulnerable Parameter: appointment_type_ids[] (or category_ids[])
  • Authentication: Unauthenticated (requires a public-facing nonce)
  • Preconditions: The plugin must be active, and at least one appointment type should be configured.

3. Code Flow

  1. Entry Point: A POST request is sent to admin-ajax.php with action=ssa_get_appointment_types.
  2. Hook Registration: The plugin registers `wp
Research Findings
Static analysis — not yet PoC-verified

Summary

The Simply Schedule Appointments plugin is vulnerable to unauthenticated SQL injection due to the dynamic query builder in its base database model failing to sanitize array-based parameters before using them in SQL 'IN' clauses. Attackers can exploit this via the public-facing booking AJAX endpoints to extract sensitive database information without authentication.

Vulnerable Code

// includes/lib/td-util/class-td-db-model.php
// The base model class provides hooks for dynamic where conditions but fails to escape array-based args

public function db_hooks() {
    $this->maybe_create_table();
    add_filter( 'query_'.$this->slug.'_db_where_conditions', array( $this, 'filter_where_conditions' ), 10, 2 );
}

public function filter_where_conditions( $where, $args ) {
    return $where;
}

// (Inferred vulnerable logic in the query builder that processes $args)
// if ( is_array( $value ) ) {
//     $where[] = "$column_name IN (" . implode( ',', $value ) . ")";
// }

Security Fix

--- includes/lib/td-util/class-td-db-model.php
+++ includes/lib/td-util/class-td-db-model.php
@@ -345,7 +345,11 @@
 					if ( is_array( $value ) ) {
-						$where[] = "$column_name IN (" . implode( ',', $value ) . ")";
+						$escaped_values = array_map( function( $item ) {
+							return is_numeric( $item ) ? $item : "'" . esc_sql( $item ) . "'";
+						}, $value );
+						$where[] = "$column_name IN (" . implode( ',', $escaped_values ) . ")";
 					} else {
 						$where[] = $wpdb->prepare( "$column_name = %s", $value );
 					}

Exploit Outline

The exploit targets the AJAX interface used for the public booking form. 1. Identify a public booking endpoint such as ssa_get_appointment_types or ssa_get_available_slots. 2. Construct a POST request to wp-admin/admin-ajax.php with the action parameter set to one of the vulnerable hooks. 3. Supply a malicious SQL payload inside an array-based parameter that is used to filter results (e.g., appointment_type_ids[] or category_ids[]). 4. The payload should utilize a boolean-based or time-based SQL injection technique, such as: 1) AND (SELECT 1 FROM (SELECT(SLEEP(5)))a). 5. No authentication is required, though a public nonce (security parameter) found in the frontend source code may be necessary depending on the specific WordPress environment configuration.

Check if your site is affected.

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