- fixed vulnerability with banned keys in usermeta;

This commit is contained in:
Mykyta Synelnikov
2023-06-27 10:24:54 +03:00
parent 5c33c9b1d3
commit fb37b1cfc7
+47 -27
View File
@@ -78,6 +78,8 @@ if ( ! class_exists( 'um\core\User' ) ) {
*/
public $target_id = null;
public $updating_process = false;
/**
* User constructor.
*/
@@ -160,8 +162,30 @@ if ( ! class_exists( 'um\core\User' ) ) {
add_action( 'update_user_meta', array( &$this, 'flush_um_count_users_transient_update' ), 10, 4 );
add_action( 'added_user_meta', array( &$this, 'flush_um_count_users_transient_add' ), 10, 4 );
add_action( 'delete_user_meta', array( &$this, 'flush_um_count_users_transient_delete' ), 10, 4 );
add_action( 'update_user_metadata', array( &$this, 'avoid_banned_keys' ), 10, 3 );
}
/**
* Low-level checking to avoid updating banned user metakeys while UM Forms submission.
*
* @param null|bool $check Whether to allow updating metadata for the given type.
* @param int $object_id ID of the object metadata is for.
* @param string $meta_key Metadata key.
*
* @return null|bool
*/
public function avoid_banned_keys( $check, $object_id, $meta_key ) {
if ( false === $this->updating_process ) {
return $check;
}
if ( in_array( $meta_key, $this->banned_keys, true ) ) {
$check = false;
}
return $check;
}
/**
* @param $meta_ids
@@ -2104,57 +2128,53 @@ if ( ! class_exists( 'um\core\User' ) ) {
um_deprecated_function( 'update_files', '2.1.0', '' );
}
/**
* Update profile
*
* @param $changes
*/
function update_profile( $changes ) {
$args['ID'] = $this->id;
public function update_profile( $changes ) {
$this->updating_process = true;
$args['ID'] = $this->id;
/**
* UM hook
* Filters the update profile changes data.
*
* @type filter
* @title um_before_update_profile
* @description Change update profile changes data
* @input_vars
* [{"var":"$changes","type":"array","desc":"User Profile Changes"},
* {"var":"$user_id","type":"int","desc":"User ID"}]
* @change_log
* ["Since: 2.0"]
* @usage
* <?php add_filter( 'um_before_update_profile', 'function_name', 10, 2 ); ?>
* @example
* <?php
* add_filter( 'um_before_update_profile', 'my_before_update_profile', 10, 2 );
* function my_before_update_profile( $changes, $user_id ) {
* // your code here
* @since 1.3.x
* @hook um_before_update_profile
*
* @param {array} $changes User Profile Changes.
* @param {int} $user_id User ID.
*
* @return {array} User Profile Changes.
*
* @example <caption>Remove some_metakey from changes where user ID equals 12.</caption>
* function my_custom_um_prepare_user_results_array_meta( $changes, $user_id ) {
* if ( 12 === $user_id ) {
* unset( $changes['{some_metakey}'];
* }
* return $changes;
* }
* ?>
* add_filter( 'um_before_update_profile', 'my_custom_before_update_profile', 10, 2 );
*/
$changes = apply_filters( 'um_before_update_profile', $changes, $args['ID'] );
foreach ( $changes as $key => $value ) {
if ( in_array( $key, $this->banned_keys ) ) {
if ( in_array( $key, $this->banned_keys, true ) ) {
continue;
}
if ( ! in_array( $key, $this->update_user_keys ) ) {
if ( ! in_array( $key, $this->update_user_keys, true ) ) {
if ( $value === 0 ) {
update_user_meta( $this->id, $key, '0' );
} else {
update_user_meta( $this->id, $key, $value );
}
} else {
$args[ $key ] = $changes[ $key ];
$args[ $key ] = $value;
}
}
// update user
if ( count( $args ) > 1 ) {
//if isset roles argument validate role to properly for security reasons
@@ -2162,14 +2182,14 @@ if ( ! class_exists( 'um\core\User' ) ) {
global $wp_roles;
$exclude_roles = array_diff( array_keys( $wp_roles->roles ), UM()->roles()->get_editable_user_roles() );
if ( in_array( $args['role'], $exclude_roles ) ) {
if ( in_array( $args['role'], $exclude_roles, true ) ) {
unset( $args['role'] );
}
}
wp_update_user( $args );
}
$this->updating_process = false;
}