CVE-2026-39525

Booking Activities <= 1.16.48.1 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
1.17.0
Patched in
9d
Time to patch

Description

The Booking Activities plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.16.48.1. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.16.48.1
PublishedApril 13, 2026
Last updatedApril 21, 2026
Affected pluginbooking-activities

What Changed in the Fix

Changes introduced in v1.17.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

system.php` again. The function `bookacti_controller_get_booking_system_data_by_interval` is *definitely* missing a nonce. And the CVE description says "Missing capability check" (Authorization) not "Missing Nonce" (CSRF). The action is likely something in `controller-booking…

Show full research plan

system.phpagain. The functionbookacti_controller_get_booking_system_data_by_intervalis *definitely* missing a nonce. And the CVE description says "Missing capability check" (Authorization) not "Missing Nonce" (CSRF). The action is likely something incontroller-bookings.php`.

*   *Hypothesis:* The `wp_ajax_nopriv_bookactiCancelBooking` action was added or the capability check was missing in the `cancel` function.

*   *Let's look at the CVSS again:* 5.3. Medium.
    This is consistent with "anyone can cancel any booking" (Integrity Low, no Confidentiality or Availability impact usually for a simple cancel).

*   *Plan for PO-C:*
    1. Create a booking (to have something to cancel).
    2. Obtain the `bookacti_cancel_booking` nonce.
    3. Attempt to cancel the booking as an unauthenticated user.

    *Wait, where is the nonce?*
    In `booking-activities.php`:
    `add_action( 'wp_enqueue_scripts', 'bookacti_enqueue_js_variables', 5 );`
    This calls `bookacti_get_js_variables()`. (Function body not in snippet).
    I will assume `bookacti_get_js_variables()` includes the `cancel_booking` nonce.

*   *Wait!
Research Findings
Static analysis — not yet PoC-verified

Summary

The Booking Activities plugin for WordPress is vulnerable to unauthorized access due to missing capability checks and missing nonce validation on several AJAX handlers. This allow unauthenticated attackers to perform unauthorized actions such as retrieving booking system data and internal booking counts, which could lead to information disclosure or unauthorized interaction with the booking system.

Vulnerable Code

// controller/controller-booking-system.php (v1.16.48.1)

function bookacti_controller_get_booking_system_data_by_interval() {
	$atts     = isset( $_POST[ 'attributes' ] ) ? ( is_array( $_POST[ 'attributes' ] ) ? $_POST[ 'attributes' ] : ( is_string( $_POST[ 'attributes' ] ) ? bookacti_maybe_decode_json( stripslashes( $_POST[ 'attributes' ] ), true ) : array() ) ) : array();
	$atts     = bookacti_format_booking_system_attributes( $atts );
	$interval = isset( $_POST[ 'interval' ] ) ? ( is_array( $_POST[ 'interval' ] ) ? $_POST[ 'interval' ] : ( is_string( $_POST[ 'interval' ] ) ? bookacti_maybe_decode_json( stripslashes( $_POST[ 'interval' ] ), true ) : array() ) ) : array();
	$interval = $interval ? bookacti_sanitize_events_interval( $interval ) : array();
	
    // ... processing ...
	
	$booking_system_data = bookacti_get_booking_system_data( $atts );
	
    // ... processing ...

	bookacti_send_json( array( 
		'status'              => 'success', 
		'booking_system_data' => $public_booking_system_data,
		'trimmed_period'      => $trimmed_period
	), 'get_booking_system_data_by_interval' );
}
add_action( 'wp_ajax_bookactiGetBookingSystemDataByInterval', 'bookacti_controller_get_booking_system_data_by_interval' );
add_action( 'wp_ajax_nopriv_bookactiGetBookingSystemDataByInterval', 'bookacti_controller_get_booking_system_data_by_interval' );

---

// controller/controller-booking-system.php (v1.16.48.1)

function bookacti_controller_get_booking_numbers() {
	$template_ids  = isset( $_POST[ 'template_ids' ] ) ? bookacti_ids_to_array( $_POST[ 'template_ids' ] ) : array();
	$groups_data   = isset( $_POST[ 'groups_data' ] ) && is_array( $_POST[ 'groups_data' ] ) ? $_POST[ 'groups_data' ] : array();
	$groups_events = isset( $_POST[ 'groups_events' ] ) && is_array( $_POST[ 'groups_events' ] ) ? $_POST[ 'groups_events' ] : array();
	$groups        = array( 'data' => $groups_data, 'groups' => $groups_events );
	
	$bookings_nb_per_event = bookacti_get_number_of_bookings_per_event( array( 'templates' => $template_ids ) );
	if( ! $bookings_nb_per_event ) { bookacti_send_json( array( 'status' => 'no_bookings' ), 'get_booking_numbers' ); }
	
	$bookings_nb_per_group = bookacti_get_number_of_bookings_per_group_of_events( $groups );
	
	bookacti_send_json( array( 'status' => 'success', 'bookings' => $bookings_nb_per_event, 'groups_bookings' => $bookings_nb_per_group ), 'get_booking_numbers' );
}
add_action( 'wp_ajax_bookactiGetBookingNumbers', 'bookacti_controller_get_booking_numbers' );
add_action( 'wp_ajax_nopriv_bookactiGetBookingNumbers', 'bookacti_controller_get_booking_numbers' );

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/booking-activities/1.16.48.1/booking-activities.php /home/deploy/wp-safety.org/data/plugin-versions/booking-activities/1.17.0/booking-activities.php
--- /home/deploy/wp-safety.org/data/plugin-versions/booking-activities/1.16.48.1/booking-activities.php	2026-03-05 10:46:10.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/booking-activities/1.17.0/booking-activities.php	2026-03-05 16:06:20.000000000 +0000
@@ -3,7 +3,7 @@
  * Plugin Name: Booking Activities
  * Plugin URI: https://booking-activities.fr/en/?utm_source=plugin&utm_medium=plugin&utm_content=header
  * Description: Booking system specialized in activities (sports, cultural, leisure, events...). Works great with WooCommerce.
- * Version: 1.16.48.1
+ * Version: 1.17.0
  * Author: Booking Activities Team
  * Author URI: https://booking-activities.fr/en/?utm_source=plugin&utm_medium=plugin&utm_content=header
  * Text Domain: booking-activities
@@ -42,7 +42,7 @@
 
 
 // GLOBALS AND CONSTANTS
-if( ! defined( 'BOOKACTI_VERSION' ) )     { define( 'BOOKACTI_VERSION', '1.16.48.1' ); }
+if( ! defined( 'BOOKACTI_VERSION' ) )     { define( 'BOOKACTI_VERSION', '1.17.0' ); }
 if( ! defined( 'BOOKACTI_PLUGIN_NAME' ) ) { define( 'BOOKACTI_PLUGIN_NAME', 'booking-activities' ); }
 if( ! defined( 'BOOKACTI_PATH' ) )        { define( 'BOOKACTI_PATH', __DIR__ ); }

Exploit Outline

To exploit this vulnerability, an unauthenticated attacker can directly interact with the plugin's AJAX handlers. 1. Locate the WordPress AJAX endpoint at `wp-admin/admin-ajax.php`. 2. Construct a POST request with the `action` parameter set to one of the vulnerable functions, such as `bookactiGetBookingSystemDataByInterval` or `bookactiGetBookingNumbers`. 3. Include the expected parameters in the POST body, such as `attributes` (JSON/array) or `template_ids[]`. 4. Since these functions are registered with the `wp_ajax_nopriv_` hook and lack `check_ajax_referer` (nonce validation) and `current_user_can` (capability checks) in the vulnerable versions, the request will be processed regardless of the user's authentication status. 5. The server will return a JSON response containing internal booking data, event intervals, or booking counts associated with the provided IDs.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.