Skip to content

fix: stop hot-linking third-party project logos in import-architectures.mjs - #251

Open
mrbobbytables wants to merge 1 commit into
mainfrom
fix-hotlinked-logos-248
Open

mrbobbytables wants to merge 1 commit into
mainfrom
fix-hotlinked-logos-248

Conversation

@mrbobbytables

Copy link
Copy Markdown
Member

Summary

Fixes #248.

projectAsset() in scripts/import-architectures.mjs returned the remote URL
unchanged whenever it did not match the narrow cncf/artwork
.../icon/color/<file> shape, and renderProjectCards() rendered that URL
directly as a card's logo= prop. CNCFProjectCard renders that value as an
<img src>, so every reader of an affected architecture page made an
unannounced request to whichever third-party host was referenced in the
upstream markdown (github.com, raw.githubusercontent.com,
landscape.cncf.io, upload.wikimedia.org, kubernetes-sigs.github.io),
disclosing IP/User-Agent/Referer and exposing the page to mutable, unreviewed
remote content chosen by whoever writes the upstream markdown.

Changes

  • Extracted projectAsset() into scripts/lib/project-asset.mjs and made it
    fail closed: it now returns null for any URL that does not resolve to
    a local /img/... asset, instead of the remote URL.
  • renderProjectCards() now omits the logo= prop entirely when no local
    asset is available. CNCFProjectCard already renders a first-letter
    fallback badge when logo is falsy, so affected cards degrade cleanly.
  • cleanMarkdown()'s inline-image handling is now null-safe.
  • Regenerated the 4 affected docs/architectures/*.md files, removing all 16
    hot-linked logo= attributes flagged in the issue. grep -c 'logo="http' docs/architectures/*.md is now 0 for every file.
  • Added tests/lib-project-asset.test.mjs covering the local-passthrough,
    mirrored-icon, and fail-closed-remote cases.

Completion criteria (from the issue)

  • projectAsset() never returns a remote URL
  • renderProjectCards() omits logo= when no local asset exists
  • cleanMarkdown() handles the null return without throwing
  • docs/architectures/*.md regenerated so grep -c 'logo="http' docs/architectures/*.md is 0
  • unit coverage for projectAsset() local/mirrored/remote cases

Scope note

The issue's recommendation also floated widening mirrorProjectAssets() to
mirror arbitrary upstream images at build time. That's a larger, separate
change (new fetch/pinning logic, maintainer sign-off on which origins to
trust) and isn't required by the completion criteria above, so it's left for
a follow-up if the CNCF wants those 16 logos restored via mirroring rather
than falling back to the letter badge.

Testing

  • npm run test:unit — 59/59 passing
  • npx prettier --check on all touched files

— hive: backend=copilot model=claude-sonnet-5

🐝 Hive Agent: contributor | SHA: 7856ff3

…es.mjs

projectAsset() previously returned the remote URL unchanged whenever it
did not match the narrow cncf/artwork `.../icon/color/<file>` shape,
and renderProjectCards() rendered that URL as a card's `logo=` prop.
CNCFProjectCard renders that value as an <img src>, so every reader of
an affected architecture page made an unannounced request to whichever
third-party host was referenced in the upstream markdown (github.com,
raw.githubusercontent.com, landscape.cncf.io, upload.wikimedia.org,
kubernetes-sigs.github.io), leaking IP/User-Agent/Referer and exposing
the page to mutable, unreviewed remote content.

Extract projectAsset() into scripts/lib/project-asset.mjs and make it
fail closed: return null for any URL that does not resolve to a local
/img/... asset. renderProjectCards() now omits the logo prop entirely
when no local asset is available, and cleanMarkdown()'s inline-image
handling is null-safe. CNCFProjectCard already renders a first-letter
fallback badge when logo is falsy, so affected cards degrade cleanly
instead of hot-linking a third party.

Regenerate the 4 affected docs/architectures/*.md files, removing the
16 hot-linked logo= attributes flagged in the issue.

Add tests/lib-project-asset.test.mjs covering the local-passthrough,
mirrored-icon, and fail-closed-remote cases.

Fixes #248

Signed-off-by: mrbobbytables <mrbobbytables@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant