Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/profile-builder/front-end/class-formbuilder.php
+++ b/profile-builder/front-end/class-formbuilder.php
@@ -259,9 +259,14 @@
return $redirect_old;
}
+ // Reject failed registrations
+ if ( is_wp_error( $user_id ) ) {
+ return $redirect_old;
+ }
+
$user_id = absint( $user_id );
- if ( ! $user_id || is_wp_error( $user_id ) ) {
+ if ( ! $user_id ) {
return $redirect_old;
}
@@ -371,7 +376,10 @@
do_action( 'wppb_after_saving_form_values',$_REQUEST, $this->args );
- if( ( isset( $_SERVER['REQUEST_METHOD'] ) && 'POST' === $_SERVER['REQUEST_METHOD'] ) && ( isset( $_POST['action'] ) && $_POST['action'] === $this->args['form_type'] ) ) {
+ if( $this->args['form_type'] == 'register' && is_wp_error( $user_id ) ) {
+ // Failed registration: show the error and re-render the form so the user can retry.
+ echo $message . wp_kses_post( apply_filters( 'wppb_general_top_error_message', '<p id="wppb_form_general_message" class="wppb-error">'. esc_html__( 'Something went wrong while creating the user account, please try again.', 'profile-builder' ) .'</p>' ) ); /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
+ } elseif( ( isset( $_SERVER['REQUEST_METHOD'] ) && 'POST' === $_SERVER['REQUEST_METHOD'] ) && ( isset( $_POST['action'] ) && $_POST['action'] === $this->args['form_type'] ) ) {
$form_message_tpl_start = apply_filters( 'wppb_form_message_tpl_start', '<p class="alert wppb-success" id="wppb_form_general_message">' );
$form_message_tpl_end = apply_filters( 'wppb_form_message_tpl_end', '</p>' );
@@ -668,7 +676,7 @@
$user_data->remove_all_caps();
foreach ($userdata['role'] as $role) {
- if ($role !== 'administrator' || $role !== 'super-admin')//make sure this doesn't happen for any reason
+ if ($role !== 'administrator' && $role !== 'super-admin')//make sure this doesn't happen for any reason
$user_data->add_role($role);
}
}
--- a/profile-builder/front-end/default-fields/email/email.php
+++ b/profile-builder/front-end/default-fields/email/email.php
@@ -29,7 +29,7 @@
$output = '
<label for="email">'.$item_title.$error_mark.'</label>
- <input class="text-input default_field_email '. apply_filters( 'wppb_fields_extra_css_class', '', $field ) .'" name="email" maxlength="'. apply_filters( 'wppb_maximum_character_length', 70, $field ) .'" type="email" id="email" value="'. esc_attr( $input_value ) .'" '. $extra_attr .' '. (( $form_location != 'register' ) ? $email_input_status : '') .' />';
+ <input class="text-input default_field_email '. apply_filters( 'wppb_fields_extra_css_class', '', $field ) .'" name="email" maxlength="'. apply_filters( 'wppb_maximum_character_length', 60, $field ) .'" type="email" id="email" value="'. esc_attr( $input_value ) .'" '. $extra_attr .' '. (( $form_location != 'register' ) ? $email_input_status : '') .' />';
if( !empty( $item_description ) )
$output .= '<span class="wppb-description-delimiter">'. $item_description .'</span>';
--- a/profile-builder/front-end/default-fields/upload/upload_helper_functions.php
+++ b/profile-builder/front-end/default-fields/upload/upload_helper_functions.php
@@ -551,6 +551,58 @@
}
}
+ // The field was not found among the top-level form fields. Repeater fields store
+ // their inner Upload fields in a separate option keyed by the repeater's
+ // meta-name, so those fields are never part of the wppb_manage_fields list scanned
+ // above. Scan the repeater groups as well, otherwise Simple Upload inside a
+ // Repeater field is silently rejected (the lookup fails and the file input clears).
+ return wppb_resolve_simple_upload_ajax_field_in_repeater( $post_name, $field_types, $all_fields );
+}
+
+/**
+ * Resolves a simple-upload AJAX `name` parameter to an Upload field nested inside a
+ * Repeater field.
+ *
+ * Repeater sub-fields are stored unindexed in an option keyed by the repeater's
+ * meta-name. On the front-end each group posts either "<slug>" (the first group) or
+ * "<slug>_N" (the Nth extra group), where <slug> is the dash-normalized wck slug of
+ * the inner field's meta-name.
+ *
+ * @param string $post_name Sanitized value of $_POST['name'] from the AJAX request.
+ * @param array $field_types Expected field type(s), e.g. array( 'Upload' ).
+ * @param array $all_fields The already-resolved top-level form fields.
+ *
+ * @return array|false Inner field definition array, or false when not found.
+ */
+function wppb_resolve_simple_upload_ajax_field_in_repeater( $post_name, $field_types, $all_fields ) {
+ foreach ( $all_fields as $form_field ) {
+ if ( empty( $form_field['field'] ) || $form_field['field'] !== 'Repeater' ) {
+ continue;
+ }
+
+ $repeater_group = get_option( $form_field['meta-name'], 'not_set' );
+ if ( $repeater_group === 'not_set' || ! is_array( $repeater_group ) ) {
+ continue;
+ }
+
+ foreach ( $repeater_group as $inner_field ) {
+ if ( empty( $inner_field['field'] ) || ! in_array( $inner_field['field'], $field_types, true ) ) {
+ continue;
+ }
+ if ( ! isset( $inner_field['simple-upload'] ) || $inner_field['simple-upload'] !== 'yes' ) {
+ continue;
+ }
+ if ( isset( $inner_field['woocommerce-checkout-field'] ) && $inner_field['woocommerce-checkout-field'] === 'Yes' ) {
+ continue;
+ }
+
+ $base_slug = str_replace( '-', '_', Wordpress_Creation_Kit_PB::wck_generate_slug( $inner_field['meta-name'], $inner_field ) );
+ if ( $base_slug === $post_name || preg_match( '/^' . preg_quote( $base_slug, '/' ) . '_[0-9]+$/', $post_name ) ) {
+ return $inner_field;
+ }
+ }
+ }
+
return false;
}
--- a/profile-builder/front-end/default-fields/username/username.php
+++ b/profile-builder/front-end/default-fields/username/username.php
@@ -25,7 +25,7 @@
$output = '
<label for="username">'.$item_title.$error_mark.'</label>
- <input class="text-input default_field_username '. apply_filters( 'wppb_fields_extra_css_class', '', $field ) .'" name="username" maxlength="'. apply_filters( 'wppb_maximum_character_length', 70, $field ) .'" type="text" id="username" value="'. esc_attr( $input_value ) .'" '.$readonly.' '. $extra_attr .'/>';
+ <input class="text-input default_field_username '. apply_filters( 'wppb_fields_extra_css_class', '', $field ) .'" name="username" maxlength="'. apply_filters( 'wppb_maximum_character_length', 60, $field ) .'" type="text" id="username" value="'. esc_attr( $input_value ) .'" '.$readonly.' '. $extra_attr .'/>';
if( !empty( $item_description ) )
$output .= '<span class="wppb-description-delimiter">'.$item_description.'</span>';
}
@@ -54,6 +54,10 @@
if (!validate_username($request_data['username'])) {
return __('This username is invalid because it uses illegal characters.', 'profile-builder') . '<br/>' . __('Please enter a valid username.', 'profile-builder');
}
+ // WordPress core rejects usernames longer than 60 characters in wp_insert_user().
+ if ( mb_strlen( sanitize_user( trim( $request_data['username'] ) ) ) > 60 ) {
+ return __( 'This username is too long. It must be 60 characters or fewer.', 'profile-builder' );
+ }
}
$wppb_generalSettings = get_option('wppb_general_settings');
--- a/profile-builder/index.php
+++ b/profile-builder/index.php
@@ -3,7 +3,7 @@
* Plugin Name: Profile Builder
* Plugin URI: https://www.cozmoslabs.com/wordpress-profile-builder/
* Description: Login, registration and edit profile shortcodes for the front-end. Also you can choose what fields should be displayed or add new (custom) ones both in the front-end and in the dashboard.
- * Version: 3.16.4
+ * Version: 3.16.5
* Author: Cozmoslabs
* Author URI: https://www.cozmoslabs.com/
* Text Domain: profile-builder
@@ -447,7 +447,7 @@
*
*
*/
-define('PROFILE_BUILDER_VERSION', '3.16.4' );
+define('PROFILE_BUILDER_VERSION', '3.16.5' );
define('WPPB_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WPPB_PLUGIN_URL', plugin_dir_url(__FILE__));
define('WPPB_PLUGIN_BASENAME', plugin_basename(__FILE__));
--- a/profile-builder/translation/profile-builder.catalog.php
+++ b/profile-builder/translation/profile-builder.catalog.php
@@ -1052,6 +1052,7 @@
<?php __('The account %1$s has been successfully created!', 'profile-builder' ); ?>
<?php __("Before you can access your account %1s, you need to confirm your email address. Please check your inbox and click the activation link.", "profile-builder"); ?>
<?php __("Before you can access your account %1s, an administrator has to approve it. You will be notified via email.", "profile-builder"); ?>
+<?php __("Something went wrong while creating the user account, please try again.", "profile-builder"); ?>
<?php __("Update", "profile-builder"); ?>
<?php __("Add User", "profile-builder"); ?>
<?php __("Send these credentials via email.", "profile-builder"); ?>
@@ -2373,6 +2374,7 @@
<?php __("This username already exists.", "profile-builder"); ?>
<?php __("This username is invalid because it uses illegal characters.", "profile-builder"); ?>
<?php __("Please enter a valid username.", "profile-builder"); ?>
+<?php __("This username is too long. It must be 60 characters or fewer.", "profile-builder"); ?>
<?php __("This username is already reserved to be used soon.", "profile-builder"); ?>
<?php __("Something isn't right.", "profile-builder"); ?>
<?php __("You must enter a valid URL.", "profile-builder"); ?>