Refactor password handling to bypass wp_unslash.

Introduce a dedicated method to handle password fields securely, avoiding `wp_unslash` for these fields. This enhances consistency and security when processing form data across the plugin.
This commit is contained in:
Mykyta Synelnikov
2025-02-12 17:47:19 +02:00
parent cbc8c24b35
commit 422d2b7c67
3 changed files with 102 additions and 81 deletions
+62 -69
View File
@@ -340,107 +340,100 @@ if ( ! class_exists( 'um\core\Account' ) ) {
}
}
/**
* Submit Account handler
* Process the submission of account details
*/
function account_submit() {
public function account_submit() {
if ( ! um_submitting_account_page() ) {
return;
}
if ( um_submitting_account_page() ) {
$formdata = wp_unslash( $_POST );
$formdata = wp_unslash( $_POST );
if ( isset( $_POST['user_password'] ) ) {
$formdata['user_password'] = trim( $_POST['user_password'] );
}
if ( isset( $_POST['confirm_user_password'] ) ) {
$formdata['confirm_user_password'] = trim( $_POST['confirm_user_password'] );
}
if ( isset( $_POST['current_user_password'] ) ) {
$formdata['current_user_password'] = trim( $_POST['current_user_password'] );
}
if ( isset( $_POST['single_user_password'] ) ) {
$formdata['single_user_password'] = trim( $_POST['single_user_password'] );
}
// Don't un-slash passwords in manner of WordPress native password field.
$fields_map = array(
'user_password',
'confirm_user_password',
'current_user_password',
'single_user_password',
);
$formdata = UM()->form()::ignore_formdata_unslash( $formdata, $fields_map );
UM()->form()->post_form = $formdata;
UM()->form()->post_form = $formdata;
/**
* UM hook
*
* @type action
* @title um_submit_account_errors_hook
* @description Validate process on account submit
* @input_vars
* [{"var":"$submitted","type":"array","desc":"Account Page Submitted data"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_submit_account_errors_hook', 'function_name', 10, 1 );
* @example
* <?php
* add_action( 'um_submit_account_errors_hook', 'my_submit_account_errors', 10, 1 );
* function my_submit_account_errors( $submitted ) {
* // your code here
* }
* ?>
*/
do_action( 'um_submit_account_errors_hook', UM()->form()->post_form );
if ( um_is_core_page( 'account' ) && get_query_var( 'um_tab' ) ) {
$this->current_tab = get_query_var( 'um_tab' );
} else {
$this->current_tab = UM()->form()->post_form['_um_account_tab'];
}
$this->current_tab = sanitize_key( $this->current_tab );
if ( ! isset( UM()->form()->errors ) ) {
/**
* UM hook
*
* @type action
* @title um_submit_account_errors_hook
* @description Validate process on account submit
* @title um_submit_account_details
* @description On success account submit
* @input_vars
* [{"var":"$submitted","type":"array","desc":"Account Page Submitted data"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_submit_account_errors_hook', 'function_name', 10, 1 );
* @usage add_action( 'um_submit_account_details', 'function_name', 10, 1 );
* @example
* <?php
* add_action( 'um_submit_account_errors_hook', 'my_submit_account_errors', 10, 1 );
* function my_submit_account_errors( $submitted ) {
* add_action( 'um_submit_account_details', 'my_submit_account_details', 10, 1 );
* function my_submit_account_details( $submitted ) {
* // your code here
* }
* ?>
*/
do_action( 'um_submit_account_errors_hook', UM()->form()->post_form );
do_action( 'um_submit_account_details', UM()->form()->post_form );
if ( um_is_core_page( 'account' ) && get_query_var( 'um_tab' ) ) {
$this->current_tab = get_query_var( 'um_tab' );
} else {
$this->current_tab = UM()->form()->post_form['_um_account_tab'];
}
} elseif ( UM()->form()->has_error( 'um_account_security' ) ) {
$url = '';
if ( um_is_core_page( 'account' ) ) {
$this->current_tab = sanitize_key( $this->current_tab );
$url = UM()->account()->tab_link( $this->current_tab );
if ( ! isset( UM()->form()->errors ) ) {
/**
* UM hook
*
* @type action
* @title um_submit_account_details
* @description On success account submit
* @input_vars
* [{"var":"$submitted","type":"array","desc":"Account Page Submitted data"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_submit_account_details', 'function_name', 10, 1 );
* @example
* <?php
* add_action( 'um_submit_account_details', 'my_submit_account_details', 10, 1 );
* function my_submit_account_details( $submitted ) {
* // your code here
* }
* ?>
*/
do_action( 'um_submit_account_details', UM()->form()->post_form );
$url = add_query_arg( 'err', 'account', $url );
} elseif ( UM()->form()->has_error( 'um_account_security' ) ) {
$url = '';
if ( um_is_core_page( 'account' ) ) {
if ( function_exists( 'icl_get_current_language' ) ) {
if ( icl_get_current_language() != icl_get_default_language() ) {
$url = UM()->permalinks()->get_current_url( true );
$url = add_query_arg( 'err', 'account', $url );
$url = UM()->account()->tab_link( $this->current_tab );
$url = add_query_arg( 'err', 'account', $url );
if ( function_exists( 'icl_get_current_language' ) ) {
if ( icl_get_current_language() != icl_get_default_language() ) {
$url = UM()->permalinks()->get_current_url( true );
$url = add_query_arg( 'err', 'account', $url );
exit( wp_redirect( $url ) );
}
exit( wp_redirect( $url ) );
}
}
exit( wp_redirect( $url ) );
}
exit( wp_redirect( $url ) );
}
}
/**
* Filter account fields
* @param array $predefined_fields
+33 -6
View File
@@ -453,6 +453,11 @@ if ( ! class_exists( 'um\core\Form' ) ) {
$arr_restricted_fields = UM()->fields()->get_restricted_fields_for_edit();
}
$password_fields = array(
'user_password',
'confirm_user_password',
);
$field_types_without_metakey = UM()->builtin()->get_fields_without_metakey();
foreach ( $custom_fields as $cf_k => $cf_data ) {
if ( ! array_key_exists( 'type', $cf_data ) || in_array( $cf_data['type'], $field_types_without_metakey, true ) ) {
@@ -462,6 +467,9 @@ if ( ! class_exists( 'um\core\Form' ) ) {
if ( array_key_exists( 'type', $cf_data ) && 'password' === $cf_data['type'] ) {
$ignore_keys[] = $cf_k;
$ignore_keys[] = 'confirm_' . $cf_k;
$password_fields[] = $cf_k;
$password_fields[] = 'confirm_' . $cf_k;
}
if ( 'profile' === $this->form_data['mode'] ) {
@@ -557,14 +565,15 @@ if ( ! class_exists( 'um\core\Form' ) ) {
do_action( 'um_before_submit_form_post', $this );
$formdata = wp_unslash( $_POST );
if ( isset( $formdata['form_id'] ) ) {
// Don't un-slash passwords in manner of WordPress native password field.
$form_id = absint( $formdata['form_id'] );
if ( isset( $_POST['user_password-' . $form_id] ) ) {
$formdata['user_password-' . $form_id] = trim( $_POST['user_password-' . $form_id] );
}
if ( isset( $_POST['confirm_user_password-' . $form_id] ) ) {
$formdata['confirm_user_password-' . $form_id] = trim( $_POST['confirm_user_password-' . $form_id] );
foreach ( $password_fields as &$password_field ) {
$password_field .= '-' . $form_id;
}
unset( $password_field );
$formdata = UM()->form()::ignore_formdata_unslash( $formdata, $password_fields );
}
/* save entire form as global */
@@ -1120,7 +1129,6 @@ if ( ! class_exists( 'um\core\Form' ) ) {
return $mode;
}
/**
* Get custom field roles
*
@@ -1177,5 +1185,24 @@ if ( ! class_exists( 'um\core\Form' ) ) {
return false;
}
/**
* Ignore of `wp_unslash()` for form data
*
* @param array $formdata The form data to process
* @param array $fields_map The fields map array
*
* @return array The updated form data
*/
public static function ignore_formdata_unslash( $formdata, $fields_map ) {
foreach ( $fields_map as $field ) {
if ( ! isset( $_POST[ $field ] ) ) {
continue;
}
$formdata[ $field ] = trim( $_POST[ $field ] );
}
return $formdata;
}
}
}
+7 -6
View File
@@ -339,12 +339,13 @@ if ( ! class_exists( 'um\core\Password' ) ) {
if ( $this->is_change_request() ) {
$formdata = wp_unslash( $_POST );
if ( isset( $_POST['user_password'] ) ) {
$formdata['user_password'] = trim( $_POST['user_password'] );
}
if ( isset( $_POST['confirm_user_password'] ) ) {
$formdata['confirm_user_password'] = trim( $_POST['confirm_user_password'] );
}
// Don't un-slash passwords in manner of WordPress native password field.
$fields_map = array(
'user_password',
'confirm_user_password',
);
$formdata = UM()->form()::ignore_formdata_unslash( $formdata, $fields_map );
UM()->form()->post_form = $formdata;