Make WordPress Core

Opened 5 weeks ago

Last modified 5 weeks ago

#61455 new defect (bug)

wp_kses & block parser being used on pre_term_name hook

Reported by: brumack's profile brumack Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.5.4
Component: General Keywords: has-patch has-unit-tests
Focuses: Cc:


While I was experimenting with a custom parser, I noticed that the very first time the parser is called it's not being passed anything close to post content, or serialized block content.

During a page's initial load, the block parser runs, and if you dump its output the very first result will be the theme's name.

This is some example code I was running from a theme's functions file:

// this should run before template-canvas is required
add_filter('template_include', function($template) {
        global $fndry_ran;
        $fndry_ran = false;
        return $template;

class TestParser extends WP_Block_Parser {

        public function parse($document) {
                var_dump("document to parse",$document);

                return parent::parse($document);

add_filter('block_parser_class', function() {
        global $fndry_ran;
        if (!$fndry_ran) {
                $fndry_ran = true;
                return "TestParser";

        return 'WP_Block_Parser';

The resulting messages for me were:

string(17) "document to parse" string(13) "foundry-blank" string(17) "document to parse" string(233) " " // this contains the serialized post content

(Despite the code above this output was dumped twice because the parser is being called before template_include, which helped me figure out where it was coming from)
I managed to track down the culprit, and it appears as though during the main query construction, a term query is prepared and it results with wp_kses_hook sanitizing the term's name field, which at this point is just a string, as this is the query prepared for the wp_theme object. Weird that it's treating it as a potential source of block content though?

Tracking it down:

blocks.php:1413 filter_block_content => parse_blocks
formatting.php:5221 wp_pre_kses_block_attributes => filter_block_content
default-filters.php:296 => add_filter( 'pre_kses', 'wp_pre_kses_block_attributes', 10, 3 );
kses.php:95 function wp_kses_hook => apply_filters 'pre_kses' hook
kses.php:747 function wp_kses => wp_kses_hook
kses.php:2104 function wp_filter_kses => wp_kses
default-filters.php:23 => add_filter( $filter, 'wp_filter_kses' ); // part of array, $filter === 'pre_term_name'
taxonomy.php:1808 sanitize_term_field => apply_filters( "pre_term_{$field}", $value, $taxonomy )
class-wp-term-query.php:562 get_terms => $_name = stripslashes( sanitize_term_field( 'name', $_name, 0, reset( $taxonomies ), 'db' ) );
class-wp-term-query.php:310 query => $this->get_terms
// getting tired writing this out..
class-wp-term-query.php:247 get_sql => get_sql_clauses => get_sql_for_query => get_sql_for_clause => transform_query => $term_list = $term_query->query( $args )
class-wp-query.php:2246 get_posts => $clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' );
block-template-utils.php:1032 get_block_templates => $template_query = new WP_Query( $wp_query_args ); // yadda yadda eventually we get to get_posts
template.php:500 get_page_template => get_query_template => locate_block_template => resolve_block_template => get_block_templates
template-loader.php:82 => $template = call_user_func( $template_getter ); // in this case it was get_page_template

Exhausting lol.
Anyway, it just strikes me as odd that the parse block func is being called on something that by rights should (probably?) never contain block content. Seems like it could be streamlined, maybe providing a flag that kses functions should not treat the field like block content? idk. Either way its workaround-able for the time being, just a little inefficient.

Change History (1)

This ticket was mentioned in PR #6855 on WordPress/wordpress-develop by @snehapatil02.

5 weeks ago

  • Keywords has-patch has-unit-tests added

### Ticket:

### Changes Made
This PR enhances the KSES filtering mechanism in WordPress to improve handling of term names within content parsing. Specifically:

  • Code Changes: Updated wp_kses_hook and filter_block_content functions to include a context check (if ( current_filter() === 'pre_term_name' )) to bypass block content parsing for term names. This prevents term names from being mistakenly treated as block content during sanitization processes.

### Purpose

  • The purpose of these changes is to enhance the accuracy and efficiency of content filtering in WordPress, specifically when dealing with term names. By ensuring that term names are not parsed as block content, we improve security and performance while maintaining robust sanitization practices across different content types.
Note: See TracTickets for help on using tickets.