- added callbacks blacklist. Added PHP command execution functions here to exclude the running them from the custom callback;

This commit is contained in:
Nikita Sinelnikov
2022-09-30 12:31:40 +03:00
parent e1bc94c110
commit aa6a238c61
6 changed files with 75 additions and 31 deletions
@@ -1220,6 +1220,10 @@ if ( ! class_exists( 'um\admin\core\Admin_Builder' ) ) {
$arr_options['function_exists'] = function_exists( $um_callback_func );
}
if ( in_array( $um_callback_func, UM()->fields()->dropdown_options_source_blacklist(), true ) ) {
wp_send_json_error( __( 'This is not possible for security reasons. Don\'t use internal PHP functions.', 'ultimate-member' ) );
}
$arr_options['data'] = array();
if ( function_exists( $um_callback_func ) ) {
$arr_options['data'] = call_user_func( $um_callback_func );
+51 -25
View File
@@ -146,17 +146,19 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
if ( array_key_exists( 'custom_dropdown_options_source', $args ) ) {
if ( function_exists( wp_unslash( $args['custom_dropdown_options_source'] ) ) ) {
$allowed_callbacks = UM()->options()->get( 'allowed_choice_callbacks' );
if ( ! empty( $allowed_callbacks ) ) {
$allowed_callbacks = array_map( 'rtrim', explode( "\n", $allowed_callbacks ) );
$allowed_callbacks[] = $args['custom_dropdown_options_source'];
} else {
$allowed_callbacks = array( $args['custom_dropdown_options_source'] );
}
$allowed_callbacks = array_unique( $allowed_callbacks );
$allowed_callbacks = implode( "\r\n", $allowed_callbacks );
if ( ! in_array( $args['custom_dropdown_options_source'], UM()->fields()->dropdown_options_source_blacklist(), true ) ) {
$allowed_callbacks = UM()->options()->get( 'allowed_choice_callbacks' );
if ( ! empty( $allowed_callbacks ) ) {
$allowed_callbacks = array_map( 'rtrim', explode( "\n", $allowed_callbacks ) );
$allowed_callbacks[] = $args['custom_dropdown_options_source'];
} else {
$allowed_callbacks = array( $args['custom_dropdown_options_source'] );
}
$allowed_callbacks = array_unique( $allowed_callbacks );
$allowed_callbacks = implode( "\r\n", $allowed_callbacks );
UM()->options()->update( 'allowed_choice_callbacks', $allowed_callbacks );
UM()->options()->update( 'allowed_choice_callbacks', $allowed_callbacks );
}
}
}
@@ -201,19 +203,21 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
if ( array_key_exists( 'custom_dropdown_options_source', $args ) ) {
if ( function_exists( wp_unslash( $args['custom_dropdown_options_source'] ) ) ) {
$allowed_callbacks = UM()->options()->get( 'allowed_choice_callbacks' );
if ( ! empty( $allowed_callbacks ) ) {
$allowed_callbacks = array_map( 'rtrim', explode( "\n", $allowed_callbacks ) );
$allowed_callbacks[] = $args['custom_dropdown_options_source'];
} else {
$allowed_callbacks = array( $args['custom_dropdown_options_source'] );
if ( ! in_array( $args['custom_dropdown_options_source'], UM()->fields()->dropdown_options_source_blacklist(), true ) ) {
$allowed_callbacks = UM()->options()->get( 'allowed_choice_callbacks' );
if ( ! empty( $allowed_callbacks ) ) {
$allowed_callbacks = array_map( 'rtrim', explode( "\n", $allowed_callbacks ) );
$allowed_callbacks[] = $args['custom_dropdown_options_source'];
} else {
$allowed_callbacks = array( $args['custom_dropdown_options_source'] );
}
$allowed_callbacks = array_unique( $allowed_callbacks );
$allowed_callbacks = implode( "\r\n", $allowed_callbacks );
UM()->options()->update( 'allowed_choice_callbacks', $allowed_callbacks );
$args['custom_dropdown_options_source'] = wp_unslash( $args['custom_dropdown_options_source'] );
}
$allowed_callbacks = array_unique( $allowed_callbacks );
$allowed_callbacks = implode( "\r\n", $allowed_callbacks );
UM()->options()->update( 'allowed_choice_callbacks', $allowed_callbacks );
$args['custom_dropdown_options_source'] = wp_unslash( $args['custom_dropdown_options_source'] );
}
}
@@ -1291,6 +1295,17 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
return '';
}
public function dropdown_options_source_blacklist() {
$blacklist = array(
'phpinfo',
'exec',
'passthru',
'shell_exec',
'system',
);
$blacklist = apply_filters( 'um_dropdown_options_source_blacklist', $blacklist );
return $blacklist;
}
/**
* Gets selected option value from a callback function
@@ -1305,6 +1320,10 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
if ( in_array( $type, array( 'select', 'multiselect' ) ) && ! empty( $data['custom_dropdown_options_source'] ) ) {
if ( in_array( $data['custom_dropdown_options_source'], $this->dropdown_options_source_blacklist(), true ) ) {
return $value;
}
$has_custom_source = apply_filters( "um_has_dropdown_options_source__{$data['metakey']}", false );
if ( $has_custom_source ) {
@@ -1372,6 +1391,10 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
if ( in_array( $type, array( 'select', 'multiselect' ) ) && ! empty( $data['custom_dropdown_options_source'] ) ) {
if ( in_array( $data['custom_dropdown_options_source'], $this->dropdown_options_source_blacklist(), true ) ) {
return $arr_options;
}
if ( function_exists( $data['custom_dropdown_options_source'] ) ) {
if ( isset( $data['parent_dropdown_relationship'] ) ) {
$arr_options = call_user_func( $data['custom_dropdown_options_source'], $data['parent_dropdown_relationship'] );
@@ -3037,7 +3060,9 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
if ( ! empty( $data['custom_dropdown_options_source'] ) && $has_parent_option && function_exists( $data['custom_dropdown_options_source'] ) &&
um_user( $data['parent_dropdown_relationship'] )
) {
$options = call_user_func( $data['custom_dropdown_options_source'], $data['parent_dropdown_relationship'] );
if ( ! in_array( $data['custom_dropdown_options_source'], $this->dropdown_options_source_blacklist(), true ) ) {
$options = call_user_func( $data['custom_dropdown_options_source'], $data['parent_dropdown_relationship'] );
}
$disabled_by_parent_option = '';
if ( um_user( $form_key ) ) {
@@ -3053,10 +3078,11 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
// Child dropdown
if ( $has_parent_option ) {
if ( ! empty( $data['custom_dropdown_options_source'] ) && $has_parent_option &&
function_exists( $data['custom_dropdown_options_source'] ) && isset( UM()->form()->post_form[ $form_key ] ) ) {
$options = call_user_func( $data['custom_dropdown_options_source'], $data['parent_dropdown_relationship'] );
if ( ! in_array( $data['custom_dropdown_options_source'], $this->dropdown_options_source_blacklist(), true ) ) {
$options = call_user_func( $data['custom_dropdown_options_source'], $data['parent_dropdown_relationship'] );
}
}
}
+7
View File
@@ -148,6 +148,13 @@ if ( ! class_exists( 'um\core\Form' ) ) {
wp_send_json( $arr_options );
}
if ( in_array( $ajax_source_func, UM()->fields()->dropdown_options_source_blacklist(), true ) ) {
$arr_options['status'] = 'error';
$arr_options['message'] = __( 'This is not possible for security reasons.', 'ultimate-member' );
wp_send_json( $arr_options );
}
if ( isset( $_POST['form_id'] ) ) {
UM()->fields()->set_id = absint( $_POST['form_id'] );
}
+4 -2
View File
@@ -95,8 +95,10 @@ if ( ! class_exists( 'um\core\Validation' ) ) {
isset( $fields[ $key ]['custom_dropdown_options_source'] ) &&
! empty( $fields[ $key ]['custom_dropdown_options_source'] ) &&
function_exists( $fields[ $key ]['custom_dropdown_options_source'] ) ) {
$arr_options = call_user_func( $fields[ $key ]['custom_dropdown_options_source'] );
$fields[ $key ]['options'] = array_keys( $arr_options );
if ( ! in_array( $fields[ $key ]['custom_dropdown_options_source'], UM()->fields()->dropdown_options_source_blacklist(), true ) ) {
$arr_options = call_user_func( $fields[ $key ]['custom_dropdown_options_source'] );
$fields[ $key ]['options'] = array_keys( $arr_options );
}
}
// Unset changed value that doesn't match the option list
+6 -4
View File
@@ -294,10 +294,12 @@ function um_user_edit_profile( $args ) {
if ( isset( $array['options'] ) && in_array( $array['type'], array( 'select', 'multiselect' ) ) ) {
$options = array();
if ( ! empty( $array['custom_dropdown_options_source'] ) && function_exists( $array['custom_dropdown_options_source'] ) && ! $has_custom_source ) {
$callback_result = call_user_func( $array['custom_dropdown_options_source'], $array['options'] );
if ( is_array( $callback_result ) ) {
$options = array_keys( $callback_result );
if ( ! empty( $array['custom_dropdown_options_source'] ) && function_exists( $array['custom_dropdown_options_source'] ) && ! $has_custom_source ) {
if ( ! in_array( $array['custom_dropdown_options_source'], UM()->fields()->dropdown_options_source_blacklist(), true ) ) {
$callback_result = call_user_func( $array['custom_dropdown_options_source'], $array['options'] );
if ( is_array( $callback_result ) ) {
$options = array_keys( $callback_result );
}
}
}
+3
View File
@@ -694,6 +694,9 @@ add_filter( 'um_field_non_utf8_value', 'um_field_non_utf8_value' );
*/
function um_select_dropdown_dynamic_callback_options( $options, $data ) {
if ( ! empty( $data['custom_dropdown_options_source'] ) && function_exists( $data['custom_dropdown_options_source'] ) ) {
if ( in_array( $data['custom_dropdown_options_source'], UM()->fields()->dropdown_options_source_blacklist(), true ) ) {
return $options;
}
$options = call_user_func( $data['custom_dropdown_options_source'] );
}