Skip to content

fix(composition): reserve the data-hypit-* attribute namespace - #441

Open
Wenjix wants to merge 1 commit into
hypit-ai:mainfrom
Wenjix:security/reserve-data-hypit-attributes
Open

Wenjix wants to merge 1 commit into
hypit-ai:mainfrom
Wenjix:security/reserve-data-hypit-attributes

Conversation

@Wenjix

@Wenjix Wenjix commented Oct 27, 2026 •

Copy link
Copy Markdown

Closes #449

Summary

  • 46 (low, CWE-918-adjacent): assertAttributes in packages/composition/src/track.ts admitted any data-[a-z0-9-]+ attribute, including the data-hypit-* names the compiler owns: data-hypit-resource-src / data-hypit-resource-href (deferred media activation) and the sampling/element-id attributes. In packages/html-program/src/document.ts authored attributes serialize before the compiler-owned deferredResource(...) call, and HTML keeps the first duplicate attribute — so an authored data-hypit-resource-src="https://evil/x" wins over the typed Artifact mapping, and the capture-scope runtime (packages/html-program/src/capture-scope.ts) promotes the attacker URL onto the element's real src/href. The capture host then fetches it — an SSRF primitive that also bypasses Artifact binding entirely.
  • Fix: assertAttributes now rejects any authored data-hypit-* name with a dedicated error (contains reserved attribute …). Legitimate emitters only use data-caption-* and data-fine-* namespaces — verified across the repo — so nothing valid is lost.

Behavior relative to main

Flow main this PR
element with data-caption-atom accepted accepted
element with authored data-hypit-resource-src emitted first, wins over compiler attr, runtime promotes attacker URL assertVisualTrackIdentity throws reserved attribute data-hypit-resource-src

Red / green

packages/composition/test/track.test.ts: new case builds an element carrying data-hypit-resource-src and asserts rejection — on main the attribute is admitted silently.

Verification

  • node --import tsx --test packages/composition/test/track.test.ts — 11 pass.
  • pnpm check — clean.
  • Repo-wide grep: no source emits data-hypit-* through element.attributes (only data-caption-*/data-fine-*).

Merge Danger

  • Authors who happened to use a data-hypit-* attribute name get a validation error where they previously got silent (and broken) compiler-owned semantics.

Checklist

  • The why is documented in this description.
  • Regression test added; fails on main, passes here.
  • TypeScript check clean.

Generated with Devin

Element attributes matching data-[a-z0-9-]+ were admitted wholesale,
including the data-hypit-* names the compiler uses for deferred media
resources and sampling state. Authored attributes serialize before
compiler-owned ones, and HTML parsing keeps the first duplicate, so an
authored data-hypit-resource-src chose the URL the activation runtime
promoted onto the element, bypassing typed Artifact binding.

Reject authored attributes under the reserved prefix.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 27, 2026 06:16

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

This branch has not been deployed

No deployments
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.

bug(composition): authored data-hypit-* attributes shadow compiler-owned resource names

2 participants