fix(security): parse members.json URLs instead of prefix-matching them - #731
Closed
hivecommons-hive[bot] wants to merge 1 commit into
Closed
hivecommons-hive[bot] wants to merge 1 commit into
hivecommons-hive[bot] wants to merge 1 commit into
Conversation
data/members.json renders as <a href> on /community/members via MemberProfile.js, but it has no validator script: there is no validate:members, nothing for it in ci.yml's validator list, and it is absent from READ_ONLY_VALIDATORS in validators-smoke.test.mjs. Its only gate was the /^https:\/\// prefix regex in members-data.test.mjs. That is the test validate-awards.mjs and validate-architectures.mjs already document as insufficient: "https://www.cncf.io@evil.example/" matches the prefix while resolving to evil.example, and the bare string "https://" matches while failing to parse at all. The awards cross-check does not compensate, because it compares only the slug/year/award key and never the URL values. Gate architectures[].sourceUrl, the three award URLs and every sourceAttribution entry on a parsed URL that must use https and must carry no userinfo, mirroring isHttpsUrl() in validate-architectures.mjs, and cover the spoofed forms. Signed-off-by: hivecommons-hive[bot] <hivecommons-hive@hive.kubestellar.io>
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 Hive will automatically remove the |
Member
|
Superseded by #753, which consolidates the six open security-fix PRs (commits cherry-picked unmodified, authorship and DCO preserved). |
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Security Fix
data/members.jsonis imported straight into the bundle(
src/components/MemberDirectory/index.js:2) and its URLs render as live<a href>links on/community/members—announcementUrl,caseStudyUrland
talkUrlinMemberProfile.js, plussourceAttribution[]andarchitectures[].sourceUrl.Unlike every other href-rendering data file it has no validator script:
no
validate:membersinpackage.json, nothing for it inci.yml'svalidator list, and it is absent from
READ_ONLY_VALIDATORSintests/validators-smoke.test.mjs. Its only gate was the/^https:\/\//prefix regex in
tests/members-data.test.mjs.That is precisely the test this repo's own validators document as
insufficient (
scripts/validate-awards.mjs:17-20,scripts/validate-architectures.mjs:22-29):https://www.cncf.io@evil.example/phishmatches the prefix while resolvingto
evil.example, and the bare stringhttps://matches while failing toparse at all. The awards cross-check does not compensate — it compares only
the
slug/year/awardkey, never the URL values.Before
Poisoning one
announcementUrlwithhttps://www.cncf.io@evil.example/phishleft every gate in the repository green:
After
What this changes
tests/members-data.test.mjsonly. AddshttpsUrlProblem()/assertHttpsUrl()— parse withnew URL(), requireprotocol === 'https:',reject any
username/password— mirroringisHttpsUrl()inscripts/validate-architectures.mjs, and applies it toarchitectures[].sourceUrl, the three award URLs andsourceAttribution[].Two regression tests cover the userinfo-spoofed, bare-
https://,wrong-scheme, whitespace and non-string forms alongside ordinary https links.
No workflow change is needed:
tests/members-data.test.mjsalready runs in CIthrough the
npm run test:unit:coverage:checkstep in.github/workflows/ci.yml.Verification
TZ=UTC node --test tests/members-data.test.mjs— 16/16 pass against real datanpm run test:unit:coverage:check— exit 0,src files100.00% lines / 97.95% regionsnpx prettier --check tests/members-data.test.mjs— cleandata/members.jsonis unmodified by this PRFiles/functions claimed:
tests/members-data.test.mjs(httpsUrlProblem,assertHttpsUrl, and the three URL assertions). Disjoint from #684(
scripts/validate-projects-born.mjs), #688 (validator fallback-labelcoverage), #717 (
validate-community-groups.mjs) and #725(
validate-community-people.mjs).Closes #730
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