Project: Wordpress Plugin Portfolio X 2.3.0

Vulnerability: #9223979 (2018-11-16 16:19:18)

Warning

There are many false positives, or unexploitable vulnerabilities. Please create working "PoC" exploit before reporting anything to vendor!

Details:

Sink @FUNCTION::add_metadata
Risk _POST
/portfolio-x/inc/cmb2/includes/CMB2_hookup.php:522 (show/hide source)
502  	 * @return null
503  	 */
504  	public function save_comment( $comment_id ) {
505  
506  		$can_edit = current_user_can( 'moderate_comments', $comment_id );
507  
508  		if ( $this->can_save( get_comment_type( $comment_id ) ) && $can_edit ) {
509  			$this->cmb->save_fields( $comment_id, 'comment', $_POST );
510  		}
511  	}
512  
513  	/**
514  	 * Save data from user fields
515  	 * @since  1.0.x
516  	 * @param  int   $user_id  User ID
517  	 * @return null
518  	 */
519  	public function save_user( $user_id ) {
520  		// check permissions
521  		if ( $this->can_save( 'user' ) ) {
522 $this->cmb->save_fields( $user_id, 'user', $_POST );
523 } 524 }
Threat level 1

Callstack:

CMB2_Field::update_data /portfolio-x/inc/cmb2/includes/CMB2_Field.php:340 (show/hide source)
320  		 * The dynamic portion of the hook, $a['field_id'], refers to the current
321  		 * field id paramater. Returning a non-null value
322  		 * will effectively short-circuit the function.
323  		 *
324  		 * @since 2.0.0
325  		 */
326  		$override = apply_filters( "cmb2_override_{$a['field_id']}_meta_save", $override, $a, $this->args(), $this );
327  
328  		// If override, return that
329  		if ( null !== $override ) {
330  			return $override;
331  		}
332  
333  		// Options page handling (or temp data store)
334  		if ( 'options-page' === $a['type'] || empty( $a['id'] ) ) {
335  			return cmb2_options( $a['id'] )->update( $a['field_id'], $a['value'], false, $a['single'] );
336  		}
337  
338  		// Add metadata if not single
339  		if ( ! $a['single'] ) {
340 return add_metadata( $a['type'], $a['id'], $a['field_id'], $a['value'], false );
341 } 342
CMB2::save_group_field /portfolio-x/inc/cmb2/includes/CMB2.php:754 (show/hide source)
734  					: false;
735  
736  				$is_updated = ( ! CMB2_Utils::isempty( $new_val ) && $new_val !== $old_val );
737  				$is_removed = ( CMB2_Utils::isempty( $new_val ) && ! CMB2_Utils::isempty( $old_val ) );
738  
739  				// Compare values and add to `$updated` array
740  				if ( $is_updated || $is_removed ) {
741  					$this->updated[] = $base_id . '::' . $field_group->index . '::' . $sub_id;
742  				}
743  
744  				// Add to `$saved` array
745  				$saved[ $field_group->index ][ $sub_id ] = $new_val;
746  
747  			}
748  
749  			$saved[ $field_group->index ] = CMB2_Utils::filter_empty( $saved[ $field_group->index ] );
750  		}
751  
752  		$saved = CMB2_Utils::filter_empty( $saved );
753  
754 return $field_group->update_data( $saved, true );
755 } 756
CMB2::save_group /portfolio-x/inc/cmb2/includes/CMB2.php:674 (show/hide source)
654  		 *
655  		 * @param int    $object_id   The ID of the current object
656  		 * @param string $updated     Array of field ids that were updated.
657  		 *                            Will only include field ids that had values change.
658  		 * @param array  $cmb         This CMB2 object
659  		 */
660  		do_action( "cmb2_save_{$object_type}_fields_{$this->cmb_id}", $object_id, $this->updated, $this );
661  	}
662  
663  	/**
664  	 * Save a repeatable group
665  	 * @since  1.x.x
666  	 * @param  array  $args Field arguments array
667  	 * @return mixed        Return of CMB2_Field::update_data()
668  	 */
669  	public function save_group( $args ) {
670  		if ( ! isset( $args['id'], $args['fields'] ) || ! is_array( $args['fields'] ) ) {
671  			return;
672  		}
673  
674 return $this->save_group_field( $this->get_new_field( $args ) );
675 } 676
CMB2::process_field /portfolio-x/inc/cmb2/includes/CMB2.php:588 (show/hide source)
568  		$this->prop( 'show_on', array() );
569  
570  		// save field ids of those that are updated
571  		$this->updated = array();
572  
573  		foreach ( $this->prop( 'fields' ) as $field_args ) {
574  			$this->process_field( $field_args );
575  		}
576  	}
577  
578  	/**
579  	 * Process and save a field
580  	 * @since  2.0.0
581  	 * @param  array  $field_args Array of field arguments
582  	 */
583  	public function process_field( $field_args ) {
584  
585  		switch ( $field_args['type'] ) {
586  
587  			case 'group':
588 if ( $this->save_group( $field_args ) ) {
589 $this->updated[] = $field_args['id']; 590 }
CMB2::process_fields /portfolio-x/inc/cmb2/includes/CMB2.php:574 (show/hide source)
554  		}
555  
556  		$this->after_save();
557  	}
558  
559  	/**
560  	 * Process and save form fields
561  	 * @since  2.0.0
562  	 */
563  	public function process_fields() {
564  
565  		$this->pre_process();
566  
567  		// Remove the show_on properties so saving works
568  		$this->prop( 'show_on', array() );
569  
570  		// save field ids of those that are updated
571  		$this->updated = array();
572  
573  		foreach ( $this->prop( 'fields' ) as $field_args ) {
574 $this->process_field( $field_args );
575 } 576 }
CMB2::get_sanitized_values /portfolio-x/inc/cmb2/includes/CMB2.php:521 (show/hide source)
501  			}
502  		}
503  	}
504  
505  	/**
506  	 * Returns array of sanitized field values (without saving them)
507  	 * @since  2.0.3
508  	 * @param  array  $data_to_sanitize Array of field_id => value data for sanitizing (likely $_POST data).
509  	 */
510  	public function get_sanitized_values( array $data_to_sanitize ) {
511  		$this->data_to_save = $data_to_sanitize;
512  		$stored_id          = $this->object_id();
513  
514  		// We do this So CMB will sanitize our data for us, but not save it
515  		$this->object_id( '_' );
516  
517  		// Ensure temp. data store is empty
518  		cmb2_options( 0 )->set();
519  
520  		// Process/save fields
521 $this->process_fields();
522 523 // Get data from temp. data store
@FUNCTION::cmb2_get_metabox_sanitized_values /portfolio-x/inc/cmb2/includes/helper-functions.php:244 (show/hide source)
224  	if ( $cmb && $object_id ) {
225  		$cmb->object_id( $object_id );
226  	}
227  
228  	if ( $cmb && $object_type ) {
229  		$cmb->object_type( $object_type );
230  	}
231  
232  	return $cmb;
233  }
234  
235  /**
236   * Returns array of sanitized field values from a metabox (without saving them)
237   * @since  2.0.3
238   * @param  mixed $meta_box         Metabox ID or Metabox config array
239   * @param  array $data_to_sanitize Array of field_id => value data for sanitizing (likely $_POST data).
240   * @return mixed                   Array of sanitized values or false if no CMB2 object found
241   */
242  function cmb2_get_metabox_sanitized_values( $meta_box, array $data_to_sanitize ) {
243  	$cmb = cmb2_get_metabox( $meta_box );
244 return $cmb ? $cmb->get_sanitized_values( $data_to_sanitize ) : false;
245 } 246