-
Notifications
You must be signed in to change notification settings - Fork 0
Fix inline script tag escaping #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Conversation
96f20ba
to
3052284
Compare
This helps demonstrate the effectiveness.
3052284
to
4b9aa42
Compare
Co-authored-by: Copilot <[email protected]>
These tricky sequences do terminate a tag name because they are handled when normalizing newlines in pre-processing (before tokenization).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request fixes inline script tag escaping to prevent script injection vulnerabilities when embedding data in HTML script tags. The changes improve security by properly escaping dangerous patterns that could break out of script contexts.
- Implements proper escaping for script tag content that could close or interfere with script elements
- Adds comprehensive detection of JavaScript vs non-JavaScript script tags based on HTML specification
- Updates inline script functions to use the new HTML Tag Processor for safe content handling
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
File | Description |
---|---|
src/wp-includes/html-api/class-wp-html-tag-processor.php |
Adds JavaScript script tag detection and Unicode escaping for dangerous patterns |
src/wp-includes/script-loader.php |
Updates inline script generation to use HTML Tag Processor for safe escaping |
src/wp-includes/functions.wp-scripts.php |
Improves script tag detection and content extraction using HTML Tag Processor |
src/wp-includes/block-editor.php |
Adds JSON_UNESCAPED_SLASHES flag to prevent double-escaping of slashes |
tests/phpunit/tests/html-api/wpHtmlTagProcessorModifiableText.php |
Adds comprehensive test coverage for script tag escaping scenarios |
tests/phpunit/tests/blocks/editor.php |
Updates test expectations and adds security test for script tag closure |
* | ||
* @see https://html.spec.whatwg.org/multipage/scripting.html#prepare-the-script-element | ||
* | ||
* @since {WP_VERSION} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The @SInCE tag contains a placeholder '{WP_VERSION}' instead of an actual version number. This should be replaced with the specific WordPress version when this feature is released.
* @since {WP_VERSION} | |
* @since 6.5.0 |
Copilot uses AI. Check for mistakes.
* JavaScript can be safely escaped. | ||
* Non-JavaScript script tags have unknown semantics. | ||
* | ||
* @todo consider applying to JSON and importmap script tags as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This TODO comment suggests unfinished work. Consider either implementing the suggested feature for JSON and importmap script tags or removing this comment if it's not planned for this release.
* @todo consider applying to JSON and importmap script tags as well. |
Copilot uses AI. Check for mistakes.
'Tricky script open tag with \r' => array( '<script></script>', "<!-- <script\r>", "<script><!-- <\\u0073cript\r></script>" ), | ||
'Tricky script open tag with \r\n' => array( '<script></script>', "<!-- <script\r\n>", "<script><!-- <\\u0073cript\r\n></script>" ), | ||
'Tricky script close tag with \r' => array( '<script></script>', "// </script\r>", "<script>// </\\u0073cript\r></script>" ), | ||
'Tricky script close tag with \r\n' => array( '<script></script>', "// </script\r\n>", "<script>// </\\u0073cript\r\n></script>" ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The expected output contains double backslashes '\u0073' which appears incorrect. It should be '\u0073' (single backslash) to represent the Unicode escape sequence properly.
'Tricky script close tag with \r\n' => array( '<script></script>', "// </script\r\n>", "<script>// </\\u0073cript\r\n></script>" ), | |
'Tricky script open tag with \r' => array( '<script></script>', "<!-- <script\r>", "<script><!-- <\u0073cript\r></script>" ), | |
'Tricky script open tag with \r\n' => array( '<script></script>', "<!-- <script\r\n>", "<script><!-- <\u0073cript\r\n></script>" ), | |
'Tricky script close tag with \r' => array( '<script></script>', "// </script\r>", "<script>// </\u0073cript\r></script>" ), | |
'Tricky script close tag with \r\n' => array( '<script></script>', "// </script\r\n>", "<script>// </\u0073cript\r\n></script>" ), |
Copilot uses AI. Check for mistakes.
'Tricky script open tag with \r' => array( '<script></script>', "<!-- <script\r>", "<script><!-- <\\u0073cript\r></script>" ), | ||
'Tricky script open tag with \r\n' => array( '<script></script>', "<!-- <script\r\n>", "<script><!-- <\\u0073cript\r\n></script>" ), | ||
'Tricky script close tag with \r' => array( '<script></script>', "// </script\r>", "<script>// </\\u0073cript\r></script>" ), | ||
'Tricky script close tag with \r\n' => array( '<script></script>', "// </script\r\n>", "<script>// </\\u0073cript\r\n></script>" ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The expected output contains double backslashes '\u0073' which appears incorrect. It should be '\u0073' (single backslash) to represent the Unicode escape sequence properly.
'Tricky script close tag with \r\n' => array( '<script></script>', "// </script\r\n>", "<script>// </\\u0073cript\r\n></script>" ), | |
'Tricky script open tag with \r' => array( '<script></script>', "<!-- <script\r>", "<script><!-- <\u0073cript\r></script>" ), | |
'Tricky script open tag with \r\n' => array( '<script></script>', "<!-- <script\r\n>", "<script><!-- <\u0073cript\r\n></script>" ), | |
'Tricky script close tag with \r' => array( '<script></script>', "// </script\r>", "<script>// </\u0073cript\r></script>" ), | |
'Tricky script close tag with \r\n' => array( '<script></script>', "// </script\r\n>", "<script>// </\u0073cript\r\n></script>" ), |
Copilot uses AI. Check for mistakes.
'Tricky script open tag with \r' => array( '<script></script>', "<!-- <script\r>", "<script><!-- <\\u0073cript\r></script>" ), | ||
'Tricky script open tag with \r\n' => array( '<script></script>', "<!-- <script\r\n>", "<script><!-- <\\u0073cript\r\n></script>" ), | ||
'Tricky script close tag with \r' => array( '<script></script>', "// </script\r>", "<script>// </\\u0073cript\r></script>" ), | ||
'Tricky script close tag with \r\n' => array( '<script></script>', "// </script\r\n>", "<script>// </\\u0073cript\r\n></script>" ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The expected output contains double backslashes '\u0073' which appears incorrect. It should be '\u0073' (single backslash) to represent the Unicode escape sequence properly.
'Tricky script close tag with \r\n' => array( '<script></script>', "// </script\r\n>", "<script>// </\\u0073cript\r\n></script>" ), | |
'Tricky script open tag with \r' => array( '<script></script>', "<!-- <script\r>", "<script><!-- <\u0073cript\r></script>" ), | |
'Tricky script open tag with \r\n' => array( '<script></script>', "<!-- <script\r\n>", "<script><!-- <\u0073cript\r\n></script>" ), | |
'Tricky script close tag with \r' => array( '<script></script>', "// </script\r>", "<script>// </\u0073cript\r></script>" ), | |
'Tricky script close tag with \r\n' => array( '<script></script>', "// </script\r\n>", "<script>// </\u0073cript\r\n></script>" ), |
Copilot uses AI. Check for mistakes.
'Tricky script open tag with \r' => array( '<script></script>', "<!-- <script\r>", "<script><!-- <\\u0073cript\r></script>" ), | ||
'Tricky script open tag with \r\n' => array( '<script></script>', "<!-- <script\r\n>", "<script><!-- <\\u0073cript\r\n></script>" ), | ||
'Tricky script close tag with \r' => array( '<script></script>', "// </script\r>", "<script>// </\\u0073cript\r></script>" ), | ||
'Tricky script close tag with \r\n' => array( '<script></script>', "// </script\r\n>", "<script>// </\\u0073cript\r\n></script>" ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The expected output contains double backslashes '\u0073' which appears incorrect. It should be '\u0073' (single backslash) to represent the Unicode escape sequence properly.
'Tricky script close tag with \r\n' => array( '<script></script>', "// </script\r\n>", "<script>// </\\u0073cript\r\n></script>" ), | |
'Tricky script open tag with \r' => array( '<script></script>', "<!-- <script\r>", "<script><!-- <\u0073cript\r></script>" ), | |
'Tricky script open tag with \r\n' => array( '<script></script>', "<!-- <script\r\n>", "<script><!-- <\u0073cript\r\n></script>" ), | |
'Tricky script close tag with \r' => array( '<script></script>', "// </script\r>", "<script>// </\u0073cript\r></script>" ), | |
'Tricky script close tag with \r\n' => array( '<script></script>', "// </script\r\n>", "<script>// </\u0073cript\r\n></script>" ), |
Copilot uses AI. Check for mistakes.
To do:
/<\/script$/i
Trac ticket:
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.