Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
Tools/GitHubGitHub/huseyn0vs/cve-2026-16540-simplyscheduleappointments
Vulnerability AnalysisWeb Application ExploitationData ExfiltrationInformation GatheringPenetration TestingMisconfiguration
GitHubhuseyn0vs/cve-2026-16540-simplyscheduleappointments

CVE-2026-16540-SimplyScheduleAppointments

CVE-2026-16540 — Simply Schedule Appointments < 1.6.12.6 Unauthenticated Appointment Data Disclosure and Mass Deletion

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
View Repository
129 days agoNot yet reviewed

CVE-2026-16540 — Simply Schedule Appointments < 1.6.12.6

Unauthenticated Appointment Data Disclosure and Mass Deletion via purge Endpoint

FieldDetails
CVECVE-2026-16540
PluginSimply Schedule Appointments
Affected Versions< 1.6.12.6
Fixed In1.6.12.6
Active Installs~70,000
CVSS 3.16.5 (Medium) — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
CWECWE-863 (Incorrect Authorization)
OWASPA5: Broken Access Control
WPVDBc3829294-c388-4151-9e25-a3eac7b1f1c6
ResearcherSuleyman Huseynov (@huseyn0vs__)
Disclosed2026-07-22

Summary

The GET /wp-json/ssa/v1/appointments/purge REST endpoint in Simply Schedule Appointments applies an authorization check (get_items_permissions_check) that validates an id_token proving ownership of a single appointment. However, the handler (purge_appointments()) completely ignores which appointment the token belongs to and instead operates on all appointments site-wide matching the supplied conditions.

An unauthenticated attacker who books any single appointment via the public booking form receives an id_token. Using that token, the attacker can:

  1. Retrieve personal data of all appointments across the site (names, emails, phone numbers, appointment details)
  2. Permanently delete all past, cancelled, or future appointments (premium editions only for deletion)

The deletion cascades across 6 dependent database tables in committed transactions, with no native undo functionality.


Root Cause Analysis

File: includes/class-appointment-model.php

Wrong-Resource Authorization (CWE-863)

The permission gate and the handler operate on completely different scopes:

root@kitploit:~
// Route registration
register_rest_route( $namespace, '/' . $base . '/purge', array(
    array(
        'methods'             => WP_REST_Server::READABLE,
        'callback'            => array( $this, 'purge_appointments' ),
        'permission_callback' => array( $this, 'get_items_permissions_check' ),
    ),
) );

Permission check — validates ownership of ONE appointment via id_token:

root@kitploit:~
public function get_items_permissions_check( $request ) {
    // ...
    if ( true === $this->id_token_permissions_check( $request ) ) {
        return true;  // grants access if caller proves ownership of one appointment
    }
    // ...
}

Handler — ignores the token's appointment and operates site-wide:

root@kitploit:~
public function purge_appointments( WP_REST_Request $request ) {
    $params = $request->get_params();

    // No customer_id or appointment_id scoping — deletes ALL matching appointments
    if ( isset( $params['purge_past_appointments'] ) && 'true' === $params['purge_past_appointments'] ) {
        $conditions[] = $wpdb->prepare( 'end_date < %s', $date_modified_max->format( 'Y-m-d' ) );
    }

    $sql = 'SELECT * FROM ' . $this->get_table_name()
         . ' WHERE ' . implode( ' OR ', $conditions )
         . ' ORDER BY id ASC LIMIT 5000';

    $list = $wpdb->get_results( $sql, ARRAY_A );
    // Cascade-deletes across 6 tables in committed transactions
}

The id_token is an HMAC-MD5 derived from a single appointment's id and date_created. Possessing this token proves only that the caller booked one specific appointment — it conveys no site-wide privilege whatsoever.


Attack Chain

root@kitploit:~
1. Attacker visits the booking page and books any free appointment
   → receives confirmation email containing: appointment_id + id_token

2. GET /wp-json/ssa/v1/appointments/purge
     ?id=<appointment_id>
     &token=<id_token>
     &purge_past_appointments=true

3. Permission check passes (valid token for attacker's own appointment)

4. Handler selects ALL past appointments site-wide → returns PII in response
   → permanently deletes them across 6 tables (on premium editions)

Proof of Concept

PoC will be published on 2026-08-05 following the coordinated disclosure embargo.

See poc/ directory after the embargo date.


Impact

ScenarioResult
Data disclosureNames, emails, phone numbers, appointment details of all customers
Mass deletion (premium)All historical/future appointments permanently destroyed across 6 tables
No recovery pathRequires full database backup restore

Disclosure Timeline

DateEvent
2026-07-10Vulnerability discovered
2026-07-10Submitted to WPScan
2026-07-22CVE-2026-16540 assigned

References

  • WPScan Advisory
  • WordPress Plugin Page
  • CWE-863: Incorrect Authorization
  • OWASP A5: Broken Access Control
Download Tool
2026-07-22Public disclosure on WPScan
2026-08-05PoC published