VYPR
Moderate severityNVD Advisory· Published Sep 21, 2022· Updated Apr 28, 2026

WordPress Awesome Support plugin <= 6.0.7 - Multiple Authenticated Persistent XSS (Additional Interested Parties)

CVE-2022-38073

Description

Multiple Authenticated (custom specific plugin role) Persistent Cross-Site Scripting (XSS) vulnerability in Awesome Support plugin <= 6.0.7 at WordPress.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
awesome-support/awesome-supportPackagist
< 6.0.86.0.8

Affected products

1

Patches

2
b2e831d7f831

Merge pull request #787 from tednh/hotfix/urgent-security-vulnerability

2 files changed · +124 120
  • includes/admin/functions-post.php+93 90 modified
    @@ -48,19 +48,22 @@ function wpas_filter_ticket_data( $data, $postarr ) {
     	if ( 'auto-draft' === $data['post_status'] ) {
     		return $data;
     	}
    -	
    +
     	/**
     	 * Sanitize the title of the ticket post
     	 */
     	$data['post_title'] = wp_kses_post( $data['post_title'] );
    -	$data['post_title'] = sanitize_text_field( $data['post_title'] );	
    +	$data['post_title'] = sanitize_text_field( $data['post_title'] );
    +
    +	/* Sanitize the data */
    +	$data['post_content'] = wp_kses( $data['post_content'], wp_kses_allowed_html( 'post' ) );
     
     	/**
     	 * Automatically set the ticket as processing if this is the first reply.
     	 */
     	if ( user_can( $current_user->ID, 'edit_ticket' ) && isset( $postarr['ID'] ) ) {
    -		
    -		
    +
    +
     		// @TODO:  Its possible that this entire section of code to set the $agent_replied flag might not be needed.
     		// We'll keep it for now but its not used in this function at this time.
     		$replies       = wpas_get_replies( intval( $postarr['ID'] ) );
    @@ -78,7 +81,7 @@ function wpas_filter_ticket_data( $data, $postarr ) {
     		}
     
     		// @TODO: Its possible this if statement below might need an additional qualifier to see if $agent_replied = true.
    -		// For now the ticket is going to IN PROCESS properly but if there is an issue later then using the additional 
    +		// For now the ticket is going to IN PROCESS properly but if there is an issue later then using the additional
     		// qualifier might be warranted.
     		if ( ! isset( $_POST['post_status_override'] ) || 'queued' === $_POST['post_status_override'] ) {
     			$_POST['post_status_override'] = 'processing';
    @@ -146,9 +149,9 @@ function wpas_save_ticket( $post_id ) {
     
     	/**
     	 * Save old assignee - will need to pass it to action hooks later
    -	 */ 
    +	 */
     	 $old_assignee = get_post_meta( $post_id, '_wpas_assignee', true );
    -	
    +
     	/* Now we can save the custom fields */
     	WPAS()->custom_fields->save_custom_fields( $post_id, $_POST );
     
    @@ -163,15 +166,15 @@ function wpas_save_ticket( $post_id ) {
     		 * First of all, set the ticket as open. This is very important.
     		 */
     		add_post_meta( $post_id, '_wpas_status', 'open', true );
    -		
    +
     		/* Next - update other some meta values. If you add or delete from this list you also */
     		/* need to do the same thing in the /includes/functions-post.php file */
     		add_post_meta( $post_id, '_wpas_last_reply_date', null, true );
     		add_post_meta( $post_id, '_wpas_last_reply_date_gmt', null, true );
    -		
    +
     		/* Set the slug */
     		wpas_set_ticket_slug( $post_id );
    -		
    +
     		/**
     		 * Fire hook when a new ticket is being added - works great for notifications
     		 *
    @@ -234,18 +237,18 @@ function wpas_save_ticket( $post_id ) {
     
     			/* In case the insertion failed... */
     			if ( is_wp_error( $reply ) ) {
    -				
    +
     				// Fire action hook for failed reply inserted via admin
     				do_action( 'wpas_insert_reply_admin_failed', $post_id, $data, $reply );
     
     				/* Set the redirection */
     				$_SESSION['wpas_redirect'] = add_query_arg( array( 'wpas-message' => 'wpas_reply_error' ), get_permalink( $post_id ) );
     
     			} else {
    -				
    +
     				/**
     				 * Fire action hook for reply inserted via admin - great place for notifications...
    -				 */								
    +				 */
     				do_action( 'wpas_insert_reply_admin_success', $post_id, $data, $reply );
     
     				/* The agent wants to close the ticket */
    @@ -265,7 +268,7 @@ function wpas_save_ticket( $post_id ) {
     						/**
     						 * wpas_ticket_closed_by_agent hook
     						 */
    -						
    +
     						if( $closed ) {
     							do_action( 'wpas_ticket_closed_by_agent', $post_id );
     						}
    @@ -286,13 +289,13 @@ function wpas_save_ticket( $post_id ) {
     
     	/* If this was a ticket update, we need to fire some action hooks and then figure out where to go next... */
     	if ( '' !== $original_status ) {
    -		
    +
     		/**
     		 * Fire action hook for after ticket update...
     		 *
     		 * @since 4.0.0
     		 */
    -		do_action( 'wpas_ticket_after_update_admin_success', $post_id, $old_assignee, $_POST);	
    +		do_action( 'wpas_ticket_after_update_admin_success', $post_id, $old_assignee, $_POST);
     
     		$gt_post      = null;
     		$where_after  = filter_input( INPUT_POST, 'where_after', FILTER_SANITIZE_STRING );
    @@ -327,7 +330,7 @@ function wpas_save_ticket( $post_id ) {
     			), admin_url( 'post.php' ) ) );
     		}
     	}
    -	
    +
     	do_action( 'wpas_ticket_after_saved', $post_id );
     
     }
    @@ -449,57 +452,57 @@ function wpas_redirect_ticket_after_save( $location, $post_id ) {
     /**
      * Get next id
      * @param int $current_ticket
    - * 
    + *
      * @return int
      */
     function wpas_get_next_ticket( $current_ticket ) {
    -	
    +
     	return wpas_get_adjacent_ticket( $current_ticket );
    -	
    +
     }
     
     /**
      * Get previous id
      * @param int $current_ticket
    - * 
    + *
      * @return int
      */
     function wpas_get_previous_ticket( $current_ticket ) {
    -	
    +
     	return wpas_get_adjacent_ticket( $current_ticket, false );
    -	
    +
     }
     
     
     /**
    - * 
    + *
      * @global object $wpdb
      * @global object $current_user
      * @param int $ticket_id
      * @param boolean $next
    - * 
    + *
      * @return int
      */
     function wpas_get_adjacent_ticket( $ticket_id , $next = true ) {
    -	
    +
     	/* Make sure this is the admin screen */
     	if ( ! is_admin() ) {
     		return false;
     	}
    -	
    +
     	if ( true === $next ) {
     		$adjacent = '>';
     		$order_type = 'ASC';
     	} else {
     		$adjacent = '<';
     		$order_type = 'DESC';
     	}
    -	
    +
     	$custom_post_status = wpas_get_post_status();
     	$custom_post_status['open'] = 'Open';
    -	
    +
     	$meta_query = wpas_ticket_listing_assignee_meta_query_args();
    -	
    +
     	$args = array(
     		'post_type' => 'ticket',
     		'posts_per_page' => 1,
    @@ -510,37 +513,37 @@ function wpas_get_adjacent_ticket( $ticket_id , $next = true ) {
     		'next_previous_adjacent' => "{$adjacent} {$ticket_id}",
     		'wpas_tickets_query' => 'listing'
     	);
    -	
    +
     	$query = new WP_Query( $args );
    -	
    +
     	$adjacent_post_id = '';
    -	
    +
     	if ( !empty( $query->posts ) ) {
     		$adjacent_post_id = $query->posts[0]->ID;
    -	} 
    -	
    +	}
    +
     	return $adjacent_post_id;
     }
     
     add_filter( 'posts_clauses', 'wpas_get_adjacent_ticket_posts_clauses', 30, 2 );
     
     /**
      * Modify get_adjacent_ticket query
    - * 
    + *
      * @global object $wpdb
      * @param array $pieces
      * @param object $wp_query
    - * 
    + *
      * @return array
      */
     function wpas_get_adjacent_ticket_posts_clauses( $pieces , $wp_query ) {
     	global $wpdb;
    -	
    +
     	if ( isset( $wp_query->query['next_previous_adjacent'] ) ) {
     		$adjacent = $wp_query->query['next_previous_adjacent'];
     		$pieces['where'] = "AND ({$wpdb->posts}.ID {$adjacent} ) " . $pieces['where'];
     	}
    -	
    +
     	return $pieces;
     }
     
    @@ -552,27 +555,27 @@ function wpas_get_adjacent_ticket_posts_clauses( $pieces , $wp_query ) {
      * @return array|int
      */
     function wpas_get_agent_tickets( $args = array(), $ticket_status = 'any' ) {
    -	
    +
     	global $current_user;
    -	
    +
     	$custom_post_status = wpas_get_post_status();
     	$custom_post_status['open'] = 'Open';
    -	
    +
     	foreach($custom_post_status as $status => $label) {
     		$post_status[] = $status;
     	}
    -	
    -	
    +
    +
     	$defaults = array(
     		'post_type'              => 'ticket',
     		'post_status'            => $post_status,
     		'posts_per_page'         => - 1
     	);
     
     	$args  = wp_parse_args( $args, $defaults );
    -	
    +
     	$meta_query = array();
    -	
    +
     	if ( 'any' !== $ticket_status ) {
     		if ( in_array( $ticket_status, array( 'open', 'closed' ) ) ) {
     			$meta_query[] = array(
    @@ -583,51 +586,51 @@ function wpas_get_agent_tickets( $args = array(), $ticket_status = 'any' ) {
     			);
     		}
     	}
    -	
    -	
    -	
    +
    +
    +
     	$meta_query = wpas_ticket_listing_assignee_meta_query_args();
    -		
    +
     	if( !empty( $meta_query ) ) {
     		$args['meta_query'] = $meta_query;
     	}
    -	
    +
     	$args['wpas_tickets_query'] = 'listing';
    -	
    +
     	$query = new WP_Query( $args );
     	if ( empty( $query->posts ) ) {
     		return array();
     	} else {
     		return $query->posts;
     	}
    -	
    +
     }
     
     /**
      * Return meta query args for ticket listing query relative to assignee
    - * 
    + *
      * @param type $use_id
      * @return type
      */
     function wpas_ticket_listing_assignee_meta_query_args( $user_id = 0, $profile_filter = true ) {
    -	
    +
     	if( 0 ===  $user_id ) {
     		$user_id = get_current_user_id();
     	}
    -	
    +
     	$user_can_see_all = wpas_can_user_see_all_tickets();
    -	
    +
     	$meta_query = array();
    -	
    +
     	if( false === $user_can_see_all ) {
    -		
    +
     		$primary_agent_meta_query = array(
     			'key'     => '_wpas_assignee',
     			'value'   => (int) $user_id,
     			'compare' => '=',
     			'type'    => 'NUMERIC',
     		);
    -	
    +
     		if( wpas_is_multi_agent_active() ) {
     			// Check if agent is set as secondary or tertiary agent
     			$multi_agents_meta_query = array();
    @@ -654,48 +657,48 @@ function wpas_ticket_listing_assignee_meta_query_args( $user_id = 0, $profile_fi
     			$meta_query[] = $primary_agent_meta_query;
     		}
     	}
    -	
    +
     	return apply_filters( 'wpas_assignee_meta_query', $meta_query, $user_id, $profile_filter );
    -	
    +
     }
     
     
     /**
      * Generate a link with icon for a reply action
    - * 
    + *
      * @param string $id
      * @param array $args
    - * 
    + *
      * @return string
      */
     function wpas_reply_control_item( $id , $args = array() ) {
    -	
    +
     	$link = isset( $args['link'] ) ? $args['link'] : '#';
     	$title = isset( $args['title'] ) ? $args['title'] : '';
    -	
    +
     	$icon = isset( $args['icon'] ) && $args['icon'] ? $args['icon'] : false;
    -	
    +
     	$attr_id = isset( $args['id'] ) && $args['id'] ? $args['id'] : '';
    -	
    +
     	$classes = isset( $args['classes'] ) ? $args['classes'] : '';
     	$classes .= " {$id}";
     	$classes .= ( $icon ? ' reply_icon' : '' );
     	$classes .= $title ? ' hint-bottom hint-anim' : '';
    -	
    +
     	$data_params = isset( $args['data'] ) && is_array( $args['data'] ) ?  $args['data'] : array();
    -	
    +
     	$markup = "<a href=\"{$link}\" data-hint=\"{$title}\" class=\"{$classes}\"";
    -	
    +
     	foreach( $data_params as $dp_name => $dp_value ) {
     		$markup .= " data-{$dp_name}=\"{$dp_value}\"";
     	}
    -	
    +
     	$markup .= $attr_id ? " id=\"{$attr_id}\"" : '';
     	$markup .= '>';
     	$markup .= $icon ? "<img src=\"{$icon}\" />" : '';
     	$markup .= '</a>';
    -	
    -	
    +
    +
     	return $markup;
     }
     
    @@ -704,19 +707,19 @@ function wpas_reply_control_item( $id , $args = array() ) {
      * Check if reply content or attachments provided with new reply
      */
     function wpas_is_new_reply_empty( $ticket_id ) {
    -		
    +
     	$content_empty = isset( $_POST['wpas_reply'] ) && isset( $_POST['wpas_reply_ticket'] ) && '' !== $_POST['wpas_reply'] ? false : true;
    -	
    +
     	$attachments_empty = true;
    -	
    +
     	// Check if agent uploaded attachments
     	if( $content_empty ) {
    -		
    +
     		if ( boolval( wpas_get_option( 'ajax_upload', false ) ) || boolval( wpas_get_option( 'ajax_upload_all', false ) ) ) {
    -			
    +
     			$upload = wp_upload_dir();
     			$dir    = trailingslashit( $upload['basedir'] ) . 'awesome-support/temp_' . $ticket_id . '_' . get_current_user_id() .'/';
    -			
    +
     			// If temp directory exists, it means that user is uploaded attachments
     			if ( is_dir( $dir ) ) {
     
    @@ -728,35 +731,35 @@ function wpas_is_new_reply_empty( $ticket_id ) {
     				}
     
     				$accept = implode( ',', $accept );
    -				
    -				
    +
    +
     				$files = glob( $dir . '{' . $accept . '}', GLOB_BRACE );
     				$attachments_empty = empty( $files ) ? true : false;
     			}
    -			
    -			
    +
    +
     		} else {
     			$attachments_empty = $_FILES && isset( $_FILES['wpas_files'] ) && !empty( $_FILES['wpas_files']['name'][0] ) ? false : true;
     		}
    -		
    +
     	}
    -	
    +
     	return ( $content_empty && $attachments_empty );
     }
     
     add_action( 'wpas_backend_ticket_status_before_actions', 'wpas_close_ticket_prevent_client_notification_field', 12 );
     /**
      * Add Checkbox to prevent client notification about ticket close
    - * 
    + *
      * @param int $ticket_id
      */
     function wpas_close_ticket_prevent_client_notification_field( $ticket_id ) {
    -	
    +
     	/* Do not show the checkbox if not enabled in settings */
     	if ( ! boolval( wpas_get_option( 'agents_can_suppress_closing_emails', false ) ) ) {
     		return ;
     	}
    -	
    +
     	$close_ticket_prevent_client_notification = get_post_meta( $ticket_id, 'wpas_close_ticket_prevent_client_notification', true );
     	?>
     
    @@ -769,4 +772,4 @@ function wpas_close_ticket_prevent_client_notification_field( $ticket_id ) {
     	</p>
     	</div>
     	<?php
    -}
    \ No newline at end of file
    +}
    
  • includes/custom-fields/class-custom-field.php+31 30 modified
    @@ -166,44 +166,44 @@ public static function get_field_defaults() {
     				'taxo_edit_terms'   	=> 'settings_tickets',
     				'taxo_delete_terms' 	=> 'settings_tickets',
     				'taxo_assign_terms' 	=> 'create_ticket',
    -				
    +
     				// Sort taxonomy terms
     				'taxo_sortorder' => '',
     
     				// @since 3.3.5
     				'readonly'              => false,
     				// Readonly field by default. Can be updated in custom save_callback
    -				
    +
     				// @since 4.1.0
     				// Whether or not to show the field in the front-end my-tickets list screen after a ticket is submitted.
     				// Sometimes when you get a ton of custom fields, having them all in the list is an issue.
     				'show_frontend_list'	=> true,
    -				
    +
     				// @since 4.1.0
     				// Whether or not to show the field in the front-end detail screen (header area) for existing tickets.
     				// Sometimes when you get a ton of custom fields, having them all in the list is an issue.
    -				'show_frontend_detail'	=> true,				
    -				
    +				'show_frontend_detail'	=> true,
    +
     				// @since 4.3.0
     				// Hold extra wrapper classes/ids - applies to front-end only
     				'extra_wrapper_css_classes'	=> '' ,
     
     				// @since 4.3.0
     				// Hold extra field classes/ids - applies to front-end only
     				'extra_field_css_classes'	=> '' ,
    -				
    +
     				// @since 4.3.0
     				// Hold extra wrapper classes/ids - applies to back-end only
     				'extra_wrapper_css_classes_be'	=> '' ,
     
     				// @since 4.3.0
     				// Hold extra field classes/ids - applies to back-end only
    -				'extra_field_css_classes_be'	=> '' ,				
    -				
    +				'extra_field_css_classes_be'	=> '' ,
    +
     				// @since 4.3.0
     				// Hold extra label classes/ids - this one not currently used - for possible future use only.
     				'extra_label_css_classes'	=> '' ,
    -				
    +
     				// @since 4.3.0
     				// Start or end front-end bootstrap row with this field?
     				'boot_strap_row_fe_start'	=> false ,
    @@ -212,38 +212,38 @@ public static function get_field_defaults() {
     				// @since 4.3.0
     				// Place this field in a bootstrap column?
     				'boot_strap_column_fe'	=> false ,
    -				
    +
     				// @since 4.4.0
     				// The sort order of the field - used only by the custom-fields add-on!
     				'order'	=> '99999',
    -				
    +
     				// @since 4.4.0
     				// Action hook to declare just before rendering the field on the front-end
     				'pre_render_action_hook_fe' => '',
    -				
    +
     				// @since 4.4.0
     				// Action hook to declare just after rendering the field on the front-end
     				'post_render_action_hook_fe' => '',
    -				
    +
     				// @since 4.4.0
     				// Action hook to declare just before rendering the field on the back-end
     				// Future use only since we don't have a back-end only rendering function yet.
     				// Use the front-end hook above for everything for now.
     				'pre_render_action_hook_be' => '',
    -				
    +
     				// @since 4.4.0
     				// Action hook to declare just after rendering the field on the back-end
     				// Future use only since we don't have a back-end only rendering function yet.
    -				// Use the front-end hook above for everything for now.				
    -				'post_render_action_hook_be' => '',	
    +				// Use the front-end hook above for everything for now.
    +				'post_render_action_hook_be' => '',
     
     				// @since 5.2.0
     				// Use ajax for uploading files - used by upload custom field
     				'use_ajax_uploader' => false,
    -				
    +
     				// @since 5.1.1
     				// Enable paste using ctrl+v commands
    -				'enable_paste' => true,	
    +				'enable_paste' => true,
     
     			);
     
    @@ -632,7 +632,7 @@ public function get_wrapper_class( $class = array() ) {
     			$classes = array(
     				'wpas-form-group',
     			);
    -			
    +
     			/* Add in any user defined classes if any (front-end) */
     			if ( ! empty( $this->field[ 'args' ][ 'extra_wrapper_css_classes' ] )  && false === is_admin() ) {
     				$classes[] = $this->field[ 'args' ][ 'extra_wrapper_css_classes' ] ;
    @@ -642,7 +642,7 @@ public function get_wrapper_class( $class = array() ) {
     			if ( ! empty( $this->field[ 'args' ][ 'extra_wrapper_css_classes_be' ] )  && true === is_admin() ) {
     				$classes[] = $this->field[ 'args' ][ 'extra_wrapper_css_classes_be' ] ;
     			}
    -			
    +
     			/* If this field should go into its own bootstrap column add in that class name here */
     			if ( ! empty( $this->field[ 'args' ][ 'boot_strap_column_fe' ] ) && true === $this->field[ 'args' ][ 'boot_strap_column_fe' ] && false === is_admin() ) {
     				$classes[] = 'col' ;
    @@ -717,16 +717,16 @@ public function get_field_class( $class = array() ) {
     			$classes = array(
     				'wpas-form-control',
     			);
    -			
    +
     			/* Add in any user defined classes if any (front-end) */
     			if ( ! empty( $this->field[ 'args' ][ 'extra_field_css_classes' ] ) && false === is_admin() ) {
     				$classes[] = $this->field[ 'args' ][ 'extra_field_css_classes' ] ;
     			}
    -			
    +
     			/* Add in any user defined classes if any (back-end) */
     			if ( ! empty( $this->field[ 'args' ][ 'extra_field_css_classes_be' ] ) && true === is_admin() ) {
     				$classes[] = $this->field[ 'args' ][ 'extra_field_css_classes_be' ] ;
    -			}			
    +			}
     
     			$class_name = $this->get_class_name();
     
    @@ -812,19 +812,19 @@ public function get_output() {
     			$this->require_field_type_class();
     
     			$wrapper     = $this->get_wrapper_markup();
    -			
    -			/* Add a beginning DIV if this field marks the start of a bootstrap row and we're displaying on the front-end... */	
    +
    +			/* Add a beginning DIV if this field marks the start of a bootstrap row and we're displaying on the front-end... */
     			if ( ! empty( $this->field[ 'args' ][ 'boot_strap_row_fe_start' ] ) && true === $this->field[ 'args' ][ 'boot_strap_row_fe_start' ] && false === is_admin() ) {
     				$wrapper = ' <div class="wpas-fe-bs4-row row"> ' . $wrapper;
     			}
     
    -			/* Add an ending DIV if this field marks the end of a bootstrap row and we're displaying on the front-end... */		
    +			/* Add an ending DIV if this field marks the end of a bootstrap row and we're displaying on the front-end... */
     			if ( ! empty( $this->field[ 'args' ][ 'boot_strap_row_fe_end' ] ) && true === $this->field[ 'args' ][ 'boot_strap_row_fe_end' ] && false === is_admin() ) {
     				$wrapper .= ' </div> ' ;
    -			}			
    -			
    +			}
    +
     			$field       = $this->get_field_markup();
    -			
    +
     			$description = $this->get_field_description();
     
     			if ( ! empty( $description ) ) {
    @@ -850,8 +850,9 @@ public function get_output() {
     		 */
     		public function get_sanitized_value( $value ) {
     
    +			$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
     			$sanitize_function = 'sanitize_text_field' ;
    -			
    +
     			if ( isset( $this->field[ 'args' ][ 'sanitize' ] ) ) {
     				$sanitize_function = function_exists( $this->field[ 'args' ][ 'sanitize' ] ) ? $this->field[ 'args' ][ 'sanitize' ] : 'sanitize_text_field';
     			}
    
85f460be88b8

FIX - Urgent security vulnerability

https://github.com/Awesome-Support/Awesome-SupportNguyen Huu MinhDec 5, 2021via ghsa
2 files changed · +124 120
  • includes/admin/functions-post.php+93 90 modified
    @@ -48,19 +48,22 @@ function wpas_filter_ticket_data( $data, $postarr ) {
     	if ( 'auto-draft' === $data['post_status'] ) {
     		return $data;
     	}
    -	
    +
     	/**
     	 * Sanitize the title of the ticket post
     	 */
     	$data['post_title'] = wp_kses_post( $data['post_title'] );
    -	$data['post_title'] = sanitize_text_field( $data['post_title'] );	
    +	$data['post_title'] = sanitize_text_field( $data['post_title'] );
    +
    +	/* Sanitize the data */
    +	$data['post_content'] = wp_kses( $data['post_content'], wp_kses_allowed_html( 'post' ) );
     
     	/**
     	 * Automatically set the ticket as processing if this is the first reply.
     	 */
     	if ( user_can( $current_user->ID, 'edit_ticket' ) && isset( $postarr['ID'] ) ) {
    -		
    -		
    +
    +
     		// @TODO:  Its possible that this entire section of code to set the $agent_replied flag might not be needed.
     		// We'll keep it for now but its not used in this function at this time.
     		$replies       = wpas_get_replies( intval( $postarr['ID'] ) );
    @@ -78,7 +81,7 @@ function wpas_filter_ticket_data( $data, $postarr ) {
     		}
     
     		// @TODO: Its possible this if statement below might need an additional qualifier to see if $agent_replied = true.
    -		// For now the ticket is going to IN PROCESS properly but if there is an issue later then using the additional 
    +		// For now the ticket is going to IN PROCESS properly but if there is an issue later then using the additional
     		// qualifier might be warranted.
     		if ( ! isset( $_POST['post_status_override'] ) || 'queued' === $_POST['post_status_override'] ) {
     			$_POST['post_status_override'] = 'processing';
    @@ -146,9 +149,9 @@ function wpas_save_ticket( $post_id ) {
     
     	/**
     	 * Save old assignee - will need to pass it to action hooks later
    -	 */ 
    +	 */
     	 $old_assignee = get_post_meta( $post_id, '_wpas_assignee', true );
    -	
    +
     	/* Now we can save the custom fields */
     	WPAS()->custom_fields->save_custom_fields( $post_id, $_POST );
     
    @@ -163,15 +166,15 @@ function wpas_save_ticket( $post_id ) {
     		 * First of all, set the ticket as open. This is very important.
     		 */
     		add_post_meta( $post_id, '_wpas_status', 'open', true );
    -		
    +
     		/* Next - update other some meta values. If you add or delete from this list you also */
     		/* need to do the same thing in the /includes/functions-post.php file */
     		add_post_meta( $post_id, '_wpas_last_reply_date', null, true );
     		add_post_meta( $post_id, '_wpas_last_reply_date_gmt', null, true );
    -		
    +
     		/* Set the slug */
     		wpas_set_ticket_slug( $post_id );
    -		
    +
     		/**
     		 * Fire hook when a new ticket is being added - works great for notifications
     		 *
    @@ -234,18 +237,18 @@ function wpas_save_ticket( $post_id ) {
     
     			/* In case the insertion failed... */
     			if ( is_wp_error( $reply ) ) {
    -				
    +
     				// Fire action hook for failed reply inserted via admin
     				do_action( 'wpas_insert_reply_admin_failed', $post_id, $data, $reply );
     
     				/* Set the redirection */
     				$_SESSION['wpas_redirect'] = add_query_arg( array( 'wpas-message' => 'wpas_reply_error' ), get_permalink( $post_id ) );
     
     			} else {
    -				
    +
     				/**
     				 * Fire action hook for reply inserted via admin - great place for notifications...
    -				 */								
    +				 */
     				do_action( 'wpas_insert_reply_admin_success', $post_id, $data, $reply );
     
     				/* The agent wants to close the ticket */
    @@ -265,7 +268,7 @@ function wpas_save_ticket( $post_id ) {
     						/**
     						 * wpas_ticket_closed_by_agent hook
     						 */
    -						
    +
     						if( $closed ) {
     							do_action( 'wpas_ticket_closed_by_agent', $post_id );
     						}
    @@ -286,13 +289,13 @@ function wpas_save_ticket( $post_id ) {
     
     	/* If this was a ticket update, we need to fire some action hooks and then figure out where to go next... */
     	if ( '' !== $original_status ) {
    -		
    +
     		/**
     		 * Fire action hook for after ticket update...
     		 *
     		 * @since 4.0.0
     		 */
    -		do_action( 'wpas_ticket_after_update_admin_success', $post_id, $old_assignee, $_POST);	
    +		do_action( 'wpas_ticket_after_update_admin_success', $post_id, $old_assignee, $_POST);
     
     		$gt_post      = null;
     		$where_after  = filter_input( INPUT_POST, 'where_after', FILTER_SANITIZE_STRING );
    @@ -327,7 +330,7 @@ function wpas_save_ticket( $post_id ) {
     			), admin_url( 'post.php' ) ) );
     		}
     	}
    -	
    +
     	do_action( 'wpas_ticket_after_saved', $post_id );
     
     }
    @@ -449,57 +452,57 @@ function wpas_redirect_ticket_after_save( $location, $post_id ) {
     /**
      * Get next id
      * @param int $current_ticket
    - * 
    + *
      * @return int
      */
     function wpas_get_next_ticket( $current_ticket ) {
    -	
    +
     	return wpas_get_adjacent_ticket( $current_ticket );
    -	
    +
     }
     
     /**
      * Get previous id
      * @param int $current_ticket
    - * 
    + *
      * @return int
      */
     function wpas_get_previous_ticket( $current_ticket ) {
    -	
    +
     	return wpas_get_adjacent_ticket( $current_ticket, false );
    -	
    +
     }
     
     
     /**
    - * 
    + *
      * @global object $wpdb
      * @global object $current_user
      * @param int $ticket_id
      * @param boolean $next
    - * 
    + *
      * @return int
      */
     function wpas_get_adjacent_ticket( $ticket_id , $next = true ) {
    -	
    +
     	/* Make sure this is the admin screen */
     	if ( ! is_admin() ) {
     		return false;
     	}
    -	
    +
     	if ( true === $next ) {
     		$adjacent = '>';
     		$order_type = 'ASC';
     	} else {
     		$adjacent = '<';
     		$order_type = 'DESC';
     	}
    -	
    +
     	$custom_post_status = wpas_get_post_status();
     	$custom_post_status['open'] = 'Open';
    -	
    +
     	$meta_query = wpas_ticket_listing_assignee_meta_query_args();
    -	
    +
     	$args = array(
     		'post_type' => 'ticket',
     		'posts_per_page' => 1,
    @@ -510,37 +513,37 @@ function wpas_get_adjacent_ticket( $ticket_id , $next = true ) {
     		'next_previous_adjacent' => "{$adjacent} {$ticket_id}",
     		'wpas_tickets_query' => 'listing'
     	);
    -	
    +
     	$query = new WP_Query( $args );
    -	
    +
     	$adjacent_post_id = '';
    -	
    +
     	if ( !empty( $query->posts ) ) {
     		$adjacent_post_id = $query->posts[0]->ID;
    -	} 
    -	
    +	}
    +
     	return $adjacent_post_id;
     }
     
     add_filter( 'posts_clauses', 'wpas_get_adjacent_ticket_posts_clauses', 30, 2 );
     
     /**
      * Modify get_adjacent_ticket query
    - * 
    + *
      * @global object $wpdb
      * @param array $pieces
      * @param object $wp_query
    - * 
    + *
      * @return array
      */
     function wpas_get_adjacent_ticket_posts_clauses( $pieces , $wp_query ) {
     	global $wpdb;
    -	
    +
     	if ( isset( $wp_query->query['next_previous_adjacent'] ) ) {
     		$adjacent = $wp_query->query['next_previous_adjacent'];
     		$pieces['where'] = "AND ({$wpdb->posts}.ID {$adjacent} ) " . $pieces['where'];
     	}
    -	
    +
     	return $pieces;
     }
     
    @@ -552,27 +555,27 @@ function wpas_get_adjacent_ticket_posts_clauses( $pieces , $wp_query ) {
      * @return array|int
      */
     function wpas_get_agent_tickets( $args = array(), $ticket_status = 'any' ) {
    -	
    +
     	global $current_user;
    -	
    +
     	$custom_post_status = wpas_get_post_status();
     	$custom_post_status['open'] = 'Open';
    -	
    +
     	foreach($custom_post_status as $status => $label) {
     		$post_status[] = $status;
     	}
    -	
    -	
    +
    +
     	$defaults = array(
     		'post_type'              => 'ticket',
     		'post_status'            => $post_status,
     		'posts_per_page'         => - 1
     	);
     
     	$args  = wp_parse_args( $args, $defaults );
    -	
    +
     	$meta_query = array();
    -	
    +
     	if ( 'any' !== $ticket_status ) {
     		if ( in_array( $ticket_status, array( 'open', 'closed' ) ) ) {
     			$meta_query[] = array(
    @@ -583,51 +586,51 @@ function wpas_get_agent_tickets( $args = array(), $ticket_status = 'any' ) {
     			);
     		}
     	}
    -	
    -	
    -	
    +
    +
    +
     	$meta_query = wpas_ticket_listing_assignee_meta_query_args();
    -		
    +
     	if( !empty( $meta_query ) ) {
     		$args['meta_query'] = $meta_query;
     	}
    -	
    +
     	$args['wpas_tickets_query'] = 'listing';
    -	
    +
     	$query = new WP_Query( $args );
     	if ( empty( $query->posts ) ) {
     		return array();
     	} else {
     		return $query->posts;
     	}
    -	
    +
     }
     
     /**
      * Return meta query args for ticket listing query relative to assignee
    - * 
    + *
      * @param type $use_id
      * @return type
      */
     function wpas_ticket_listing_assignee_meta_query_args( $user_id = 0, $profile_filter = true ) {
    -	
    +
     	if( 0 ===  $user_id ) {
     		$user_id = get_current_user_id();
     	}
    -	
    +
     	$user_can_see_all = wpas_can_user_see_all_tickets();
    -	
    +
     	$meta_query = array();
    -	
    +
     	if( false === $user_can_see_all ) {
    -		
    +
     		$primary_agent_meta_query = array(
     			'key'     => '_wpas_assignee',
     			'value'   => (int) $user_id,
     			'compare' => '=',
     			'type'    => 'NUMERIC',
     		);
    -	
    +
     		if( wpas_is_multi_agent_active() ) {
     			// Check if agent is set as secondary or tertiary agent
     			$multi_agents_meta_query = array();
    @@ -654,48 +657,48 @@ function wpas_ticket_listing_assignee_meta_query_args( $user_id = 0, $profile_fi
     			$meta_query[] = $primary_agent_meta_query;
     		}
     	}
    -	
    +
     	return apply_filters( 'wpas_assignee_meta_query', $meta_query, $user_id, $profile_filter );
    -	
    +
     }
     
     
     /**
      * Generate a link with icon for a reply action
    - * 
    + *
      * @param string $id
      * @param array $args
    - * 
    + *
      * @return string
      */
     function wpas_reply_control_item( $id , $args = array() ) {
    -	
    +
     	$link = isset( $args['link'] ) ? $args['link'] : '#';
     	$title = isset( $args['title'] ) ? $args['title'] : '';
    -	
    +
     	$icon = isset( $args['icon'] ) && $args['icon'] ? $args['icon'] : false;
    -	
    +
     	$attr_id = isset( $args['id'] ) && $args['id'] ? $args['id'] : '';
    -	
    +
     	$classes = isset( $args['classes'] ) ? $args['classes'] : '';
     	$classes .= " {$id}";
     	$classes .= ( $icon ? ' reply_icon' : '' );
     	$classes .= $title ? ' hint-bottom hint-anim' : '';
    -	
    +
     	$data_params = isset( $args['data'] ) && is_array( $args['data'] ) ?  $args['data'] : array();
    -	
    +
     	$markup = "<a href=\"{$link}\" data-hint=\"{$title}\" class=\"{$classes}\"";
    -	
    +
     	foreach( $data_params as $dp_name => $dp_value ) {
     		$markup .= " data-{$dp_name}=\"{$dp_value}\"";
     	}
    -	
    +
     	$markup .= $attr_id ? " id=\"{$attr_id}\"" : '';
     	$markup .= '>';
     	$markup .= $icon ? "<img src=\"{$icon}\" />" : '';
     	$markup .= '</a>';
    -	
    -	
    +
    +
     	return $markup;
     }
     
    @@ -704,19 +707,19 @@ function wpas_reply_control_item( $id , $args = array() ) {
      * Check if reply content or attachments provided with new reply
      */
     function wpas_is_new_reply_empty( $ticket_id ) {
    -		
    +
     	$content_empty = isset( $_POST['wpas_reply'] ) && isset( $_POST['wpas_reply_ticket'] ) && '' !== $_POST['wpas_reply'] ? false : true;
    -	
    +
     	$attachments_empty = true;
    -	
    +
     	// Check if agent uploaded attachments
     	if( $content_empty ) {
    -		
    +
     		if ( boolval( wpas_get_option( 'ajax_upload', false ) ) || boolval( wpas_get_option( 'ajax_upload_all', false ) ) ) {
    -			
    +
     			$upload = wp_upload_dir();
     			$dir    = trailingslashit( $upload['basedir'] ) . 'awesome-support/temp_' . $ticket_id . '_' . get_current_user_id() .'/';
    -			
    +
     			// If temp directory exists, it means that user is uploaded attachments
     			if ( is_dir( $dir ) ) {
     
    @@ -728,35 +731,35 @@ function wpas_is_new_reply_empty( $ticket_id ) {
     				}
     
     				$accept = implode( ',', $accept );
    -				
    -				
    +
    +
     				$files = glob( $dir . '{' . $accept . '}', GLOB_BRACE );
     				$attachments_empty = empty( $files ) ? true : false;
     			}
    -			
    -			
    +
    +
     		} else {
     			$attachments_empty = $_FILES && isset( $_FILES['wpas_files'] ) && !empty( $_FILES['wpas_files']['name'][0] ) ? false : true;
     		}
    -		
    +
     	}
    -	
    +
     	return ( $content_empty && $attachments_empty );
     }
     
     add_action( 'wpas_backend_ticket_status_before_actions', 'wpas_close_ticket_prevent_client_notification_field', 12 );
     /**
      * Add Checkbox to prevent client notification about ticket close
    - * 
    + *
      * @param int $ticket_id
      */
     function wpas_close_ticket_prevent_client_notification_field( $ticket_id ) {
    -	
    +
     	/* Do not show the checkbox if not enabled in settings */
     	if ( ! boolval( wpas_get_option( 'agents_can_suppress_closing_emails', false ) ) ) {
     		return ;
     	}
    -	
    +
     	$close_ticket_prevent_client_notification = get_post_meta( $ticket_id, 'wpas_close_ticket_prevent_client_notification', true );
     	?>
     
    @@ -769,4 +772,4 @@ function wpas_close_ticket_prevent_client_notification_field( $ticket_id ) {
     	</p>
     	</div>
     	<?php
    -}
    \ No newline at end of file
    +}
    
  • includes/custom-fields/class-custom-field.php+31 30 modified
    @@ -166,44 +166,44 @@ public static function get_field_defaults() {
     				'taxo_edit_terms'   	=> 'settings_tickets',
     				'taxo_delete_terms' 	=> 'settings_tickets',
     				'taxo_assign_terms' 	=> 'create_ticket',
    -				
    +
     				// Sort taxonomy terms
     				'taxo_sortorder' => '',
     
     				// @since 3.3.5
     				'readonly'              => false,
     				// Readonly field by default. Can be updated in custom save_callback
    -				
    +
     				// @since 4.1.0
     				// Whether or not to show the field in the front-end my-tickets list screen after a ticket is submitted.
     				// Sometimes when you get a ton of custom fields, having them all in the list is an issue.
     				'show_frontend_list'	=> true,
    -				
    +
     				// @since 4.1.0
     				// Whether or not to show the field in the front-end detail screen (header area) for existing tickets.
     				// Sometimes when you get a ton of custom fields, having them all in the list is an issue.
    -				'show_frontend_detail'	=> true,				
    -				
    +				'show_frontend_detail'	=> true,
    +
     				// @since 4.3.0
     				// Hold extra wrapper classes/ids - applies to front-end only
     				'extra_wrapper_css_classes'	=> '' ,
     
     				// @since 4.3.0
     				// Hold extra field classes/ids - applies to front-end only
     				'extra_field_css_classes'	=> '' ,
    -				
    +
     				// @since 4.3.0
     				// Hold extra wrapper classes/ids - applies to back-end only
     				'extra_wrapper_css_classes_be'	=> '' ,
     
     				// @since 4.3.0
     				// Hold extra field classes/ids - applies to back-end only
    -				'extra_field_css_classes_be'	=> '' ,				
    -				
    +				'extra_field_css_classes_be'	=> '' ,
    +
     				// @since 4.3.0
     				// Hold extra label classes/ids - this one not currently used - for possible future use only.
     				'extra_label_css_classes'	=> '' ,
    -				
    +
     				// @since 4.3.0
     				// Start or end front-end bootstrap row with this field?
     				'boot_strap_row_fe_start'	=> false ,
    @@ -212,38 +212,38 @@ public static function get_field_defaults() {
     				// @since 4.3.0
     				// Place this field in a bootstrap column?
     				'boot_strap_column_fe'	=> false ,
    -				
    +
     				// @since 4.4.0
     				// The sort order of the field - used only by the custom-fields add-on!
     				'order'	=> '99999',
    -				
    +
     				// @since 4.4.0
     				// Action hook to declare just before rendering the field on the front-end
     				'pre_render_action_hook_fe' => '',
    -				
    +
     				// @since 4.4.0
     				// Action hook to declare just after rendering the field on the front-end
     				'post_render_action_hook_fe' => '',
    -				
    +
     				// @since 4.4.0
     				// Action hook to declare just before rendering the field on the back-end
     				// Future use only since we don't have a back-end only rendering function yet.
     				// Use the front-end hook above for everything for now.
     				'pre_render_action_hook_be' => '',
    -				
    +
     				// @since 4.4.0
     				// Action hook to declare just after rendering the field on the back-end
     				// Future use only since we don't have a back-end only rendering function yet.
    -				// Use the front-end hook above for everything for now.				
    -				'post_render_action_hook_be' => '',	
    +				// Use the front-end hook above for everything for now.
    +				'post_render_action_hook_be' => '',
     
     				// @since 5.2.0
     				// Use ajax for uploading files - used by upload custom field
     				'use_ajax_uploader' => false,
    -				
    +
     				// @since 5.1.1
     				// Enable paste using ctrl+v commands
    -				'enable_paste' => true,	
    +				'enable_paste' => true,
     
     			);
     
    @@ -632,7 +632,7 @@ public function get_wrapper_class( $class = array() ) {
     			$classes = array(
     				'wpas-form-group',
     			);
    -			
    +
     			/* Add in any user defined classes if any (front-end) */
     			if ( ! empty( $this->field[ 'args' ][ 'extra_wrapper_css_classes' ] )  && false === is_admin() ) {
     				$classes[] = $this->field[ 'args' ][ 'extra_wrapper_css_classes' ] ;
    @@ -642,7 +642,7 @@ public function get_wrapper_class( $class = array() ) {
     			if ( ! empty( $this->field[ 'args' ][ 'extra_wrapper_css_classes_be' ] )  && true === is_admin() ) {
     				$classes[] = $this->field[ 'args' ][ 'extra_wrapper_css_classes_be' ] ;
     			}
    -			
    +
     			/* If this field should go into its own bootstrap column add in that class name here */
     			if ( ! empty( $this->field[ 'args' ][ 'boot_strap_column_fe' ] ) && true === $this->field[ 'args' ][ 'boot_strap_column_fe' ] && false === is_admin() ) {
     				$classes[] = 'col' ;
    @@ -717,16 +717,16 @@ public function get_field_class( $class = array() ) {
     			$classes = array(
     				'wpas-form-control',
     			);
    -			
    +
     			/* Add in any user defined classes if any (front-end) */
     			if ( ! empty( $this->field[ 'args' ][ 'extra_field_css_classes' ] ) && false === is_admin() ) {
     				$classes[] = $this->field[ 'args' ][ 'extra_field_css_classes' ] ;
     			}
    -			
    +
     			/* Add in any user defined classes if any (back-end) */
     			if ( ! empty( $this->field[ 'args' ][ 'extra_field_css_classes_be' ] ) && true === is_admin() ) {
     				$classes[] = $this->field[ 'args' ][ 'extra_field_css_classes_be' ] ;
    -			}			
    +			}
     
     			$class_name = $this->get_class_name();
     
    @@ -812,19 +812,19 @@ public function get_output() {
     			$this->require_field_type_class();
     
     			$wrapper     = $this->get_wrapper_markup();
    -			
    -			/* Add a beginning DIV if this field marks the start of a bootstrap row and we're displaying on the front-end... */	
    +
    +			/* Add a beginning DIV if this field marks the start of a bootstrap row and we're displaying on the front-end... */
     			if ( ! empty( $this->field[ 'args' ][ 'boot_strap_row_fe_start' ] ) && true === $this->field[ 'args' ][ 'boot_strap_row_fe_start' ] && false === is_admin() ) {
     				$wrapper = ' <div class="wpas-fe-bs4-row row"> ' . $wrapper;
     			}
     
    -			/* Add an ending DIV if this field marks the end of a bootstrap row and we're displaying on the front-end... */		
    +			/* Add an ending DIV if this field marks the end of a bootstrap row and we're displaying on the front-end... */
     			if ( ! empty( $this->field[ 'args' ][ 'boot_strap_row_fe_end' ] ) && true === $this->field[ 'args' ][ 'boot_strap_row_fe_end' ] && false === is_admin() ) {
     				$wrapper .= ' </div> ' ;
    -			}			
    -			
    +			}
    +
     			$field       = $this->get_field_markup();
    -			
    +
     			$description = $this->get_field_description();
     
     			if ( ! empty( $description ) ) {
    @@ -850,8 +850,9 @@ public function get_output() {
     		 */
     		public function get_sanitized_value( $value ) {
     
    +			$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
     			$sanitize_function = 'sanitize_text_field' ;
    -			
    +
     			if ( isset( $this->field[ 'args' ][ 'sanitize' ] ) ) {
     				$sanitize_function = function_exists( $this->field[ 'args' ][ 'sanitize' ] ) ? $this->field[ 'args' ][ 'sanitize' ] : 'sanitize_text_field';
     			}
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.