Skip to content

Bug: XSS via Unescaped Attribute Values in CustomMediaElement Shadow Root #1562

Description

@decepulis

Note

Triage estimate — cycle priority and story points were assigned during an AI-assisted planning pass and are rough first guesses. Confirm or adjust when you pick this up.

serializeAttributes in packages/utils/src/dom/attributes.ts interpolates attribute values into an HTML string without escaping quotes or </>. The result is assigned to this.shadowRoot!.innerHTML in CustomMediaElement's constructor (packages/core/src/dom/media/custom-media-element/index.ts:226), so any attribute on a custom media element that contains a " can break out of the attribute and inject arbitrary markup — including event handler attributes or <script> siblings — into the shadow root.

Attribute names come from getAttrsFromProps(ctor.properties), but the values come from this.attributes unfiltered. Pages that render user-controlled data into a media element attribute (e.g. <hls-video src={userInput}>) inherit this sink. The duplicate serializeAttributes in packages/html/src/media/background-video/index.ts:93 has the same bug.

Reported by Codex during review of the security guide in #1559.

Tasks

  • Escape ", &, <, > in attribute values inside serializeAttributes (and the background-video duplicate, or delete it in favor of the shared util).
  • Add unit tests covering quote-injection, angle-bracket injection, and ampersand handling.
  • Add an e2e/regression test that constructs a CustomMediaElement with a malicious attribute value and asserts no injected nodes end up in the shadow root.
  • Audit other innerHTML sinks for the same pattern.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions