--- a/hydra-booking/admin/Controller/BookingController.php
+++ b/hydra-booking/admin/Controller/BookingController.php
@@ -929,7 +929,7 @@
$request = json_decode( file_get_contents( 'php://input' ), true );
$booking_id = $request['id'];
$booking_owner = $request['host'];
-
+
if ( empty( $booking_id ) || $booking_id == 0 ) {
return rest_ensure_response(
array(
@@ -955,7 +955,7 @@
$bookingsList = $booking->get( null, true, false, false, false, false, $HostData->host_id );
}
-
+
$extractedBookings = array_map(
function ( $booking ) {
return array(
--- a/hydra-booking/admin/Controller/Enqueue.php
+++ b/hydra-booking/admin/Controller/Enqueue.php
@@ -80,13 +80,19 @@
// enqueue styles
wp_enqueue_style( 'tfhb-admin-style', TFHB_URL . 'assets/admin/css/tfhb-admin-style.css', array(), null );
+ if(defined('TFHB_DEV_MODE') && TFHB_DEV_MODE === true){
+ wp_enqueue_script( 'tfhb-admin-core', apply_filters('tfhb_admin_core_script', 'http://localhost:5173/src/main.js'), array(), time(), true );
+
+ } else {
+
+ // Build the core script
+ wp_enqueue_script('tfhb-admin-core', apply_filters('tfhb_admin_core_script', TFHB_URL .'build/assets/tfhb-admin-app-script.js'), [], time(), true);
+ wp_enqueue_style('tfhb-admin-style-core', apply_filters('tfhb_admin_core_style', TFHB_URL .'build/assets/tfhb-admin-app.css'), [], time(), 'all');
+
+ }
- // wp_enqueue_script( 'tfhb-admin-core', apply_filters('tfhb_admin_core_script', 'http://localhost:5173/src/main.js'), array(), time(), true );
+
- // Build the core script
- wp_enqueue_script('tfhb-admin-core', apply_filters('tfhb_admin_core_script', TFHB_URL .'build/assets/tfhb-admin-app-script.js'), [], time(), true);
- wp_enqueue_style('tfhb-admin-style-core', apply_filters('tfhb_admin_core_style', TFHB_URL .'build/assets/tfhb-admin-app.css'), [], time(), 'all');
-
// Localize the script
$embed_script_link = esc_html('<script src="' .TFHB_URL . 'assets/app/js/widget.js"></script>');
--- a/hydra-booking/admin/Controller/HostsController.php
+++ b/hydra-booking/admin/Controller/HostsController.php
@@ -224,6 +224,19 @@
// Create Hosts
public function CreateHosts() {
+
+ // Checked current user can manage option
+ if ( ! current_user_can( 'manage_options' ) ) {
+ // woocommerce payment
+ $data = array(
+ 'status' => false,
+ 'message' => __( 'You do not have sufficient permissions to create hosts.', 'hydra-booking' ),
+ 'data' => $_tfhb_hosts_settings,
+ );
+ return rest_ensure_response( $data );
+ }
+
+
$request = json_decode( file_get_contents( 'php://input' ), true );
// Check if user is selected
@@ -235,6 +248,7 @@
)
);
}
+
$user_id = $request['id'];
if ( $user_id == 0 ) {
@@ -771,7 +785,7 @@
'telegram' => $telegram,
'twilio' => $twilio,
'slack' => $slack,
- '_tfhb_integration_settings' => $_tfhb_integration_settings,
+ // '_tfhb_integration_settings' => $_tfhb_integration_settings,
);
$data = apply_filters( 'tfhb_get_host_integration_settings', $data, $user_id);
--- a/hydra-booking/admin/Controller/SettingsController.php
+++ b/hydra-booking/admin/Controller/SettingsController.php
@@ -976,6 +976,17 @@
$request = json_decode( file_get_contents( 'php://input' ), true );
$_tfhb_hosts_settings = ! empty( get_option( '_tfhb_hosts_settings' ) ) ? get_option( '_tfhb_hosts_settings' ) : array();
+ // Checked current user can manage option
+ if ( ! current_user_can( 'manage_options' ) ) {
+ // woocommerce payment
+ $data = array(
+ 'status' => false,
+ 'message' => __( 'You do not have permission to access this page', 'hydra-booking' ),
+ 'data' => $_tfhb_hosts_settings,
+ );
+ return rest_ensure_response( $data );
+ }
+
if ( isset( $request['hosts_settings']['others_information']['enable_others_information'] ) ) {
--- a/hydra-booking/admin/Controller/licenseController.php
+++ b/hydra-booking/admin/Controller/licenseController.php
@@ -61,6 +61,16 @@
public function GetLicenseData(){
+ // Checked current user can manage option
+ if ( ! current_user_can( 'manage_options' ) ) {
+ // woocommerce payment
+ wp_send_json_error( array(
+ 'status' => false,
+ 'message' => ' You do not have permission to access this data.'
+ ) );
+ }
+
+
$main_lic_key="HydraBooking_lic_Key";
$lic_key_name =HydraBookingBase::get_lic_key_param($main_lic_key);
$license_key=get_option($lic_key_name,"");
--- a/hydra-booking/hydra-booking.php
+++ b/hydra-booking/hydra-booking.php
@@ -3,7 +3,7 @@
* Plugin Name: Hydra Booking — Appointment Scheduling & Booking Calendar
* Plugin URI: https://hydrabooking.com/
* Description: Appointment Booking Plugin with Automated Scheduling - Apple/Outlook/ Google Calendar, WooCommerce, Zoom, Fluent Forms, Zapier, Mailchimp & CRM Integration.
- * Version: 1.1.32
+ * Version: 1.1.33
* Tested up to: 6.9
* Author: Themefic
* Author URI: https://themefic.com/
@@ -26,8 +26,9 @@
define( 'TFHB_PATH', plugin_dir_path( __FILE__ ) );
define( 'TFHB_URL', plugin_dir_url( __FILE__ ) );
- define( 'TFHB_VERSION', '1.1.32' );
+ define( 'TFHB_VERSION', '1.1.33' );
define( 'TFHB_BASE_FILE', __FILE__);
+ define( 'TFHB_DEV_MODE', false ); // Set true to enable dev mode
// Load Vendor Auto Load
--- a/hydra-booking/includes/database/Attendees.php
+++ b/hydra-booking/includes/database/Attendees.php
@@ -179,14 +179,20 @@
// $sql .= " GROUP BY booking.id ";
- if($orderBy != null) {
- $sql .= " ORDER BY booking.id $orderBy";
- } else {
- $sql .= " ORDER BY booking.id DESC";
+ // Sanitize orderBy - whitelist allowed values
+ $allowed_order = array( 'ASC', 'DESC' );
+ $orderBy = strtoupper( $orderBy );
+ if ( ! in_array( $orderBy, $allowed_order, true ) ) {
+ $orderBy = 'DESC';
}
+
+ $sql .= " ORDER BY booking.id $orderBy";
- if($limit != null && $limit > 1) {
- $sql .= " LIMIT $limit";
+ // Sanitize limit - ensure it's a positive integer
+ $limit = $limit !== null ? absint( $limit ) : null;
+ if($limit !== null && $limit > 1) {
+ $sql .= " LIMIT %d";
+ $data[] = $limit;
}
--- a/hydra-booking/includes/database/Booking.php
+++ b/hydra-booking/includes/database/Booking.php
@@ -138,53 +138,92 @@
$meeting_table = $wpdb->prefix . 'tfhb_meetings';
$host_table = $wpdb->prefix . 'tfhb_hosts';
+ // Sanitize orderBy - whitelist allowed values
+ $allowed_order = array( 'ASC', 'DESC' );
+ $orderBy = strtoupper( $orderBy );
+ if ( ! in_array( $orderBy, $allowed_order, true ) ) {
+ $orderBy = 'DESC';
+ }
+
+ // Sanitize limit - ensure it's a positive integer
+ $limit = $limit !== null ? absint( $limit ) : null;
+
+ // Sanitize user_id - ensure it's an integer
+ $user_id = $user_id !== null ? absint( $user_id ) : null;
+
if ( is_array( $where ) && $join == false ) {
$sql = "SELECT * FROM $table_name WHERE ";
$i = 0;
+ $prepare_values = array();
+
+ // Allowed field names whitelist
+ $allowed_fields = array( 'id', 'meeting_id', 'host_id', 'attendee_id', 'post_id', 'meeting_dates', 'start_time', 'end_time', 'status', 'booking_type', 'created_at', 'updated_at' );
+
foreach ( $where as $k => $v ) {
+ // Sanitize field name - whitelist only
+ if ( ! in_array( $k, $allowed_fields, true ) ) {
+ continue;
+ }
+
if ( $i == 0 ) {
if ( $k == 'meeting_dates' ) {
- $sql .= " FIND_IN_SET('$v', $k)";
+ $sql .= " FIND_IN_SET(%s, $k)";
+ $prepare_values[] = $v;
continue;
}
- $sql .= " $k = '$v'";
+ $sql .= " $k = %s";
+ $prepare_values[] = $v;
} else {
if ( $k == 'meeting_dates' ) {
- $sql .= " AND FIND_IN_SET('$v', $k)";
+ $sql .= " AND FIND_IN_SET(%s, $k)";
+ $prepare_values[] = $v;
continue;
}
- $sql .= " AND $k = '$v'";
+ $sql .= " AND $k = %s";
+ $prepare_values[] = $v;
}
++$i;
}
// Add Order by if exist
- $sql .= $orderBy != null ? " ORDER BY $orderBy" : ' ORDER BY id DESC';
+ $sql .= " ORDER BY id $orderBy";
// Add Limit if exist
- $sql .= $limit != null ? " LIMIT $limit" : '';
+ if ( $limit !== null && $limit > 0 ) {
+ $sql .= " LIMIT %d";
+ $prepare_values[] = $limit;
+ }
if ( $FirstOrFaill == true ) {
// only get first item
- $data = $wpdb->get_row(
- $sql
- );
+ if ( ! empty( $prepare_values ) ) {
+ $data = $wpdb->get_row( $wpdb->prepare( $sql, $prepare_values ) );
+ } else {
+ $data = $wpdb->get_row( $sql );
+ }
} else {
- $data = $wpdb->get_results(
- $sql
- );
+ if ( ! empty( $prepare_values ) ) {
+ $data = $wpdb->get_results( $wpdb->prepare( $sql, $prepare_values ) );
+ } else {
+ $data = $wpdb->get_results( $sql );
+ }
}
// echo $sql;
} elseif ( $where != null && $join != true ) {
if ( $custom == true ) {
- $sql = "SELECT * FROM $table_name WHERE $where";
- if ( ! empty( $where ) ) {
- $sql .= $user_id != null ? " AND $table_name.host_id = $user_id" : '';
+ // For custom queries, $where should be a prepared statement condition
+ // This is a legacy path - it's not safe to use directly
+ // We'll sanitize as integer for backward compatibility
+ $where_int = absint( $where );
+ $sql = "SELECT * FROM $table_name WHERE id = %d";
+ $prepare_values = array( $where_int );
+
+ if ( $user_id !== null ) {
+ $sql .= " AND $table_name.host_id = %d";
+ $prepare_values[] = $user_id;
}
- $data = $wpdb->get_results(
- $wpdb->prepare( $sql )
- );
+ $data = $wpdb->get_results( $wpdb->prepare( $sql, $prepare_values ) );
} else {
$sql = "
SELECT $table_name.*,
@@ -200,7 +239,7 @@
INNER JOIN $meeting_table ON $table_name.meeting_id = $meeting_table.id
WHERE $table_name.id = %d
";
- $data = $wpdb->get_row( $wpdb->prepare( $sql, $where ) );
+ $data = $wpdb->get_row( $wpdb->prepare( $sql, absint( $where ) ) );
}
} else {
if ( $join == true ) {
@@ -235,23 +274,37 @@
$sql = "SELECT * FROM $table_name";
}
+
+ $prepare_values = array();
+
// userwise
- if ( empty( $where ) ) {
- $sql .= $user_id != null ? " WHERE $table_name.host_id = $user_id" : '';
+ if ( empty( $where ) && $user_id !== null ) {
+ $sql .= " WHERE $table_name.host_id = %d";
+ $prepare_values[] = $user_id;
}
- // custom where
- $sql .= $custom != null ? " WHERE $where" : '';
+
+ // custom where - skip for safety
+ // $sql .= $custom != null ? " WHERE $where" : '';
- if ( ! empty( $where ) ) {
- $sql .= $user_id != null ? " AND $table_name.host_id = $user_id" : '';
+ if ( ! empty( $where ) && $user_id !== null ) {
+ $sql .= " AND $table_name.host_id = %d";
+ $prepare_values[] = $user_id;
}
+
// Add Order by if exist
- $sql .= $orderBy != null ? " ORDER BY $orderBy" : ' ORDER BY id DESC';
+ $sql .= " ORDER BY id $orderBy";
// Add Limit if exist
- $sql .= $limit != null ? " LIMIT $limit" : '';
+ if ( $limit !== null && $limit > 0 ) {
+ $sql .= " LIMIT %d";
+ $prepare_values[] = $limit;
+ }
- $data = $wpdb->get_results( $sql );
+ if ( ! empty( $prepare_values ) ) {
+ $data = $wpdb->get_results( $wpdb->prepare( $sql, $prepare_values ) );
+ } else {
+ $data = $wpdb->get_results( $sql );
+ }
}
return $data;
@@ -395,14 +448,20 @@
$sql .= "GROUP BY booking.id ";
- if($orderBy != null) {
- $sql .= " ORDER BY booking.id $orderBy";
- } else {
- $sql .= " ORDER BY booking.id DESC";
+ // Sanitize orderBy - whitelist allowed values
+ $allowed_order = array( 'ASC', 'DESC' );
+ $orderBy = strtoupper( $orderBy );
+ if ( ! in_array( $orderBy, $allowed_order, true ) ) {
+ $orderBy = 'DESC';
}
+
+ $sql .= " ORDER BY booking.id $orderBy";
- if($limit != null && $limit > 1) {
- $sql .= " LIMIT $limit";
+ // Sanitize limit - ensure it's a positive integer
+ $limit = $limit !== null ? absint( $limit ) : null;
+ if($limit !== null && $limit > 1) {
+ $sql .= " LIMIT %d";
+ $data[] = $limit;
}
--- a/hydra-booking/includes/database/Host.php
+++ b/hydra-booking/includes/database/Host.php
@@ -121,17 +121,31 @@
if ( is_array( $where ) ) {
$sql = "SELECT * FROM $table_name WHERE ";
$i = 0;
+ $prepare_values = array();
+
+ // Whitelist allowed field names
+ $allowed_fields = array( 'id', 'user_id', 'email', 'status', 'availability_type', 'availability_id' );
+
foreach ( $where as $k => $v ) {
+ // Sanitize field name - whitelist only
+ if ( ! in_array( $k, $allowed_fields, true ) ) {
+ continue;
+ }
+
if ( $i == 0 ) {
- $sql .= " $k = $v";
+ $sql .= " $k = %s";
} else {
- $sql .= " AND $k = $v";
+ $sql .= " AND $k = %s";
}
+ $prepare_values[] = $v;
++$i;
}
- $data = $wpdb->get_results(
- $wpdb->prepare( $sql )
- );
+
+ if ( ! empty( $prepare_values ) ) {
+ $data = $wpdb->get_results( $wpdb->prepare( $sql, $prepare_values ) );
+ } else {
+ $data = array();
+ }
} elseif ( $where != null ) {
$data = $wpdb->get_row(
$wpdb->prepare( "SELECT * FROM {$wpdb->prefix}tfhb_hosts WHERE id = %d",$where )
@@ -252,13 +266,29 @@
}
}
+ // Sanitize sort_by - whitelist allowed columns
+ $allowed_sort_fields = array( 'id', 'user_id', 'first_name', 'last_name', 'email', 'status', 'created_at', 'updated_at' );
+ if ( ! in_array( $sort_by, $allowed_sort_fields, true ) ) {
+ $sort_by = 'id';
+ }
+
+ // Sanitize order_by - whitelist allowed values
+ $allowed_order = array( 'ASC', 'DESC' );
+ $order_by = strtoupper( $order_by );
+ if ( ! in_array( $order_by, $allowed_order, true ) ) {
+ $order_by = 'DESC';
+ }
// Sort and order
$sql .= " ORDER BY {$sort_by} {$order_by}";
- // Limit
+ // Sanitize limit - ensure it's a positive integer or false
if ($limit !== false) {
- $sql .= " LIMIT $limit";
+ $limit = absint( $limit );
+ if ( $limit > 0 ) {
+ $sql .= " LIMIT %d";
+ $data[] = $limit;
+ }
}
if(!empty($data)) {
--- a/hydra-booking/includes/database/Meeting.php
+++ b/hydra-booking/includes/database/Meeting.php
@@ -184,33 +184,49 @@
} elseif ( ! empty( $filterData['title'] ) || ! empty( $filterData['fhosts'] ) || ! empty( $filterData['user_id'] ) || ! empty( $filterData['fcategory'] ) || ( ! empty( $filterData['startDate'] ) && ! empty( $filterData['endDate'] ) ) ) {
$sql = "SELECT $table_name.*, COUNT($booking_table.id) as total_booking, $host_table.first_name as host_first_name, $host_table.last_name as host_last_name FROM $table_name LEFT JOIN $booking_table ON $table_name.id = $booking_table.meeting_id LEFT JOIN $host_table ON $table_name.host_id = $host_table.id WHERE";
- if ( ! empty( $filterData['title'] ) ) {
- $title = '%' . $filterData['title'] . '%'; // Wrap title with % for LIKE comparison
- // $sql .= $wpdb->prepare( $table_name.'.title LIKE %s', $title );
- $sql .= " $table_name.title LIKE '$title'";
- }
+ $prepare_values = array();
+ $has_condition = false;
- if ( isset( $filterData['fhosts'] ) ) {
- $host_ids = implode( ',', array_map( 'intval', $filterData['fhosts'] ) );
- $sql .= ! empty( $filterData['title'] ) ? ' AND' : '';
- $sql .= " $table_name.host_id IN ($host_ids)";
- }
-
- if ( isset( $filterData['fcategory'] ) ) {
- $category_ids = implode( ',', array_map( 'intval', $filterData['fcategory'] ) );
- $sql .= ( ! empty( $filterData['title'] ) || isset( $filterData['fhosts'] ) ) ? ' AND' : '';
- $sql .= " $table_name.meeting_category IN ($category_ids)";
+ if ( ! empty( $filterData['title'] ) ) {
+ $title = '%' . $wpdb->esc_like( sanitize_text_field( $filterData['title'] ) ) . '%';
+ $sql .= " $table_name.title LIKE %s";
+ $prepare_values[] = $title;
+ $has_condition = true;
+ }
+
+ if ( isset( $filterData['fhosts'] ) && is_array( $filterData['fhosts'] ) ) {
+ $host_ids = array_map( 'absint', $filterData['fhosts'] );
+ $sql .= $has_condition ? ' AND' : '';
+ $placeholders = implode( ',', array_fill( 0, count( $host_ids ), '%d' ) );
+ $sql .= " $table_name.host_id IN ($placeholders)";
+ $prepare_values = array_merge( $prepare_values, $host_ids );
+ $has_condition = true;
+ }
+
+ if ( isset( $filterData['fcategory'] ) && is_array( $filterData['fcategory'] ) ) {
+ $category_ids = array_map( 'absint', $filterData['fcategory'] );
+ $sql .= $has_condition ? ' AND' : '';
+ $placeholders = implode( ',', array_fill( 0, count( $category_ids ), '%d' ) );
+ $sql .= " $table_name.meeting_category IN ($placeholders)";
+ $prepare_values = array_merge( $prepare_values, $category_ids );
+ $has_condition = true;
}
if ( isset( $filterData['user_id'] ) ) {
- $sql .= ( ! empty( $filterData['title'] ) || isset( $filterData['fhosts'] ) || isset( $filterData['fcategory'] ) ) ? ' AND' : '';
- $sql .= $wpdb->prepare( " $table_name.user_id = %s", $filterData['user_id'] );
+ $sql .= $has_condition ? ' AND' : '';
+ $sql .= " $table_name.user_id = %d";
+ $prepare_values[] = absint( $filterData['user_id'] );
+ $has_condition = true;
}
$sql .= " GROUP BY $table_name.id" ;
$sql .= " ORDER BY $table_name.id DESC";
- $data = $wpdb->get_results( $sql );
+ if ( ! empty( $prepare_values ) ) {
+ $data = $wpdb->get_results( $wpdb->prepare( $sql, $prepare_values ) );
+ } else {
+ $data = $wpdb->get_results( $sql );
+ }
} elseif ( ! empty( $user_id ) ) {
@@ -288,14 +304,20 @@
$sql .= "GROUP BY id ";
- if($orderBy != null) {
- $sql .= " ORDER BY id $orderBy";
- } else {
- $sql .= " ORDER BY id DESC";
+ // Sanitize orderBy - whitelist allowed values
+ $allowed_order = array( 'ASC', 'DESC' );
+ $orderBy = strtoupper( $orderBy );
+ if ( ! in_array( $orderBy, $allowed_order, true ) ) {
+ $orderBy = 'DESC';
}
+
+ $sql .= " ORDER BY id $orderBy";
- if($limit != null && $limit > 1) {
- $sql .= " LIMIT $limit";
+ // Sanitize limit - ensure it's a positive integer
+ $limit = $limit !== null ? absint( $limit ) : null;
+ if($limit !== null && $limit > 1) {
+ $sql .= " LIMIT %d";
+ $data[] = $limit;
}