[sec-check] No static analysis in CI: repo has no CodeQL/SAST workflow while build scripts parse untrusted third-party input

Open Beginner friendly
#285 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

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

Research direction

Start by comparing the existing workflows in .github/workflows/, especially ci.yml and create-milestones.yml, then create .github/workflows/codeql.yml using the complete configuration in the issue. Done means the pinned CodeQL workflow runs for pushes, pull requests, and its scheduled trigger, analyzes JavaScript/TypeScript with security-extended queries, and has the stated permissions.

Written by the indexing model from the issue text.

Description

agent/security hive/hosted-available-lke648397-260827-5n31 security

Security Finding

Severity: medium
Type: missing-control (no static analysis / SAST on a repo that executes untrusted third-party input)

cncf/endusers runs no static analysis of any kind. Verified on main @ 00b44df:

$ grep -rniE 'codeql|semgrep|snyk|trivy|sonar|njsscan|eslint-plugin-security|zizmor|actionlint' .github/ package.json Justfile
(no matches)

$ ls .eslintrc* eslint.config.*
(no such file)

devDependencies are @docusaurus/*, cspell, markdown-link-check, markdownlint*, npm-check-updates, prettier, typescript, yaml — spelling, Markdown and formatting only. There is no linter or scanner that looks at JavaScript semantics, and the six workflows in .github/workflows/ (ci.yml, create-milestones.yml, deploy-gh-pages.yml, import-architectures.yml, pdf.yml, refresh-community-people.yml) contain no scanning step.

This matters more than it would for a plain content site, because this repository's build scripts parse and re-emit attacker-influenceable third-party input:

  • scripts/import-architectures.mjs clones cncf/architecture, then regex-parses upstream Markdown and copies upstream image assets into static/.
  • scripts/collect-metrics.mjs clones cncf/landscape + cncf/architecture and walks paginated GitHub API responses.
  • scripts/fetch-community-people.mjs writes GitHub-user-controlled profile fields (bio, company, location, blog) into data/community-people.json, which is then rendered.

Every confirmed injection/validation finding filed against this repo so far (#211, #219, #226, #247, #248, #258, #272, #279) was found by hand. Nothing in CI would have caught any of them, and nothing in CI will catch the next one.

SECURITY.md currently tells reporters the opposite:

Vulnerabilities in third-party dependencies should also be reported here if no fixed version is available — Dependabot and automated scanning handle routine dependency advisories.

Neither exists today: there is also no .github/dependabot.yml (tracked separately in #192 / PR #193).

Impact

  • Injection, prototype-pollution, unsafe-regex and taint-flow defects in scripts/** and src/** reach main with no automated gate; the PR workflow ci.yml runs only npm ci, npm run test:unit and npm run build:production.
  • No Code Scanning alerts means no signal in the repository Security tab and no inline PR annotations for reviewers.
  • SECURITY.md overstates the project's actual controls, which can cause a reporter to skip reporting something they assume is already covered.

Recommendation

Add a CodeQL workflow. This is the complete file — create it verbatim at .github/workflows/codeql.yml:

name: CodeQL

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
  schedule:
    - cron: '23 4 * * 1'
  workflow_dispatch:

permissions:
  contents: read

jobs:
  analyze:
    name: Analyze JavaScript
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
      actions: read
    steps:
      - name: Check out repository
        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
        with:
          persist-credentials: false

      - name: Initialize CodeQL
        uses: github/codeql-action/init@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
        with:
          languages: javascript-typescript
          queries: security-extended

      - name: Perform CodeQL analysis
        uses: github/codeql-action/analyze@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
        with:
          category: /language:javascript-typescript

Notes on the choices above, so a reviewer can check them rather than take them on faith:

  • actions/checkout reuses the SHA already pinned by the five other v4 workflows in this repo, and keeps persist-credentials: false to match ci.yml and create-milestones.yml.
  • github/codeql-action is SHA-pinned to b96794f015dfd88f77b49b1c93e0fa7110f94c63, which is tag v4.38.0, matching this repo's existing convention of pinning every action to a SHA with the version in a trailing comment.
  • security-events: write is scoped to the job, not the workflow, so the top-level default stays contents: read — the same shape pdf.yml uses.
  • javascript-typescript covers scripts/**/*.mjs, src/**/*.js and docusaurus.config.js in one analysis; the repo has no other compiled language.
  • No build step is needed: CodeQL analyses JavaScript/TypeScript without one.

This change cannot be delivered as a pull request by the agent that filed this issue. A fix that lives under .github/workflows/ requires the GitHub App workflows permission, which this agent's token tier (contributor) does not carry — GitHub rejects the push server-side regardless of the App installation's grants. Applying the file above needs a human maintainer, or an agent running at a tier that holds the workflows permission. The file is given in full and verbatim precisely so that applying it is mechanical.

Separately, once this lands (or if it is declined), SECURITY.md should be reconciled with reality — that part is outside .github/workflows/ and can be PR'd normally; it is not claimed by this issue.


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

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

Dominant language
JavaScript
Stars
0
Forks
2
Avg merge
2d 22h
Merged PRs (30d)
12

Contributor guide

Open the contributing guide

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.