fix(community): validate profile website links before rendering - #273
Open
kubestellar-hive[bot] wants to merge 1 commit into
Open
kubestellar-hive[bot] wants to merge 1 commit into
kubestellar-hive[bot] wants to merge 1 commit into
Conversation
The community lightbox built its Website link with a startsWith("http")
test and, when that failed, concatenated the value onto "https://".
The value is the free-text blog field of a third-party GitHub profile,
copied verbatim into data/community-people.json by the scheduled refresh
and never reviewed, so a value such as trusted.example@attacker.example
produced a link whose visible prefix and real authority disagree.
Resolve the value through the URL parser instead: accept only http and
https, treat a scheme-less value as an https host rather than a string to
concatenate, and reject a userinfo authority. Percent-encode the social
handles profileUrl interpolates so a handle cannot add path segments.
The helper lives in src/lib/profile-links.mjs so it is importable by
node --test without a React renderer.
Closes #272
Signed-off-by: kubestellar-hive[bot] <kubestellar-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 |
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
src/components/CommunityPeople/index.jsbuilt the "Website" link of a memberlightbox with a
startsWith("http")substring test and, when that test failed,concatenated the value onto
https://.That value is not repository data.
scripts/fetch-community-people.mjscopiesthe free-text
blogfield of a third-party GitHub profile verbatim intodata/community-people.json, and.github/workflows/refresh-community-people.ymlcommits the result weekly without anyone editing it. So a value such as
www.cncf.io@attacker.example/loginbecamehttps://www.cncf.io@attacker.example/login— a published outbound link whosevisible prefix and real authority disagree.
This change resolves the value through the URL parser instead of testing a
prefix:
http:andhttps:are accepted; anything else is droppedconcatenate, so the userinfo trick no longer works
user@host) is rejected outrightgithub/linkedin/twitterhandles thatprofileUrl()interpolates are percent-encoded, so a handle cannot add path segments
An explicit
http://value is preserved rather than silently rewritten tohttps://— rewriting a person's stated URL can break the link, and theprotocol allowlist is the security control here.
data/community-people.jsoncurrently exercises both live paths:
abebars.io(bare host) andhttp://wangxu.me(explicit http).javascript:was never exploitable here — it failed the oldstartsWithtest and got the
https://prefix, which neutralised it. This is anunvalidated-redirect / link-spoofing fix, not an XSS fix, and the issue says so.
Files and cluster claimed
src/components/CommunityPeople/index.js(PersonDialoglinks array)src/lib/profile-links.mjs(new —websiteUrl(),profileUrl())tests/profile-links.test.mjs(new)Disjoint from the open PRs: #249 fixes the same substring-vs-URL class in
scripts/import-architectures.mjsrenderProjectCards, #266 touchesscripts/lib/project-assets.mjs, #214 adds tests forscripts/fetch-community-people.mjswithout changing it, and #268 coversuseFocusTrap. None of them touchessrc/components/CommunityPeople/index.jsor
src/lib/.The helper is a plain ESM module rather than a React module specifically so
node --testcan import it without a renderer.Verification
node --test tests/profile-links.test.mjs— 12/12 passnpm run test:unit— 67/67 passnpm run build—[SUCCESS] Generated static files in "build"; the bundlecontains the new helper and no longer contains the
startsWith("http")guardCloses #272
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