Skip to content

fix(playground): guard runner against markup break-out#1705

Open
caugner wants to merge 2 commits into
mainfrom
1440-playground-detect-swallowed-script
Open

fix(playground): guard runner against markup break-out#1705
caugner wants to merge 2 commits into
mainfrom
1440-playground-detect-swallowed-script

Conversation

@caugner

@caugner caugner commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

(⚠️ Mirrored to mdn/dex#435. ⚠️ )

Description

Harden the Playground runner content assembly (vendor/yari/libs/play/index.js) against malformed input:

  • Swallowed JS script: add an id to the JS <script> and a post-render check that warns (via console.warn) when it did not parse as an HTMLScriptElement. The check queries script#mdn-play-js specifically, so user HTML reusing the id cannot trigger a false warning.
  • CSS/JS break-out: escape literal </style / </script in user CSS/JS (<\/style, <\/script) so they can no longer terminate the element early.

Adds unit tests (test/unit/play/runner.test.js) covering the escaping, case preservation, the swallow-detection marker, and the known <!--<script> limitation.

Motivation

Additional details

The escaping is behavior-preserving (\/ resolves to / in CSS/JS strings, templates, and regexes; already-escaped sequences are untouched).

This file is mirrored in mdn/dex (cloud-function/src/internal/play/index.js), which serves the runner in deployed/review environments, so the fix is only observable outside local dev once mdn/dex#435 lands.

Related issues and pull requests

Fixes #1440.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

b720866 was deployed to: https://fred-pr1705.review.mdn.allizom.net/

Comment thread vendor/yari/libs/play/index.js
@caugner
caugner force-pushed the 1440-playground-detect-swallowed-script branch from 24b04be to 9623022 Compare July 17, 2026 14:25
@caugner caugner changed the title fix(playground): warn when malformed HTML swallows the JS script fix(playground): guard runner against markup break-out Jul 17, 2026
caugner added 2 commits July 17, 2026 16:48
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, with no indication of why.

Add `id="mdn-play-js"` 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.
The check queries `script#mdn-play-js` specifically, so user HTML reusing
the id cannot trigger a false warning.
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.
@caugner
caugner force-pushed the 1440-playground-detect-swallowed-script branch from 9623022 to 4f7eb53 Compare July 17, 2026 14:49
@caugner
caugner marked this pull request as ready for review July 17, 2026 14:51
@caugner
caugner requested a review from a team as a code owner July 17, 2026 14:51
@caugner
caugner requested a review from LeoMcA July 17, 2026 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When <o characters in Playground HTML input causes entire JavaScript input to show up in HTML preview

2 participants