Skip to content

fix(security): reject every markup-bearing data: media type and legacy script scheme in the MDX scanner - #1219

Closed
hivecommons-hive[bot] wants to merge 1 commit into
mainfrom
sec/fix-mdx-schemes
Closed

hivecommons-hive[bot] wants to merge 1 commit into
mainfrom
sec/fix-mdx-schemes

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Security Fix

scripts/validate-architectures.mjs gates every imported third-party
architecture body with findActiveContent() from
scripts/lib/mdx-active-content.mjs. Its DANGEROUS_URL_PATTERN recognised a
strictly smaller set of schemes than activeScheme() in
scripts/lib/svg-active-content.mjs, which guards imported SVGs against the
identical threat.

Before:

const DANGEROUS_URL_PATTERN = /(?:javascript|vbscript):|data:text\/html/gi;

Two gaps, both in that single constant:

  • Only data:text/html. A browser parses image/svg+xml,
    application/xhtml+xml, text/xml and application/xml as documents and
    runs <script> in them, so the identical payload passed under a sibling
    media type. This is the rationale svg-active-content.mjs:683-688 already
    states in its own comment (added by fix(security): reject every markup-bearing data: media type in activeScheme #1168) — only this file had not caught
    up.
  • Only javascript: and vbscript:. ACTIVE_SCHEMES
    (svg-active-content.mjs:32) also carries livescript: and mocha:.

Verified against main @ 593b9fe with base64 payloads, so no raw <element>
is present to trip the unrelated element scan and the scheme test is the only
thing that can produce a finding:

FLAGGED data text/html        script-capable URL scheme
MISSED  data image/svg+xml
MISSED  data application/xhtml+xml
MISSED  data text/xml
MISSED  data application/xml
FLAGGED javascript:           script-capable URL scheme
FLAGGED vbscript:             script-capable URL scheme
MISSED  livescript:
MISSED  mocha:

What changed

Exactly two files, no behaviour outside the scheme test:

  • scripts/lib/mdx-active-content.mjs — widen DANGEROUS_URL_PATTERN to the
    set svg-active-content.mjs already rejects, with a comment pointing at
    that module so the two stay paired.
  • tests/mdx-active-content.test.mjs — two new tests covering each of the
    four media types and both legacy schemes, including behind the character
    references normalizeSchemes() decodes.

Checks

  • node --test tests/mdx-active-content.test.mjs — 31/31 pass.
  • npx prettier --check on both changed files — clean.
  • Widening a gate can only break the build if existing content matches it:
    grep over docs/, blog/, data/ and src/ for all six newly gated
    forms returns nothing, so the validator stays green on the current tree.

The remaining unit-test files fail in this environment only because
node_modules is absent (Cannot find package 'react'); that is unrelated to
this diff.

Closes #1218


Filed by sec-check agent (ACMM L4/L5 — hold-gated mode). Hold-gated: human review required.

— hive: agent=sec-check backend=copilot model=claude-opus-5 copilot=1.0.88

…y script scheme in the MDX scanner

scripts/validate-architectures.mjs gates imported third-party architecture
bodies with findActiveContent() from scripts/lib/mdx-active-content.mjs, but
its DANGEROUS_URL_PATTERN recognised a strictly smaller set of schemes than
activeScheme() in scripts/lib/svg-active-content.mjs, which guards imported
SVGs against the identical threat.

Two gaps, both in that one constant:

  * Only data:text/html was matched. A browser parses image/svg+xml,
    application/xhtml+xml, text/xml and application/xml as documents too and
    runs <script> in them, so the identical payload passed under a sibling
    media type -- the rationale svg-active-content.mjs already states in its
    own comment.
  * Only javascript: and vbscript: were matched, while ACTIVE_SCHEMES also
    carries livescript: and mocha:.

Widen the constant so the two scanners agree, and cover each newly gated
scheme in tests/mdx-active-content.test.mjs, including behind the character
references normalizeSchemes() decodes. No existing docs/, blog/, data/ or
src/ content matches the widened pattern, so the gate stays green on the
current tree.

Closes #1218

Signed-off-by: sec-check <sec-check@hive.kubestellar.io>
@hivecommons-hive hivecommons-hive Bot added the hold label Oct 8, 2026
@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

Important

Held for human review by the hive's ACMM level gate.

This PR was opened by the "sec-check" agent while Hive policy required a human checkpoint for that agent. Non-outreach agents are held at ACMM L3–L5; the outreach agent is always held because it publishes project-facing communication.

Hive will keep the hold label until a human removes it. Operators can make a deliberate one-off release during an ACMM level change with release_level_holds=true, but level changes never release this hold automatically.

@mrbobbytables

Copy link
Copy Markdown
Member

Superseded by #1245, which replaces the regex scanners with parser-based ones (the approach decided on #1194) and covers this fix, with regression tests. Closing in favour of that PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[sec-check] mdx-active-content.mjs misses four markup-bearing data: types and two script schemes that the SVG scanner rejects

1 participant