Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : May 4, 2026

CVE-2024-13362: Freemius <= 2.10.1 – Reflected DOM-Based Cross-Site Scripting via url Parameter (automatic-youtube-gallery)

Severity Medium (CVSS 6.1)
CWE 79
Vulnerable Version 2.5.5
Patched Version 2.5.6
Disclosed April 29, 2026

Analysis Overview

Atomic Edge analysis of CVE-2024-13362: This is a reflected DOM-based cross-site scripting vulnerability affecting the Freemius SDK versions up to 2.10.1, as bundled in multiple WordPress plugins and themes including Automatic YouTube Gallery. The vulnerability allows unauthenticated attackers to inject arbitrary web scripts via the url parameter. The CVSS score is 6.1 (Medium).

The root cause is insufficient input sanitization and output escaping on the url parameter processed by the Freemius SDK. While the code diff shows multiple files changed across the Automatic YouTube Gallery plugin and its bundled Freemius SDK, the core issue involves how the SDK constructs URLs and handles user-supplied input. The vulnerable code path exists within the Freemius class files, specifically in trial promotion messages and menu URL generation. The SDK failed to properly escape or validate the url parameter before using it in JavaScript or HTML contexts.

An attacker can exploit this by crafting a malicious URL that includes JavaScript payloads in the url parameter. The attack vector is reflected XSS: the victim must click a crafted link. The payload executes in the context of the victim’s browser session on the WordPress admin or frontend. The attacker can use standard XSS payloads such as alert(1) or javascript:alert(1) within the url parameter, which the Freemius SDK then renders without proper escaping.

The patch addresses the issue by modifying several files to properly escape and validate output. Key changes include: adding width and height attributes to thumbnail images (improper image sanitization), restructuring admin notice containers with FS-specific CSS classes, and implementing checks for PHP 8.2 compatibility. The patch also adds logic to properly handle sticky admin notice dismissal JavaScript and corrects menu URL generation to use FS-specific filters. These changes prevent the injection of arbitrary HTML/JavaScript by ensuring user-controllable data is properly escaped before rendering.

Successful exploitation allows an attacker to execute arbitrary JavaScript in the victim’s browser. This can lead to session hijacking, credential theft, defacement of the WordPress site, or redirection to malicious sites. The attack does not require authentication, making it particularly dangerous for unauthenticated users who click a crafted link. The impact is limited to reflected XSS rather than stored XSS, but the broad distribution of the Freemius SDK across thousands of WordPress plugins amplifies the potential damage.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/automatic-youtube-gallery/automatic-youtube-gallery.php
+++ b/automatic-youtube-gallery/automatic-youtube-gallery.php
@@ -11,7 +11,7 @@
  * Plugin Name:       Automatic YouTube Gallery
  * Plugin URI:        https://plugins360.com/automatic-youtube-gallery/
  * Description:       Create responsive, modern & dynamic video galleries by simply adding a YouTube USERNAME, CHANNEL, PLAYLIST, SEARCH KEYWORDS, or a custom list of YouTube URLs.
- * Version:           2.5.5
+ * Version:           2.5.6
  * Author:            Team Plugins360
  * Author URI:        https://plugins360.com
  * License:           GPL-2.0+
@@ -30,7 +30,7 @@
 }
 // Current version of the plugin
 if ( !defined( 'AYG_VERSION' ) ) {
-    define( 'AYG_VERSION', '2.5.5' );
+    define( 'AYG_VERSION', '2.5.6' );
 }
 // Unique identifier of the plugin
 if ( !defined( 'AYG_SLUG' ) ) {
--- a/automatic-youtube-gallery/public/templates/thumbnail.php
+++ b/automatic-youtube-gallery/public/templates/thumbnail.php
@@ -44,7 +44,7 @@
         $image_url = apply_filters( 'ayg_thumbnail_image_url', $image_url, $video, $attributes );

         echo sprintf(
-            '<img src="%s" class="ayg-thumbnail-image" alt="%s" %s/>',
+            '<img src="%s" class="ayg-thumbnail-image" width="320" height="180" alt="%s" %s/>',
             esc_url( $image_url ),
             esc_attr( $video->title ),
             ( ! empty( $attributes['lazyload'] ) ? 'loading="lazy"' : '' )
--- a/automatic-youtube-gallery/vendor/freemius/includes/class-freemius.php
+++ b/automatic-youtube-gallery/vendor/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/automatic-youtube-gallery/vendor/freemius/includes/class-fs-plugin-updater.php
+++ b/automatic-youtube-gallery/vendor/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/automatic-youtube-gallery/vendor/freemius/includes/entities/class-fs-plugin-plan.php
+++ b/automatic-youtube-gallery/vendor/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/automatic-youtube-gallery/vendor/freemius/includes/entities/class-fs-site.php
+++ b/automatic-youtube-gallery/vendor/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/automatic-youtube-gallery/vendor/freemius/includes/entities/class-fs-user.php
+++ b/automatic-youtube-gallery/vendor/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/automatic-youtube-gallery/vendor/freemius/includes/managers/class-fs-admin-menu-manager.php
+++ b/automatic-youtube-gallery/vendor/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/automatic-youtube-gallery/vendor/freemius/includes/managers/class-fs-admin-notice-manager.php
+++ b/automatic-youtube-gallery/vendor/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/automatic-youtube-gallery/vendor/freemius/start.php
+++ b/automatic-youtube-gallery/vendor/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 --------------------------------------------------------------------

ModSecurity Protection Against This CVE

Here you will find our ModSecurity compatible rule to protect against this particular CVE.

ModSecurity
SecRule ARGS:url "@rx (?i)(?:<script[^>]*>.*?</script>|javascript:)" "id:202613362,phase:2,deny,status:403,msg:'Atomic Edge CVE-2024-13362: Reflected XSS via url parameter',logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',tag:'attack-xss',tag:'platform-wordpress',tag:'cve-2024-13362',tag:'package-freemius',ver:'atomic-edge/1.0',severity:'CRITICAL',t:none,t:urlDecodeUni,t:lowercase,block"
SecRule ARGS:url "@rx (?i)(?:alert|prompt|confirm)s*(" "id:202613363,phase:2,deny,status:403,msg:'Atomic Edge CVE-2024-13362: Reflected XSS via url parameter',logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',tag:'attack-xss',tag:'platform-wordpress',tag:'cve-2024-13362',tag:'package-freemius',ver:'atomic-edge/1.0',severity:'CRITICAL',t:none,t:urlDecodeUni,t:lowercase,block"
SecRule ARGS:url "@rx (?i)(?:on(?:load|click|error|mouseover|focus|blur|submit|change|keydown|keyup|keypress|scroll|resize|unload|abort|beforeunload|hashchange|message|offline|online|pagehide|pageshow|popstate|storage)s*=)" "id:202613364,phase:2,deny,status:403,msg:'Atomic Edge CVE-2024-13362: Reflected XSS via url parameter',logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',tag:'attack-xss',tag:'platform-wordpress',tag:'cve-2024-13362',tag:'package-freemius',ver:'atomic-edge/1.0',severity:'CRITICAL',t:none,t:urlDecodeUni,t:lowercase,block"

Frequently Asked Questions

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.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School