You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
serializeAttributesinpackages/utils/src/dom/attributes.tsinterpolates attribute values into an HTML string without escaping quotes or</>. The result is assigned tothis.shadowRoot!.innerHTMLinCustomMediaElement'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 fromthis.attributesunfiltered. Pages that render user-controlled data into a media element attribute (e.g.<hls-video src={userInput}>) inherit this sink. The duplicateserializeAttributesinpackages/html/src/media/background-video/index.ts:93has the same bug.Reported by Codex during review of the security guide in #1559.
Tasks
",&,<,>in attribute values insideserializeAttributes(and the background-video duplicate, or delete it in favor of the shared util).CustomMediaElementwith a malicious attribute value and asserts no injected nodes end up in the shadow root.innerHTMLsinks for the same pattern.