SMS Alert – SMS & OTP for WooCommerce, Order Notifications & Abandoned Cart Recovery <= 3.9.3 - Missing Authorization
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:NTechnical Details
What Changed in the Fix
Changes introduced in v3.9.4
Source Code
WordPress.org SVN# 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 becauseadmin_initfires 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
- The plugin's main class
smsalert_WC_Order_SMSis instantiated. - During initialization, a callback is registered to a hook that executes early in the WordPress lifecycle (most likely
admin_initas seen in typical patterns for this plugin'soptionrouting). - The handler checks for the presence of
$_GET['option']or$_POST['option']. - In
js/admin.js, thelogout()andverifyUser()functions demonstrate that the plugin expects to handle actions likesmsalert-woocommerce-logoutandsmsalert-woocommerce-senderlistviaadmin.php. - The Flaw: The server-side logic associated with these
optionvalues performs state-changing operations (likedelete_option('smsalert_gateway')) before verifying if the user has themanage_optionscapability.
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:
- The nonce check is either entirely missing on the server-side for these specific
optionactions, OR - 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:
- Check Public Exposure: Search the homepage for localized scripts.
- JS Variable:
smsalert.nonce. - Extraction:
- Use
browser_navigateto the homepage. - Use
browser_eval("window.smsalert?.nonce")to extract the token.
- Use
5. Exploitation Strategy
We will target the smsalert-woocommerce-logout action to demonstrate an unauthorized state change.
Step-by-Step Plan:
- Preparation: Verify current plugin settings using WP-CLI.
- Execution: Send an unauthenticated request to
admin-post.phpwith the maliciousoption. - 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_gatewayoption from the database.
6. Test Data Setup
- Ensure WooCommerce and SMS Alert are installed and active.
- Configure a mock API key in the plugin settings so that
smsalert_gatewayis 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_gatewayoption 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.
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
@@ -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.