Make WordPress Core


Ignore:
Timestamp:
09/04/2025 02:38:15 PM (5 months ago)
Author:
jonsurrell
Message:

HTML API: Prevent adding dangerous double-escape SCRIPT contents.

Prevent WP_Tag_Processor::set_modifiable_text() from allowing SCRIPT contents with "<script" like it does with "</script". Either of these sequences may affect the script element's close.

Developed in https://github.com/WordPress/wordpress-develop/pull/9560.

Props jonsurrell, westonruter, dmsnell.
See #63738.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/html-api/class-wp-html-tag-processor.php

    r60649 r60706  
    37813781        switch ( $this->get_tag() ) {
    37823782            case 'SCRIPT':
    3783                 /*
     3783                /**
    37843784                 * This is over-protective, but ensures the update doesn't break
    3785                  * out of the SCRIPT element. A more thorough check would need to
    3786                  * ensure that the script closing tag doesn't exist, and isn't
    3787                  * also "hidden" inside the script double-escaped state.
     3785                 * the HTML structure of the SCRIPT element.
    37883786                 *
    3789                  * It may seem like replacing `</script` with `<\/script` would
    3790                  * properly escape these things, but this could mask regex patterns
    3791                  * that previously worked. Resolve this by not sending `</script`
     3787                 * More thorough analysis could track the HTML tokenizer states
     3788                 * and to ensure that the SCRIPT element closes at the expected
     3789                 * SCRIPT close tag as is done in {@see ::skip_script_data()}.
     3790                 *
     3791                 * A SCRIPT element could be closed prematurely by contents
     3792                 * like `</script>`. A SCRIPT element could be prevented from
     3793                 * closing by contents like `<!--<script>`.
     3794                 *
     3795                 * The following strings are essential for dangerous content,
     3796                 * although they are insufficient on their own. This trade-off
     3797                 * prevents dangerous scripts from being sent to the browser.
     3798                 * It is also unlikely to produce HTML that may confuse more
     3799                 * basic HTML tooling.
    37923800                 */
    3793                 if ( false !== stripos( $plaintext_content, '</script' ) ) {
     3801                if (
     3802                    false !== stripos( $plaintext_content, '</script' ) ||
     3803                    false !== stripos( $plaintext_content, '<script' )
     3804                ) {
    37943805                    return false;
    37953806                }
Note: See TracChangeset for help on using the changeset viewer.