Make WordPress Core


Ignore:
Timestamp:
05/31/2026 07:30:28 AM (39 hours ago)
Author:
dmsnell
Message:

KSES: Decode style attribute before sending to safecss_filter_attr().

safecss_filter_attr() assumes that it receives already-unescaped HTML
attribute values. For example, consider the raw HTML string:

style="background:url("bg.png")"

This should be decoded and passed into safecss_filter_attr() as:

background:url("bg.png")

Unfortuantely this hasn’t been done in wp_kses_attr_check(), which
takes the output from wp_kses_hair() and sends it directly to the
filtering function.

In this patch, wp_kses_attr_check() unescapes the style attribute,
filters it, and then re-escapes it when updating the style value.

Tests added by Codex

Developed in: https://github.com/WordPress/wordpress-develop/pull/11868
Discussed in: https://core.trac.wordpress.org/ticket/65270

Props dmsnell, westonruter.
Fixes #65270.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/kses.php

    r61882 r62433  
    15571557
    15581558    if ( 'style' === $name_low ) {
    1559         $new_value = safecss_filter_attr( $value );
     1559        $decoded_value = WP_HTML_Decoder::decode_attribute( $value );
     1560        $new_value     = safecss_filter_attr( $decoded_value );
    15601561
    15611562        if ( empty( $new_value ) ) {
     
    15661567        }
    15671568
    1568         $whole = str_replace( $value, $new_value, $whole );
    1569         $value = $new_value;
     1569        if ( $new_value !== $decoded_value ) {
     1570            $encoded_value = esc_attr( $new_value );
     1571            $whole         = str_replace( $value, $encoded_value, $whole );
     1572            $value         = $encoded_value;
     1573        }
    15701574    }
    15711575
     
    25552559 * @since 6.9.0 Added support for `white-space`.
    25562560 *
    2557  * @param string $css        A string of CSS rules.
     2561 * @param string $css        A string of CSS rules, decoded from an HTML `style` attribute.
    25582562 * @param string $deprecated Not used.
    2559  * @return string Filtered string of CSS rules.
     2563 * @return string Filtered string of CSS rules, needing HTML escaping before sending back to a `style` attribute.
    25602564 */
    25612565function safecss_filter_attr( $css, $deprecated = '' ) {
     
    25692573    $allowed_protocols = wp_allowed_protocols();
    25702574
     2575    /** @todo Parse enough CSS to split rules without breaking on things like quoted strings. */
    25712576    $css_array = explode( ';', trim( $css ) );
    25722577
Note: See TracChangeset for help on using the changeset viewer.