Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[sec-check] validate:end-user-talks is missing from ci.yml, so the required status check never gates the URLs EndUserTalkSchedule renders as hrefs

Closed Beginner friendly
#1,758 3 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
74/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
github-actions, javascript
Domain
ci-cd, security

Research direction

Read .github/workflows/ci.yml and scripts["validate:all"] in package.json, then compare their validator steps with ciValidators() in tests/netlify-publish-contract.test.mjs. Add the missing End User talks validator step and the reverse inclusion test described in the issue. Run npm run test:unit; done means the CI validator list matches validate:all and the tests pass.

Written by the indexing model from the issue text.

Description

agent/sec-check security stage/010-actionable

Security Finding

Severity: medium
Type: missing-gate (required status check does not run a URL validator)

scripts/validate-end-user-talks.mjs is the scheme/host gate for the three
fields src/components/EndUserTalkSchedule/index.js renders as <a href>:

  • index.js:25 — <a href={schedule.apiUrl} …>
  • index.js:30 — <a href={schedule.sourceUrl} …>
  • index.js:57 — <a href={talk.url} …>

That validator is in validate:all (package.json) but it is the only one of
the fourteen that is missing from the validate job in
.github/workflows/ci.yml
, which is the job behind the required status check
Validate repository.

Reproduced against b490a7f, comparing the npm run validate:* steps in
ci.yml's validate job with the targets chained in scripts["validate:all"]:

IN validate:all BUT NOT ci.yml:
  npm run validate:end-user-talks

The branch ruleset for main requires exactly two checks — Validate repository and Lint repository, both GitHub Actions. The Netlify deploy
check is not a required check. So a pull request that edits
data/end-user-talks.json passes every required check and merges, with the
validator that exists specifically to reject a javascript: scheme or an
off-host link never having run on the change.

Impact

data/end-user-talks.json is maintained through ordinary pull requests, which
is precisely the lane ci.yml gates. A change to it that sets talk.url,
sourceUrl or apiUrl to a javascript: URI, or to a host outside the
schedule host the validator pins, merges to main unchallenged.

Publication is still blocked — the Netlify build runs validate:all, so the
deploy fails and the previous deploy stays live — so this is not a live XSS on
the published site. The damage is that the gate moves from "rejected in review"
to "merged, then every deploy is frozen until someone reverts it": main
carries the bad data, and no site update can ship until it is removed.

The drift went unnoticed because the guard in
tests/netlify-publish-contract.test.mjs:80 asserts only one direction —
every validator ci.yml runs must also be in validate:all. A validator present
in validate:all but absent from ci.yml satisfies that assertion, which is
exactly the state the repository is in.

Recommendation

Two edits. They must land together, or the workflow edit first: the test edit
alone fails on main until the ci.yml step exists.

1. .github/workflows/ci.yml — add the missing step. Insert between the
existing Validate projects-born data and Validate button contrast steps, so
the job order keeps matching validate:all:

      - name: Validate projects-born data
        run: npm run validate:projects-born
      - name: Validate End User talks data
        run: npm run validate:end-user-talks
      - name: Validate button contrast
        run: npm run validate:button-contrast

2. tests/netlify-publish-contract.test.mjs — close the one-way guard so
the two sets cannot drift apart again in either direction. Add after the
existing validate:all runs everything the PR lane validates test:

test('the PR lane validates everything validate:all does', () => {
  const inCi = ciValidators();
  const inAll = new Set(
    npmRunTargets(scripts['validate:all'] ?? '').filter((target) =>
      target.startsWith('validate:'),
    ),
  );
  const missing = [...inAll].filter((target) => !inCi.has(target));
  assert.deepEqual(
    missing,
    [],
    'validators validate:all runs that ci.yml does not; the required status ' +
      'check is the only gate a human-authored data pull request passes, so ' +
      'a validator missing from it lets that data merge unvalidated',
  );
});

The existing test asserts ci.yml ⊆ validate:all; this one asserts
validate:all ⊆ ci.yml. Together they pin the two lists as equal.

Why no pull request accompanies this issue

Edit 1 is in .github/workflows/. This agent's token is minted at the
contributor tier, which does not carry the Workflows permission, so GitHub
rejects any push whose diff touches that directory. Edit 2 is pushable on its
own, but landing it alone would turn main red, because the assertion it adds
fails until edit 1 exists. Both edits are therefore left here as exact
replacement text; applying them needs a human maintainer or an agent with
workflow-write scope.

Completion criteria

  • .github/workflows/ci.yml runs npm run validate:end-user-talks in the validate job
  • tests/netlify-publish-contract.test.mjs asserts validate:all ⊆ ci.yml validators
  • npm run test:unit passes with both edits applied

Filed by sec-check agent (ACMM L4/L5 — hold-gated mode)


🐝 Hive Agent: security | Instance: hosted-available-lke648397-260827-5n31 | SHA: b490a7f

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

Dominant language
JavaScript
Stars
0
Forks
3
Avg merge
7h 15m
Merged PRs (30d)
623

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from cncf/endusers

All issues in cncf/endusers

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.