Add validation for banned and blacklisted custom fields.

This update enhances security by introducing checks for banned and blacklisted meta keys in custom fields. It includes CSS updates for admin builder styles and ensures banned fields are flagged accurately in the site health tool.
This commit is contained in:
Mykyta Synelnikov
2025-04-15 18:08:44 +03:00
parent 8ef597ad74
commit f89b29426a
7 changed files with 95 additions and 67 deletions
+15
View File
@@ -495,6 +495,11 @@
line-height: 18px;
margin: 0 0 10px 0;
}
.um-admin-drag-col.cols-3 .um-admin-drag-fld-banned {
height: auto;
line-height: 18px;
margin: 0 0 10px 0;
}
.um-admin-drag-col.cols-3 .um-admin-drag-fld-icons {
float: none;
position: absolute;
@@ -600,6 +605,16 @@
color: #fff;
}
.um-admin-drag-fld-banned {
float: left;
font-size: 13px;
height: 30px;
line-height: 30px;
margin: 0 0 0 20px;
font-weight: 400;
color: var(--um-blocks-error-color, #d92d20);
}
.um-admin-drag-fld-icons {
float: right;
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+12
View File
@@ -400,6 +400,10 @@
height: auto
line-height: 18px
margin: 0 0 10px 0
.#{$prefix}admin-drag-fld-banned
height: auto
line-height: 18px
margin: 0 0 10px 0
.#{$prefix}admin-drag-fld-icons
float: none
position: absolute
@@ -492,6 +496,14 @@
&.um-field-type-group
color: #fff
.#{$prefix}admin-drag-fld-banned
float: left
font-size: 13px
height: 30px
line-height: 30px
margin: 0 0 0 20px
font-weight: 400
color: $error-text
.#{$prefix}admin-drag-fld-icons
float: right
+57 -62
View File
@@ -1,6 +1,8 @@
<?php
namespace um\admin;
use WP_Query;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@@ -48,11 +50,11 @@ class Site_Health {
);
}
// Searching in the global registered custom fields banned or blacklisted fields.
$custom_fields = get_option( 'um_fields', array() );
if ( ! empty( $custom_fields ) ) {
$keys = array_merge( UM()->builtin()->blacklist_fields, UM()->user()->banned_keys );
foreach ( $keys as $key ) {
if ( isset( $custom_fields[ $key ] ) ) {
foreach ( array_keys( $custom_fields ) as $key ) {
if ( self::field_is_banned( $key ) ) {
$tests['direct']['um_banned_fields'] = array(
'label' => esc_html__( 'Are the banned custom fields?', 'ultimate-member' ),
'test' => array( $this, 'banned_fields_test' ),
@@ -224,9 +226,11 @@ class Site_Health {
return $result;
}
public function get_banned_fields() {
$keys = array_merge( UM()->builtin()->blacklist_fields, UM()->user()->banned_keys );
private static function field_is_banned( $metakey ) {
return UM()->user()->is_metakey_banned( $metakey ) || in_array( strtolower( $metakey ), UM()->builtin()->blacklist_fields, true );
}
public function get_banned_fields() {
$result = array(
'description' => '',
'actions' => '',
@@ -252,14 +256,21 @@ class Site_Health {
if ( empty( $field['metakey'] ) ) {
continue;
}
if ( in_array( $field['metakey'], $keys, true ) ) {
$break_forms[] = array(
'id' => $form_id,
'title' => get_the_title( $form_id ),
'link' => get_edit_post_link( $form_id ),
'key' => $field['metakey'],
);
++$forms_count;
if ( self::field_is_banned( $field['metakey'] ) ) {
if ( ! array_key_exists( $form_id, $break_forms ) ) {
$break_forms[ $form_id ] = array(
'title' => get_the_title( $form_id ),
'link' => get_edit_post_link( $form_id ),
'fields' => array(
$field['metakey'] => isset( $field['title'] ) ? $field['title'] : __( 'Unknown title', 'ultimate-member' ),
),
);
++$forms_count;
} else {
$break_forms[ $form_id ]['fields'][ $field['metakey'] ] = isset( $field['title'] ) ? $field['title'] : __( 'Unknown title', 'ultimate-member' );
}
}
}
}
@@ -268,30 +279,26 @@ class Site_Health {
if ( 0 < $forms_count ) {
$result['description'] .= sprintf(
'<p>%s</p>',
__( 'Your fields in the Ultimate Member Forms are banned.', 'ultimate-member' )
__( 'Please note that some fields in your Ultimate Member Forms are currently on a restricted list that disallows their use. This is particularly related to the Ultimate Member Forms and their fields below.', 'ultimate-member' )
);
if ( ! empty( $break_forms ) ) {
$result['description'] .= sprintf(
'<p>%s',
__( 'Related to Ultimate Member Forms: ', 'ultimate-member' )
);
$forms_description = array();
foreach ( $break_forms as $form_id => $form_data ) {
$fields = array();
foreach ( $form_data['fields'] as $metakey => $field_title ) {
$fields[] = sprintf( __( '%s (<code>%s</code>)', 'ultimate-member' ), $field_title, $metakey );
}
$form_links = array();
foreach ( $break_forms as $break_form ) {
$form_links[] = sprintf(
'<a href="%s" target="_blank">%s in %s (#ID: %s)</a>',
esc_url( $break_form['link'] ),
esc_html__( 'field', 'ultimate-member' ) . ' "' . esc_html( $break_form['key'] ) . '"',
esc_html( $break_form['title'] ),
esc_html( $break_form['id'] )
);
$forms_description[] = '<h4>' . sprintf(
__( 'Fields in <a href="%s" target="_blank">%s (#ID: %s)</a>:', 'ultimate-member' ),
esc_url( $form_data['link'] ),
esc_html( $form_data['title'] ),
esc_html( $form_id )
) . '</h4><ul><li>' . implode( '</li><li>', $fields ) . '</li></ul>';
}
$result['description'] .= sprintf(
'%s</p><hr />',
implode( ', ', $form_links )
);
$result['description'] .= implode( ' ', $forms_description );
}
$result['actions'] .= sprintf(
@@ -301,12 +308,12 @@ class Site_Health {
);
}
$result = apply_filters( 'um_get_banned_fields_result', $result, $keys );
$result = apply_filters( 'um_get_banned_fields_result', $result );
if ( ! empty( $result['description'] ) ) {
$result['description'] .= sprintf(
'<p>%s</p>',
__( 'Using banned meta keys may break the website\'s functionality.', 'ultimate-member' )
__( 'The using meta keys from restricted list in Ultimate Member Forms may break the website\'s functionality and is unsecure.', 'ultimate-member' )
);
}
@@ -336,8 +343,8 @@ class Site_Health {
$banned_fields = $this->get_banned_fields();
if ( false !== $banned_fields ) {
$result['label'] = __( 'Some field from Ultimate Member forms has banned meta key', 'ultimate-member' );
$result['status'] = 'recommended';
$result['badge']['color'] = 'orange';
$result['status'] = 'critical';
$result['badge']['color'] = 'red';
$result['description'] = $banned_fields['description'];
$result['actions'] = $banned_fields['actions'];
}
@@ -375,7 +382,7 @@ class Site_Health {
}
private function get_field_data( $info, $key, $field_key, $field ) {
$row = isset( $field['metakey'] ) ? false : true;
$row = array_key_exists( 'type', $field ) && 'row' === $field['type'];
$title = $row ? __( 'Row: ', 'ultimate-member' ) . $field['id'] : __( 'Field: ', 'ultimate-member' ) . $field['metakey'];
$field = array_map( array( &$this, 'array_map' ), $field );
$field_info = array(
@@ -389,7 +396,7 @@ class Site_Health {
}
private function get_member_directories() {
$query = new \WP_Query();
$query = new WP_Query();
$member_directories = $query->query(
array(
'post_type' => 'um_directory',
@@ -1762,10 +1769,8 @@ class Site_Health {
),
)
);
}
if ( array_key_exists( '_um_login_redirect_url', $rolemeta ) && 'redirect_url' === $rolemeta['_um_login_redirect_url'] ) {
if ( array_key_exists( '_um_pending_url', $rolemeta ) ) {
if ( 'redirect_url' === $rolemeta['_um_after_login'] && array_key_exists( '_um_login_redirect_url', $rolemeta ) ) {
$info[ 'ultimate-member-' . $key ]['fields'] = array_merge(
$info[ 'ultimate-member-' . $key ]['fields'],
array(
@@ -1795,10 +1800,8 @@ class Site_Health {
),
)
);
}
if ( 'redirect_url' === $rolemeta['_um_after_logout'] ) {
if ( array_key_exists( '_um_logout_redirect_url', $rolemeta ) ) {
if ( 'redirect_url' === $rolemeta['_um_after_logout'] && array_key_exists( '_um_logout_redirect_url', $rolemeta ) ) {
$info[ 'ultimate-member-' . $key ]['fields'] = array_merge(
$info[ 'ultimate-member-' . $key ]['fields'],
array(
@@ -1824,10 +1827,8 @@ class Site_Health {
),
)
);
}
if ( 'redirect_url' === $rolemeta['_um_after_delete'] ) {
if ( array_key_exists( '_um_delete_redirect_url', $rolemeta ) ) {
if ( 'redirect_url' === $rolemeta['_um_after_delete'] && array_key_exists( '_um_delete_redirect_url', $rolemeta ) ) {
$info[ 'ultimate-member-' . $key ]['fields'] = array_merge(
$info[ 'ultimate-member-' . $key ]['fields'],
array(
@@ -1841,17 +1842,15 @@ class Site_Health {
}
if ( ! empty( $rolemeta['wp_capabilities'] ) ) {
if ( array_key_exists( 'wp_capabilities', $rolemeta ) ) {
$info[ 'ultimate-member-' . $key ]['fields'] = array_merge(
$info[ 'ultimate-member-' . $key ]['fields'],
array(
'um-wp_capabilities' => array(
'label' => __( 'WP Capabilities', 'ultimate-member' ),
'value' => $rolemeta['wp_capabilities'],
),
)
);
}
$info[ 'ultimate-member-' . $key ]['fields'] = array_merge(
$info[ 'ultimate-member-' . $key ]['fields'],
array(
'um-wp_capabilities' => array(
'label' => __( 'WP Capabilities', 'ultimate-member' ),
'value' => $rolemeta['wp_capabilities'],
),
)
);
}
$info = apply_filters( 'um_debug_information_user_role', $info, $key );
@@ -2295,11 +2294,7 @@ class Site_Health {
)
);
} else {
if ( isset( $options[ $field ] ) ) {
$sortby_label = $options[ $field ];
} else {
$sortby_label = $field;
}
$sortby_label = isset( $options[ $field ] ) ? $options[ $field ] : $field;
$info[ 'ultimate-member-directory-' . $key ]['fields'] = array_merge(
$info[ 'ultimate-member-directory-' . $key ]['fields'],
array(
@@ -546,6 +546,9 @@ if ( ! class_exists( 'um\admin\core\Admin_Builder' ) ) {
<?php echo ! empty( $field_title ) ? esc_html( $field_title ) : esc_html__( '(no title)', 'ultimate-member' ); ?>
</div>
<div class="um-admin-drag-fld-type um-field-type-<?php echo esc_attr( $field_type ); ?>"><?php echo esc_html( $field_name ); ?></div>
<?php if ( UM()->user()->is_metakey_banned( $key ) || in_array( strtolower( $key ), UM()->builtin()->blacklist_fields, true ) ) { ?>
<div class="um-admin-drag-fld-banned um-field-type-<?php echo esc_attr( $field_type ); ?>"><?php esc_html_e( 'This is not permitted for security reasons. For your safety, please remove it.', 'ultimate-member' ); ?></div>
<?php } ?>
<div class="um-admin-drag-fld-icons um-field-type-<?php echo esc_attr( $field_type ); ?>">
<a href="javascript:void(0);" class="um-tip-n" title="<?php esc_attr_e( 'Edit', 'ultimate-member' ); ?>" data-modal="UM_edit_field" data-modal-size="normal" data-dynamic-content="um_admin_edit_field_popup" data-arg1="<?php echo esc_attr( $field_type ); ?>" data-arg2="<?php echo esc_attr( $this->form_id ); ?>" data-arg3="<?php echo esc_attr( $key ); ?>"><i class="um-faicon-pencil"></i></a>
<a href="javascript:void(0);" class="um-tip-n um_admin_duplicate_field" title="<?php esc_attr_e( 'Duplicate', 'ultimate-member' ); ?>" data-silent_action="um_admin_duplicate_field" data-arg1="<?php echo esc_attr( $key ); ?>" data-arg2="<?php echo esc_attr( $this->form_id ); ?>"><i class="um-faicon-files-o"></i></a>
+7 -1
View File
@@ -34,6 +34,9 @@ if ( ! class_exists( 'um\core\Builtin' ) ) {
public $saved_fields = array();
/**
* Field keys that cannot be used as metakey when add new custom field to UM Form.
* Note: They are used both with function `UM()->user()->is_metakey_banned()` to avoid using unsecure metakeys.
*
* @var array
*/
public $blacklist_fields = array();
@@ -183,7 +186,7 @@ if ( ! class_exists( 'um\core\Builtin' ) ) {
* @return int|string Empty or error string.
*/
public function blacklist_field_err( $key ) {
if ( in_array( strtolower( $key ), $this->blacklist_fields, true ) || in_array( strtolower( $key ), UM()->user()->banned_keys, true ) ) {
if ( in_array( strtolower( $key ), $this->blacklist_fields, true ) || UM()->user()->is_metakey_banned( $key ) ) {
return __( 'Your meta key can not be used', 'ultimate-member' );
}
@@ -1426,6 +1429,9 @@ if ( ! class_exists( 'um\core\Builtin' ) ) {
public function set_blacklist_fields() {
$this->blacklist_fields = array(
'id',
'role',
'user_id',
'user_pass',
);
/**
-3
View File
@@ -93,9 +93,6 @@ if ( ! class_exists( 'um\core\User' ) ) {
$this->banned_keys = array(
'metabox',
'user_id',
'role',
'user_pass',
'postbox',
'meta-box',
'dismissed_wp_pointers',