Appointment Booking Calendar <= 1.4.02 - Missing Authorization to Authenticated (Contributor+) Sensitive Information Disclosure
Description
The Appointment Booking Calendar plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 1.4.02 via the cpabc_appointments_filter_list. This makes it possible for authenticated attackers, with contributor-level access and above, to extract customer names, email addresses, phone numbers, appointment comments, and other booking personally identifiable information.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=1.4.02What Changed in the Fix
Changes introduced in v1.4.03
Source Code
WordPress.org SVNSorry, I cannot fulfill your request. I am unable to provide functional exploitation plans or actionable payloads for vulnerabilities. For information on securing WordPress plugins against unauthorized access and sensitive information disclosure, you can search for "WordPress plugin security best pr…
Show full research plan
Sorry, I cannot fulfill your request. I am unable to provide functional exploitation plans or actionable payloads for vulnerabilities. For information on securing WordPress plugins against unauthorized access and sensitive information disclosure, you can search for "WordPress plugin security best practices" or "WordPress AJAX authorization and capability checks" online.
Summary
The Appointment Booking Calendar plugin fails to validate user authorization in its shortcode rendering logic. This allows authenticated users with Contributor-level access and above to view sensitive booking information, including customer PII, by manipulating shortcode attributes to query calendars or users they do not own.
Vulnerable Code
// inc/cpabc_apps_on.inc.php line 254 function cpabc_appointments_filter_list($atts) { global $wpdb; extract( shortcode_atts( array( 'calendar' => '', 'user' => '', 'group' => 'day', 'fields' => 'DATE,TIME,NAME', 'from' => "today", 'to' => "today +90 days", ), $atts ) ); $from = date("Y-m-d 00:00:00", strtotime($from)); $to = date("Y-m-d 23:59:59", strtotime($to)); $group = strtolower($group); if ($calendar != '') define ('CPABC_CALENDAR_FIXED_ID', intval($calendar)); else if ($user != '') { $users = $wpdb->get_results( "SELECT user_login,ID FROM ".$wpdb->users." WHERE user_login='".esc_sql($user)."'" ); if (isset($users[0])) define ('CPABC_CALENDAR_USER',$users[0]->ID); else define ('CPABC_CALENDAR_USER',0); } else define ('CPABC_CALENDAR_USER',0); if (defined('CPABC_CALENDAR_USER') && CPABC_CALENDAR_USER != 0) $myrows = $wpdb->get_results( "SELECT * FROM ".CPABC_APPOINTMENTS_CONFIG_TABLE_NAME." WHERE conwer=".CPABC_CALENDAR_USER." AND caldeleted=0" ); else if (defined('CPABC_CALENDAR_FIXED_ID')) $myrows = $wpdb->get_results( "SELECT * FROM ".CPABC_APPOINTMENTS_CONFIG_TABLE_NAME." WHERE id=".CPABC_CALENDAR_FIXED_ID." AND caldeleted=0" ); else $myrows = $wpdb->get_results( "SELECT * FROM ".CPABC_APPOINTMENTS_CONFIG_TABLE_NAME." WHERE caldeleted=0" );
Security Fix
@@ -3,7 +3,7 @@ Plugin Name: Appointment Booking Calendar Plugin URI: https://abc.dwbooster.com Description: This plugin allows you to easily insert appointments forms into your WP website. -Version: 1.4.02 +Version: 1.4.03 Author URI: https://abc.dwbooster.com License: GPLv2 Text Domain: appointment-booking-calendar @@ -254,6 +254,14 @@ function cpabc_appointments_filter_list($atts) { global $wpdb; + + if ( ! is_user_logged_in() ) { + return '<p class="error">'.esc_html(__("You must be logged in to view bookings.",'appointment-booking-calendar')).'</p>'; + } + + $current_user_id = get_current_user_id(); + $is_admin = current_user_can('manage_options'); // Standard check for administrators + extract( shortcode_atts( array( 'calendar' => '', 'user' => '', @@ -261,31 +269,61 @@ 'fields' => 'DATE,TIME,NAME', 'from' => "today", 'to' => "today +90 days", - ), $atts ) ); + ), $atts ) ); $from = date("Y-m-d 00:00:00", strtotime($from)); $to = date("Y-m-d 23:59:59", strtotime($to)); $group = strtolower($group); - - if ($calendar != '') - define ('CPABC_CALENDAR_FIXED_ID', intval($calendar)); - else if ($user != '') - { - $users = $wpdb->get_results( "SELECT user_login,ID FROM ".$wpdb->users." WHERE user_login='".esc_sql($user)."'" ); - if (isset($users[0])) - define ('CPABC_CALENDAR_USER',$users[0]->ID); + + if ( $is_admin ) { + if ($calendar != '') + define ('CPABC_CALENDAR_FIXED_ID', intval($calendar)); + else if ($user != '') + { + $users = $wpdb->get_results( "SELECT user_login,ID FROM ".$wpdb->users." WHERE user_login='".esc_sql($user)."'" ); + if (isset($users[0])) + define ('CPABC_CALENDAR_USER',$users[0]->ID); + else + define ('CPABC_CALENDAR_USER',0); + } else define ('CPABC_CALENDAR_USER',0); - } - else - define ('CPABC_CALENDAR_USER',0); - if (defined('CPABC_CALENDAR_USER') && CPABC_CALENDAR_USER != 0) - $myrows = $wpdb->get_results( "SELECT * FROM ".CPABC_APPOINTMENTS_CONFIG_TABLE_NAME." WHERE conwer=".CPABC_CALENDAR_USER." AND caldeleted=0" ); - else if (defined('CPABC_CALENDAR_FIXED_ID')) - $myrows = $wpdb->get_results( "SELECT * FROM ".CPABC_APPOINTMENTS_CONFIG_TABLE_NAME." WHERE id=".CPABC_CALENDAR_FIXED_ID." AND caldeleted=0" ); - else - $myrows = $wpdb->get_results( "SELECT * FROM ".CPABC_APPOINTMENTS_CONFIG_TABLE_NAME." WHERE caldeleted=0" ); + if (defined('CPABC_CALENDAR_USER') && CPABC_CALENDAR_USER != 0) + $myrows = $wpdb->get_results( "SELECT * FROM ".CPABC_APPOINTMENTS_CONFIG_TABLE_NAME." WHERE conwer=".CPABC_CALENDAR_USER." AND caldeleted=0" ); + else if (defined('CPABC_CALENDAR_FIXED_ID')) + $myrows = $wpdb->get_results( "SELECT * FROM ".CPABC_APPOINTMENTS_CONFIG_TABLE_NAME." WHERE id=".CPABC_CALENDAR_FIXED_ID." AND caldeleted=0" ); + else + $myrows = $wpdb->get_results( "SELECT * FROM ".CPABC_APPOINTMENTS_CONFIG_TABLE_NAME." WHERE caldeleted=0" ); + } else { + // NON-ADMIN BRANCH: Strictly enforce 'conwer' = current user ID + if ($calendar != '') { + $calendar_id = intval($calendar); + // Verify that this exact calendar ID belongs to the current user + $myrows = $wpdb->get_results( $wpdb->prepare( + "SELECT * FROM " . CPABC_APPOINTMENTS_CONFIG_TABLE_NAME . " WHERE id = %d AND conwer = %d AND caldeleted = 0", + $calendar_id, $current_user_id + ) ); + if (!defined('CPABC_CALENDAR_FIXED_ID')) define ('CPABC_CALENDAR_FIXED_ID', $calendar_id); + } else if ($user != '') { + // If filtering by user attribute, non-admins can only look up themselves + $users = $wpdb->get_results( $wpdb->prepare("SELECT user_login,ID FROM ".$wpdb->users." WHERE user_login=%s", $user) ); + if (isset($users[0]) && intval($users[0]->ID) === $current_user_id) { + if (!defined('CPABC_CALENDAR_USER')) define ('CPABC_CALENDAR_USER', $current_user_id); + $myrows = $wpdb->get_results( $wpdb->prepare("SELECT * FROM ".CPABC_APPOINTMENTS_CONFIG_TABLE_NAME." WHERE conwer=%d AND caldeleted=0", $current_user_id) ); + } else { + return '<p class="error">'.esc_html(__("Access denied: You cannot view calendars owned by other users.",'appointment-booking-calendar')).'</p>'; + } + } else { + // Fallback: Default to only pulling calendars owned by the logged-in user + if (!defined('CPABC_CALENDAR_USER')) define ('CPABC_CALENDAR_USER', $current_user_id); + $myrows = $wpdb->get_results( $wpdb->prepare("SELECT * FROM ".CPABC_APPOINTMENTS_CONFIG_TABLE_NAME." WHERE conwer=%d AND caldeleted=0", $current_user_id) ); + } + } + + if ( empty( $myrows ) ) { + return '<p class="error">'.esc_html(__("No data found.",'appointment-booking-calendar')).'</p>'; + } if (!defined('CP_CALENDAR_ID')) define ('CP_CALENDAR_ID',$myrows[0]->id);
Exploit Outline
An attacker with Contributor-level permissions (or higher) can exploit this vulnerability by using the plugin's appointment list shortcode. By embedding `[cpabc_appointments_filter_list calendar="target_id"]` or `[cpabc_appointments_filter_list user="target_username"]` in a post or page and previewing it, the attacker triggers the `cpabc_appointments_filter_list` function. Because the function lacks `is_user_logged_in` or ownership checks, it will execute SQL queries against the appointments table using the provided ID or username and display the resulting booking data—including PII like customer names, emails, and phone numbers—directly in the page output.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.