Skip to content

fix(security): reject imported architecture ids that claim the gate-exempt index.md page - #842

Merged
mrbobbytables merged 1 commit into
mainfrom
sec/reserved-architecture-page-ids
Sep 29, 2026
Merged

mrbobbytables merged 1 commit into
mainfrom
sec/reserved-architecture-page-ids

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Security Fix

scripts/validate-architectures.mjs scans every page under docs/architectures/
for active content and fails the build when it finds any, but it skips
REPO_AUTHORED_PAGES (index.md) — the hand-authored catalog landing page,
which legitimately renders layout elements and imports a component.

Nothing enforced the precondition that exemption relies on: that no imported
page can land on an exempt path. Both importers write
docs/architectures/<id>.md with an id derived from text the repository does
not control — a submission issue's "Organization or Team Name" answer
(scripts/import-architecture-issue.mjs), or an upstream cncf/architecture
directory name (scripts/import-architectures.mjs). slugify('Index') is
index, so a submission overwrites index.md with its own body and the gate
skips exactly that file.

Verified on main @ 7772dcf: a submission whose organization name is Index
and whose body carries <iframe src="https://evil.example/beacon"> overwrites
docs/architectures/index.md, and both validate:architectures and
validate:architecture-assets exit 0. The same body in any non-exempt page is
correctly rejected.

What this changes

  • scripts/lib/architecture-pages.mjs: adds RESERVED_PAGE_IDS, derived from
    REPO_AUTHORED_PAGES so the two cannot drift, plus isReservedPageId().
  • scripts/validate-architectures.mjs: rejects a catalog record whose id is
    reserved, beside the existing duplicate-id check, and notes at the exemption
    why the continue is now safe.

Gating at the validator covers every importer, including the two that write the
page, without editing either. .github/workflows/architecture-submission.yml
already runs npm run validate:architectures after its import step, so this
fails the run — issue comment, architecture-ready label removed — rather than
opening a pull request.

Previously the exploit was backstopped only incidentally, by
tests/architecture-catalog-contract.test.mjs filtering its page list with a
hard-coded name !== 'index.md'. That is a data-shape contract test that does
not mention the exemption; the security gate itself failed open.

Verification

  • Post-fix, the reproduction now fails closed: [error] index: id is reserved for a repo-authored page ..., exit 1.
  • Mutation-checked both directions: with the source change reverted, the 2 new test groups fail; restored, all pass.
  • node --test tests/architecture-pages.test.mjs tests/validate-architectures.test.mjs: 40 pass, 0 fail.
  • Coverage gate (--check 97 --check-source 99 --check-regions 93 --check-source-regions 97) exit 0; all four changed files at 100.00% lines / 100.00% regions.
  • prettier --check clean on all four files.

Claimed ground

scripts/lib/architecture-pages.mjs, scripts/validate-architectures.mjs,
tests/architecture-pages.test.mjs, tests/validate-architectures.test.mjs;
functions RESERVED_PAGE_IDS/isReservedPageId and the catalog-record loop in
validate-architectures.mjs.

Deliberately disjoint from the open hold-gated PRs on neighbouring files: #812
(scripts/import-architecture-issue.mjs, scripts/lib/mdx-escape.mjs), #827
(scripts/validate-architecture-assets.mjs), #836
(scripts/lib/svg-active-content.mjs), #810 and #820 (their respective test
files), #825 (tests/import-architectures.test.mjs and siblings). No file or
function here is touched by any of them.

Closes #841


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

…hored page

The active-content scan in validate-architectures.mjs skips
REPO_AUTHORED_PAGES (index.md), because the hand-authored catalog landing
page legitimately renders layout elements and imports a component. Nothing
enforced the precondition that exemption relies on: that no imported page
can land on an exempt path.

Both importers write docs/architectures/<id>.md with an id derived from
text the repository does not control - a submission issue's 'Organization
or Team Name' answer, or an upstream cncf/architecture directory name.
slugify('Index') is 'index', so a submission overwrites index.md with its
own body, and the gate skips exactly that file.

Derive RESERVED_PAGE_IDS from REPO_AUTHORED_PAGES so the two cannot drift,
and reject a catalog record claiming one. Gating at the validator covers
every importer without editing either.

Signed-off-by: hivecommons-hive[bot] <hivecommons-hive@hive.kubestellar.io>
@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 automatically remove the hold label once current policy no longer requires a level hold for "sec-check". If this is an outreach PR, a human must review it and remove the label.

@hivecommons-hive hivecommons-hive Bot added security Approved by a Hive merger/owner for auto-merge on green CI agent/security Approved by a Hive merger/owner for auto-merge on green CI hive/hosted-available-lke648397-260827-5n31 Approved by a Hive merger/owner for auto-merge on green CI labels Sep 29, 2026
@mrbobbytables
mrbobbytables added this pull request to the merge queue Sep 29, 2026
Merged via the queue into main with commit 70bc5c2 Sep 29, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent/security Approved by a Hive merger/owner for auto-merge on green CI hive/hosted-available-lke648397-260827-5n31 Approved by a Hive merger/owner for auto-merge on green CI security Approved by a Hive merger/owner for auto-merge on green CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[sec-check] imported architecture id can claim index.md, the page the active-content gate exempts

1 participant