fix(playground): warn when malformed HTML swallows the JS script#1705
Draft
caugner wants to merge 3 commits into
Draft
fix(playground): warn when malformed HTML swallows the JS script#1705caugner wants to merge 3 commits into
caugner wants to merge 3 commits into
Conversation
An unclosed or malformed tag in the HTML input (e.g. `<o`) is parsed such that the following `<script>` element becomes attributes of the open tag, leaving the user's JavaScript source rendered as visible text instead of executing. Add an `id` to the JS `<script>` and a post-rendering check in the runner document that verifies it parsed as an `HTMLScriptElement`. When it did not, emit a `console.warn` pointing the user at the malformed tag.
Contributor
|
ccf9c76 was deployed to: https://fred-pr1705.review.mdn.allizom.net/ |
User CSS containing `</style` or user JS containing `</script` (for example inside a string) terminated the runner's `<style>` / `<script>` element early, corrupting the page and allowing arbitrary markup to be injected after it. Escape those sequences by inserting a backslash (`<\/style`, `<\/script`), which stops the HTML parser from ending the element while remaining equivalent inside CSS/JS strings, template literals, and regexes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Harden the Playground runner's content assembly (
vendor/yari/libs/play/index.js) against malformed input:<script>: add anidto the runner's JS<script>and a post-rendering check that verifies a<script>element with that id parsed (matched viaquerySelector("script#mdn-play-js"), so a user element reusing the id cannot trigger a false warning); when it did not, emit aconsole.warnpointing the user at the malformed tag.</style/</scriptsequences in user CSS/JS (<\/style,<\/script) so they can no longer terminate the<style>/<script>element early.Motivation
<o) is parsed such that the following<script>becomes attributes of the open tag, so the user's JavaScript renders as visible text instead of executing, with no indication why (When<ocharacters in Playground HTML input causes entire JavaScript input to show up in HTML preview #1440).</styleor JS containing</script(for example inside a string) terminated the corresponding element early, corrupting the page and allowing arbitrary markup to be injected after it.Additional details
The runner document is assembled in
renderHtml, where the raw HTML/CSS/JS are interpolated into the document.>), so it fires reliably. This implements the stop-gap agreed in the issue thread. The malformed HTML (and leaked JS text) still renders, but the user is now told why.<\/style/<\/scriptescaping is behavior-preserving within literal contents:\/resolves to/inside CSS/JS strings, template literals, and regexes, and already-escaped sequences are left untouched. (The one exception is the pathologicalx</script/— a<operator immediately followed by a regex literal beginning withscript— which is vanishingly rare.) Verified at the DOM level with parse5 that break-out payloads no longer inject stray elements while string values round-trip unchanged.</script. A<!--…<scriptsequence in user JS still pushes the parser into the script-data-double-escaped state, where the runner's own</script>no longer closes the element (swallowing everything after it, including the swallow warning). No backslash escape fixes this without changing behavior (<\!--is an invalid escape in/uregexes), so it is documented inescapeScriptTextrather than fixed here.test/unit/play/runner.test.jscover the escaping round-trip and break-out prevention, case preservation, the detection tagging, and pin the<!--<script>limitation.Related issues and pull requests
Fixes #1440.