CVE-2026-54802

SMS Alert – SMS & OTP for WooCommerce, Order Notifications & Abandoned Cart Recovery <= 3.9.3 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.9.4
Patched in
10d
Time to patch

Description

The SMS Alert – SMS & OTP for WooCommerce, Order Notifications & Abandoned Cart Recovery plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 3.9.3. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=3.9.3
PublishedJune 16, 2026
Last updatedJune 25, 2026
Affected pluginsms-alert

What Changed in the Fix

Changes introduced in v3.9.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-54802 (SMS Alert - Missing Authorization) ## 1. Vulnerability Summary The **SMS Alert – SMS & OTP for WooCommerce** plugin (versions <= 3.9.3) is vulnerable to **Missing Authorization**. The plugin registers a handler (likely on `admin_init` or `init`) that pr…

Show full research plan

Exploitation Research Plan: CVE-2026-54802 (SMS Alert - Missing Authorization)

1. Vulnerability Summary

The SMS Alert – SMS & OTP for WooCommerce plugin (versions <= 3.9.3) is vulnerable to Missing Authorization. The plugin registers a handler (likely on admin_init or init) that processes various administrative actions via an option HTTP parameter. Because this handler lacks a current_user_can() capability check, unauthenticated attackers can trigger sensitive actions—such as logging the site out of the SMS Alert service or triggering customer data synchronization—by simply sending a crafted request to the WordPress administrative entry points.

2. Attack Vector Analysis

  • Vulnerable Endpoints:
    • /wp-admin/admin-post.php (Targeted because admin_init fires here without requiring authentication).
    • /wp-admin/admin-ajax.php
  • Payload Parameter: option (GET or POST).
  • Vulnerable Actions (Values for option):
    • smsalert-woocommerce-logout: Clears plugin gateway settings, effectively disabling SMS/OTP functionality.
    • smsalert-group-sync: Triggers a synchronization process for user groups.
    • smsalert-woocommerce-creategroup: Attempts to create a new group in the SMS Alert service.
  • Authentication Level: Unauthenticated (Privileges Required: None).
  • Preconditions: The plugin must be active.

3. Code Flow

  1. The plugin's main class smsalert_WC_Order_SMS is instantiated.
  2. During initialization, a callback is registered to a hook that executes early in the WordPress lifecycle (most likely admin_init as seen in typical patterns for this plugin's option routing).
  3. The handler checks for the presence of $_GET['option'] or $_POST['option'].
  4. In js/admin.js, the logout() and verifyUser() functions demonstrate that the plugin expects to handle actions like smsalert-woocommerce-logout and smsalert-woocommerce-senderlist via admin.php.
  5. The Flaw: The server-side logic associated with these option values performs state-changing operations (like delete_option('smsalert_gateway')) before verifying if the user has the manage_options capability.

4. Nonce Acquisition Strategy

While the client-side js/admin.js passes a nonce (smsalert.nonce), the vulnerability description "Missing Authorization" and the CVSS vector PR:N suggest that:

  1. The nonce check is either entirely missing on the server-side for these specific option actions, OR
  2. The nonce is validated using a weak check (e.g., wp_verify_nonce($nonce, -1)), which can be satisfied by an unauthenticated nonce.

Strategy:
First, attempt the exploit without a nonce. If the response indicates a failure, the nonce can be retrieved as follows:

  1. Check Public Exposure: Search the homepage for localized scripts.
  2. JS Variable: smsalert.nonce.
  3. Extraction:
    • Use browser_navigate to the homepage.
    • Use browser_eval("window.smsalert?.nonce") to extract the token.

5. Exploitation Strategy

We will target the smsalert-woocommerce-logout action to demonstrate an unauthorized state change.

Step-by-Step Plan:

  1. Preparation: Verify current plugin settings using WP-CLI.
  2. Execution: Send an unauthenticated request to admin-post.php with the malicious option.
  3. Verification: Check if the plugin settings have been wiped.

Payload (Unauthenticated Logout):

  • Method: GET
  • URL: http://[target]/wp-admin/admin-post.php?option=smsalert-woocommerce-logout
  • Expected Result: The plugin should process the request and delete the smsalert_gateway option from the database.

6. Test Data Setup

  1. Ensure WooCommerce and SMS Alert are installed and active.
  2. Configure a mock API key in the plugin settings so that smsalert_gateway is populated.
    • wp option update smsalert_gateway '{"smsalert_api":"DUMMY_KEY","smsalert_password":"DUMMY_PASSWORD"}'

7. Expected Results

  • Success: The HTTP request returns a 200 or 302 status.
  • Impact: The smsalert_gateway option is removed or modified in the WordPress database, disabling the plugin's core functionality.

8. Verification Steps

After sending the HTTP request, verify the modification via WP-CLI:

# Check if the gateway option was deleted
wp option get smsalert_gateway

If the command returns "Error: Could not find the option with key 'smsalert_gateway'", the exploit was successful.

9. Alternative Approaches

If admin-post.php is blocked or fails, target the sync functionality:

  • Request: GET /wp-admin/admin-post.php?option=smsalert-group-sync&grp_name=pwned
  • Verification: Check for outbound requests or logs indicating a sync attempt was made unauthenticated.

If the logout action requires a nonce but doesn't check capabilities, use the browser_eval method described in Section 4 to obtain the nonce from the admin dashboard (if leaked) or any page where it is localized.

Research Findings
Static analysis — not yet PoC-verified

Summary

The SMS Alert plugin for WordPress is vulnerable to unauthorized access due to a lack of capability checks and nonce validation on its request handling logic. Unauthenticated attackers can exploit this by sending requests with specific 'option' parameters to administrative endpoints, allowing them to perform actions such as retrieving sensitive order information or resetting plugin settings.

Vulnerable Code

// handler/forms/woocommerce/wc-checkout.php line 2251
        $order_id = isset($_REQUEST['order_id']) ? sanitize_text_field(wp_unslash($_REQUEST['order_id'])) : '';
        $option   = isset($_REQUEST['option']) ? sanitize_text_field(wp_unslash($_REQUEST['option'])) : '';
		

        if (! empty($option) && ( 'fetch-order-variable' === sanitize_text_field($option) ) && ! empty($order_id) ) {
            $tokens = array();

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/sms-alert/3.9.3/handler/forms/woocommerce/wc-checkout.php /home/deploy/wp-safety.org/data/plugin-versions/sms-alert/3.9.4/handler/forms/woocommerce/wc-checkout.php
--- /home/deploy/wp-safety.org/data/plugin-versions/sms-alert/3.9.3/handler/forms/woocommerce/wc-checkout.php	2026-03-20 02:49:30.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/sms-alert/3.9.4/handler/forms/woocommerce/wc-checkout.php	2026-04-15 02:22:48.000000000 +0000
@@ -2251,8 +2251,7 @@
         $order_id = isset($_REQUEST['order_id']) ? sanitize_text_field(wp_unslash($_REQUEST['order_id'])) : '';
         $option   = isset($_REQUEST['option']) ? sanitize_text_field(wp_unslash($_REQUEST['option'])) : '';
 		
-
-        if (! empty($option) && ( 'fetch-order-variable' === sanitize_text_field($option) ) && ! empty($order_id) ) {
+        if (! empty($option) && ( 'fetch-order-variable' === sanitize_text_field($option) ) && ! empty($order_id) && current_user_can('manage_options') && wp_verify_nonce( $_REQUEST['sa_var_wp_nonce'], 'sa_var_wp_nonce' ) ) {
             $tokens = array();
 
             global $woocommerce, $post;

Exploit Outline

The vulnerability is exploited by sending an unauthenticated HTTP GET or POST request to the WordPress administrative backend (typically /wp-admin/admin-post.php or /wp-admin/admin.php). The attacker provides an 'option' parameter set to a sensitive action name (such as 'fetch-order-variable' or 'smsalert-woocommerce-logout'). Since the plugin's initialization hook processes these options without verifying the user's administrative privileges or checking for a valid security nonce, the requested action is executed. For the 'fetch-order-variable' action, providing an 'order_id' allows the attacker to retrieve customer and order details.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.