Project: Wordpress Plugin Portfolio X 2.3.0

Vulnerability: #9223982 (2018-11-16 16:19:21)

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::save_fields /portfolio-x/inc/cmb2/includes/CMB2.php:549 (show/hide source)
529  		// Reset the object id
530  		$this->object_id( $stored_id );
531  
532  		return $sanitized_values;
533  	}
534  
535  	/**
536  	 * Loops through and saves field data
537  	 * @since  1.0.0
538  	 * @param  int    $object_id    Object ID
539  	 * @param  string $object_type  Type of object being saved. (e.g., post, user, or comment)
540  	 * @param  array  $data_to_save Array of key => value data for saving. Likely $_POST data.
541  	 */
542  	public function save_fields( $object_id = 0, $object_type = '', $data_to_save = array() ) {
543  
544  		// Fall-back to $_POST data
545  		$this->data_to_save = ! empty( $data_to_save ) ? $data_to_save : $_POST;
546  		$object_id = $this->object_id( $object_id );
547  		$object_type = $this->object_type( $object_type );
548  
549 $this->process_fields();
550 551 // If options page, save the updated options
@FUNCTION::cmb2_print_metabox_form /portfolio-x/inc/cmb2/includes/helper-functions.php:307 (show/hide source)
287  		'form_format' => '<form class="cmb-form" method="post" id="%1$s" enctype="multipart/form-data" encoding="multipart/form-data"><input type="hidden" name="object_id" value="%2$s">%3$s<input type="submit" name="submit-cmb" value="%4$s" class="button-primary"></form>',
288  		'save_button' => esc_html__( 'Save', 'cmb2' ),
289  		'object_type' => $cmb->mb_object_type(),
290  		'cmb_styles'  => $cmb->prop( 'cmb_styles' ),
291  		'enqueue_js'  => $cmb->prop( 'enqueue_js' ),
292  	) );
293  
294  	// Set object type explicitly (rather than trying to guess from context)
295  	$cmb->object_type( $args['object_type'] );
296  
297  	// Save the metabox if it's been submitted
298  	// check permissions
299  	// @todo more hardening?
300  	if (
301  		$cmb->prop( 'save_fields' )
302  		// check nonce
303  		&& isset( $_POST['submit-cmb'], $_POST['object_id'], $_POST[ $cmb->nonce() ] )
304  		&& wp_verify_nonce( $_POST[ $cmb->nonce() ], $cmb->nonce() )
305  		&& $object_id && $_POST['object_id'] == $object_id
306  	) {
307 $cmb->save_fields( $object_id, $cmb->object_type(), $_POST );
308 } 309
@FUNCTION::cmb2_get_metabox_form /portfolio-x/inc/cmb2/includes/helper-functions.php:262 (show/hide source)
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  
247  /**
248   * Retrieve a metabox form
249   * @since  2.0.0
250   * @param  mixed   $meta_box  Metabox config array or Metabox ID
251   * @param  int     $object_id Object ID
252   * @param  array   $args      Optional arguments array
253   * @return string             CMB2 html form markup
254   */
255  function cmb2_get_metabox_form( $meta_box, $object_id = 0, $args = array() ) {
256  
257  	$object_id = $object_id ? $object_id : get_the_ID();
258  	$cmb       = cmb2_get_metabox( $meta_box, $object_id );
259  
260  	ob_start();
261  	// Get cmb form
262 cmb2_print_metabox_form( $cmb, $object_id, $args );
263 $form = ob_get_contents(); 264 ob_end_clean();