Skip to content

WP 6.9 is over-sanitizing classes on the group block (and potentially other attributes) leading to rendering issues #73733

@briangrider

Description

@briangrider

Description

The issue: WP 6.9 is over-sanitizing classes (and potentially other attributes) on group blocks (and potentially other block types). "&," ">," and "<" are being converted to their respective HTML entities.

Why it's an issue: A common practice when using Tailwind is using descendant selectors (ie. using [&>p]:text-white to make all direct children p elements have the color white). This worked great up until WP 6.9. Now, with whatever changed regarding class sanitization on the group block, "&" in classes is being rendered as "&amp;", ">" is being rendered as "&gt;" and "<" is being rendered as "&lt;"

This causes significant issues for a major feature of Tailwind (descendant selectors) which was working as recently as the previous version of WP.

Proposed fix: These characters should be added to an exception list wherever this sanitization is happening as many hundreds of thousands of users use Tailwind with WP everyday. These characters still work fine on classes on a paragraph block so this is clearly not a security issue.

Step-by-step reproduction instructions

  1. Spin up a new install of WP. I'm using: https://pootleplayground.com/ (just add a single page with a random name to be able to launch the site in the upper right)
  2. Open a page in the site editor (or page editor)
  3. Choose or create a group block
  4. Add the class [&>p]:text-white on that group block
  5. Save the page
  6. View on the front end - the class will be over-sanitized, converting those characters to their HTML entities and breaking their potential usage with Tailwind. I'm temporarily fixing this with a custom snippet that uses the Tag Processor to reconvert those HTML entities back to their original form but this is less than ideal.
    Thank you in advance!

For anyone currently running into this issue, I'm using this snippet to get around it for now:

/**
 * Decode HTML entities in class attributes using WP_HTML_Tag_Processor
 */
add_filter( 'render_block', function( $html, $block ) {

    if ( empty( $block['blockName'] ) || $block['blockName'] !== 'core/group' ) {
        return $html;
    }
    
    if (
        empty( $html ) ||
        strpos( $html, 'class=' ) === false ||
        ( strpos( $html, '&amp;' ) === false && strpos( $html, '&gt;' ) === false && strpos( $html, '&lt;' ) === false )
    ) {
        return $html;
    }

    if ( ! class_exists( 'WP_HTML_Tag_Processor' ) ) {
        return $html;
    }

    $p = new WP_HTML_Tag_Processor( $html );

    while ( $p->next_tag() ) {

        // Skip unsafe tags
        if ( in_array( $p->get_tag(), [ 'SCRIPT', 'STYLE', 'SVG', 'CODE', 'PRE', 'TEXTAREA' ], true ) ) {
            continue;
        }

        $class = $p->get_attribute( 'class' );

        if ( $class === null ) {
            continue;
        }

        if (
            strpos( $class, '&amp;' ) === false &&
            strpos( $class, '&gt;' ) === false &&
            strpos( $class, '&lt;' ) === false
        ) {
            continue;
        }

        $decoded = html_entity_decode( $class, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
        $decoded = str_replace( "\0", '', $decoded );

        $p->set_attribute( 'class', $decoded );
    }

    return $p->get_updated_html();

}, 20, 2 );

Screenshots, screen recording, code snippet

No response

Environment info

  • WordPress 6.9 - Any block theme
  • Chrome
  • Windows 11

Please confirm that you have searched existing issues in the repo.

  • Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

  • Yes

Please confirm which theme type you used for testing.

  • Block
  • Classic
  • Hybrid (e.g. classic with theme.json)
  • Not sure

Metadata

Metadata

Assignees

No one assigned

    Labels

    [Feature] HTML APIAn API for updating HTML attributes in markup[Type] BugAn existing feature does not function as intended[Type] WP Core TicketRequires an upstream change from WordPress. Core Trac ticket should be linked.

    Type

    No type

    Projects

    Status

    ✅ Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions