Mobile nav dropdown aria-label can be corrupted by third-party wp_kses_allowed_html filters
@Alexia-Soare is already working on this.
Since Sep 18, 2026.
- Dominant language
- PHP
- Stars
- 306
- Forks
- 88
- Avg merge
- 2d 16h
- Merged PRs (30d)
- 12
Description
The mobile sidebar dropdown toggle button's aria-label is built using wp_filter_nohtml_kses(), which is not resilient to third-party plugins that hook wp_kses_allowed_html incorrectly. When such a plugin adds allowed tags without respecting WordPress's reserved 'strip' context, the wrapper Neve adds around the menu title survives instead of being stripped, producing a corrupted, HTML-tag-filled aria-label on every dropdown menu item.
Steps to reproduce:
- Activate Neve, create a menu with at least one item that has children (e.g. "Shop" with a submenu), assign it to the Primary location.
- Install and activate the "Booster for WooCommerce" plugin (woocommerce-jetpack) — any recent version.
- View the mobile menu markup (view-source, or inspect the dropdown toggle button for "Shop").
Expected:
<button ... aria-label="Toggle Shop">
Actual:
<button ... aria-label="Toggle <span class=\"menu-item-title-wrap dd-title\">Shop</span>">
Root cause:
nav_walker.php:154:
$toggle_aria_label = __( 'Toggle', 'neve' ) . ' ' . wp_filter_nohtml_kses( $title );
$title at this point already contains our own ... wrapper (added a few lines earlier). We rely on wp_filter_nohtml_kses() to strip it back down to plain text before using it as an attribute value.
wp_filter_nohtml_kses() is a core WP function whose own docblock says "This function expects slashed data" — it's designed for sanitizing raw form/DB-bound input, not for stripping tags out of HTML we built ourselves. Internally it calls wp_kses( $data, 'strip' ), and that 'strip' context is passed through the public, pluggable wp_kses_allowed_html filter. Any plugin that hooks that filter and adds tags without checking $context === 'strip' will cause tags to survive a call that's supposed to guarantee zero tags. (Confirmed: Booster for WooCommerce's wcj_add_allowed_html() does exactly this.)
The value does get passed through esc_attr() before being output, so this isn't an XSS/broken-HTML issue — but it's a real accessibility regression (screen readers announce raw markup instead of the menu label) and is visible to anyone inspecting the DOM or running an accessibility audit.
Suggested fix:
Use wp_strip_all_tags() instead, since it does a plain string-based tag strip and never touches the wp_kses_allowed_html filter chain:
$toggle_aria_label = __( 'Toggle', 'neve' ) . ' ' . wp_strip_all_tags( $title );
This makes the dropdown toggle immune to this entire class of third-party filter conflicts, regardless of what any given plugin does wrong.
Severity: Low visual/security impact (escaped output), but a real accessibility bug and a support-burden source, since it presents as "menu looks broken" reports that are hard for less technical users/reporters to diagnose as a plugin conflict.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.