Make WordPress Core


Ignore:
Timestamp:
11/01/2021 02:12:09 AM (3 months ago)
Author:
pento
Message:

KSES: Add options for restricting tags based upon their attributes.

This change adds two now attribute-related config options to KSES:

  • An array of allowed values can be defined for attributes. If the attribute value doesn't fall into the list, the attribute will be removed from the tag.
  • Attributes can be marked as required. If a required attribute is not present, KSES will remove all attributes from the tag. As KSES doesn't match opening and closing tags, it's not possible to safely remove the tag itself, the safest fallback is to strip all attributes from the tag, instead.

Included with this change is an implementation of these options, allowing the <object> tag to be stored in posts, but only when it has a type attribute set to application/pdf.

Props pento, swissspidy, peterwilsoncc, dd32, jorbin.
Fixes #54261.

File:
1 edited

Legend:

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

    r51729 r51963  
    271271            'lang'     => true,
    272272            'xml:lang' => true,
     273        ),
     274        'object'     => array(
     275            'data' => true,
     276            'type' => array(
     277                'required' => true,
     278                'values'   => array( 'application/pdf' ),
     279            ),
    273280        ),
    274281        'p'          => array(
     
    11661173    $attrarr = wp_kses_hair( $attr, $allowed_protocols );
    11671174
     1175    // Check if there are attributes that are required.
     1176    $required_attrs = array_filter(
     1177        $allowed_html[ $element_low ],
     1178        function( $required_attr_limits ) {
     1179            return isset( $required_attr_limits['required'] ) && true === $required_attr_limits['required'];
     1180        }
     1181    );
     1182
     1183    // If a required attribute check fails, we can return nothing for a self-closing tag,
     1184    // but for a non-self-closing tag the best option is to return the element with attributes,
     1185    // as KSES doesn't handle matching the relevant closing tag.
     1186    $stripped_tag = '';
     1187    if ( empty( $xhtml_slash ) ) {
     1188        $stripped_tag = "<$element>";
     1189    }
     1190
    11681191    // Go through $attrarr, and save the allowed attributes for this element
    11691192    // in $attr2.
    11701193    $attr2 = '';
    11711194    foreach ( $attrarr as $arreach ) {
     1195        // Check if this attribute is required.
     1196        $required = isset( $required_attrs[ strtolower( $arreach['name'] ) ] );
     1197
    11721198        if ( wp_kses_attr_check( $arreach['name'], $arreach['value'], $arreach['whole'], $arreach['vless'], $element, $allowed_html ) ) {
    11731199            $attr2 .= ' ' . $arreach['whole'];
     1200
     1201            // If this was a required attribute, we can mark it as found.
     1202            if ( $required ) {
     1203                unset( $required_attrs[ strtolower( $arreach['name'] ) ] );
     1204            }
     1205        } elseif ( $required ) {
     1206            // This attribute was required, but didn't pass the check. The entire tag is not allowed.
     1207            return $stripped_tag;
    11741208        }
     1209    }
     1210
     1211    // If some required attributes weren't set, the entire tag is not allowed.
     1212    if ( ! empty( $required_attrs ) ) {
     1213        return $stripped_tag;
    11751214    }
    11761215
     
    16011640            }
    16021641            break;
     1642
     1643        case 'values':
     1644            /*
     1645             * The values check is used when you want to make sure that the attribute
     1646             * has one of the given values.
     1647             */
     1648
     1649            if ( false === array_search( strtolower( $value ), $checkvalue, true ) ) {
     1650                $ok = false;
     1651            }
     1652            break;
    16031653    } // End switch.
    16041654
Note: See TracChangeset for help on using the changeset viewer.