Skip to content

Resolve the first CodeQL default-setup alerts (href allowlist, HTML tokenizer, exact hostname) - #104

Merged
seathatflowsinourveins merged 4 commits into
mainfrom
claude/codeql-alert-fixes
Sep 23, 2026
Merged

seathatflowsinourveins merged 4 commits into
mainfrom
claude/codeql-alert-fixes

Conversation

@seathatflowsinourveins

Copy link
Copy Markdown
Owner

Resolves the 10 alerts from the repository's first CodeQL default-setup analysis (run 35815088202, commit 168a3a8), so a code_scanning ruleset rule (security high_or_higher, alerts errors) can be enabled without blocking work.

Changes

Evidence (local_integration)

  • python -m unittest discover: 2496 tests, 0 failures.
  • build_ecosystem.py --check, validate.py, validate_catalogs.py and evidence_manifest.py --check all pass.
  • Guarded gitleaks: no leaks.
  • The hosted CodeQL re-analysis on this PR is the close-out signal for the fixed alerts.
  • Independent review: two Opus evidence-review rounds; the remaining finding (re.I insufficient) is resolved by the parser change.

🤖 Generated with Claude Code

…tive tag scan, exact hostname check

Resolves the 5 real defects from the repository's first CodeQL default-setup
analysis (commit 168a3a8, alerts 1/3/4/5/8), re-located at base 796f759 since
PR #96 changed the generated explorer between the two:

- js/xss-through-dom (docs/ecosystem/template.html:145): link() now builds
  href through a safeHref() helper that only allows http:/https: URLs,
  blocking a javascript:-URI href from catalog data.
- py/bad-tag-filter (scripts/build_ecosystem.py:704,
  tests/test_ecosystem_manifest.py:231, tests/test_claude_repository_evidence.py:147):
  add re.IGNORECASE so an injected uppercase <SCRIPT> tag is still counted
  into the page's inline-script CSP hash instead of silently bypassing the
  single-script precondition.
- py/incomplete-url-substring-sanitization (tests/test_lifecycle_capture.py:103):
  replace the "sec.gov" in url substring check with an exact
  urlparse(url).hostname comparison.

The remaining 5 alerts (2, 6, 7, 9, 10) are false positives / test-only
synthetic-secret fixtures; their justification is recorded for the
coordinator to apply via the GitHub API in
docs/decisions/2026-09-22-codeql-first-analysis.md and the sibling
codeql-dismissals.json, not dismissed here.

manifests/evidence.json's sha256/bytes entries for the five touched files
are refreshed so scripts/validate.py (run by validate.yml) still passes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…review fixes)

Resolves the independent reviewer's three medium findings on 65f73e2:
alerts #7 and #9's location descriptions and dismissal comments pointed at
the wrong code after the 796f759 re-location (both now cite the actual
CodeQL sink); alert #1's "node -e smoke check" claim named no runnable
command, so it is replaced with an executed unittest that runs the
committed safeHref helper (extracted verbatim from template.html) under
Node and asserts javascript:/data:/vbscript:/file:/mailto: are rejected
while http(s) and relative URLs pass through, and alert #1 is relabeled
defense-in-depth given build_ecosystem.py's public_url() is the primary
control. Refreshes manifests/evidence.json for the two touched files so
validate.py stays green. Re-running the full suite three times confirms
the reviewer's flagged skip-count (338) is deterministic, not a flake.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ad-tag-filter)

re.I alone would likely leave py/bad-tag-filter open (it also flags missed
end-tag variants such as </script >). The build script and both tests now use
html.parser, which tokenizes like a browser; on the real generated pages the
parsers return the identical single body the regexes returned. Corrects the
record's alert #1 control description (loopback_url also admits http loopback
links) and the skip-count claim.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Review follow-up: a self-closing <script/> or a script after <!--> (Python 3.12)
was invisible to InlineScripts. render_from_data now requires no self-closing
script and requires the parser's script-start count to equal the raw
"<script" count; the CSP test asserts the same count. The record's loopback_url
and browser-equivalence wording is corrected.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@seathatflowsinourveins
seathatflowsinourveins merged commit 7dc8317 into main Sep 23, 2026
11 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the claude/codeql-alert-fixes branch September 23, 2026 04:42
seathatflowsinourveins added a commit that referenced this pull request Sep 23, 2026
…immutable releases, target ruleset (#108)

* Close the catalog's GitHub automation: OSV/zizmor-online scans, gates, immutable releases, target ruleset

Add security-scan.yml: an osv-scanner job (OSV-Scanner 2.6.0, checksum-verified)
over every tracked lockfile in .github/osv-scanner-lockfiles.json with
--no-resolve, failing on unignored vulnerabilities and uploading SARIF off PRs,
plus a zizmor-online SARIF job. A unittest fails when a tracked lockfile is
missing from the inventory or an ignore lacks a <=90-day expiry.

Gate dependency review at high (warn-only removed) and grype at --fail-on high
with a reviewed, empty .grype.yaml; upload Scorecard SARIF with a job-scoped
security-events write; add a 7-day Dependabot cooldown. publish-catalog.yml
gains a tag-only release job (contents: write only) that re-checks the attested
digests and creates the immutable release with both files attached at creation.

.github/main-ruleset.json becomes the target (dependency-review and osv-scanner
required, strict checks, signatures, CodeQL code_scanning, squash only); the
tag rulesets match live 23829417 and 23859358. Record the evidence, the
CodeQL-vs-zizmor comparison on 168a3a8 and the superseded decisions in
docs/decisions/2026-09-22-github-automation-closure.md; update SECURITY.md,
automation.json, the docs, the regenerated verdicts/explorer and evidence hashes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Drop required_signatures from the target ruleset; gate .grype.yaml changes; fix stale gate docs

A measured agent-lab run (2026-09-23) blocked PRs with unsigned branch
commits under required_signatures even though GitHub signs the squash merge,
so the target main ruleset leaves the rule out as keep-but-compare until every
writer signs. supply-chain.yml now runs its grype gate when .grype.yaml
changes, with a test. Scorecard, dependency-review and grype docs no longer
call the new gates report-only, and the CodeQL default-setup row cites the
re-read settings GET.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Resolve the catalog-automation review findings after rebasing on main

- Rebase onto origin/main 8faca90 (#96, #99-#104, #106): take main's removal of
  docs/ecosystem/index.html, merge main's explorer build/attest/upload steps
  with the release job's digest outputs, and re-register manifest hashes
  with host_receipts.register_file.
- OSV inventory: add a reasoned "excluded" list for the #101 grype
  positive-control fixture; the coverage test accepts only listed,
  fixture-scoped exclusions with an evidence path and still fails on any
  unlisted tracked lockfile. osv-scanner 2.6.0 exits 0 on the 37 listed files.
- Target main ruleset: strict_required_status_checks_policy false (auto-merge
  without a merge queue would stall every open PR when main moves);
  required_signatures stays out; regression tests assert both.
- automation.json: gating lanes move to security_gate_lanes with boolean
  required_check/target_required_check; fresh CodeQL default-setup GET cited.
- foundation.json: restore ci-supply-chain lane gap text, replace stale
  automation.json line citations with JSON-path anchors at 92bb279;
  regenerate verdicts and the handbook section with build_verdicts.
- Handbook automation summary and closure record updated (mlx branch dropped
  after #99, fixture alerts 7-15 dismissed and #105 closed, security updates
  kept on, strict decision, gap-ledger mapping).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Align merge-queue and osv-scanner catalog text with the strict-off target; record #104 CodeQL triage

- automation.json merge-queue non-adoption no longer cites strict checks;
  it points at the strict-off decision (closure record section 10) with its
  overturn condition.
- osv-scanner selection says "required in the target ruleset once applied"
  and names the 37 listed lockfiles, 2 covered manifests and 1 fixture
  exclusion.
- Closure record section 2: the 10 first-analysis CodeQL alerts were
  resolved in #104, not left for owners.
- Hashes re-registered in manifests/evidence.json.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Keep Dependabot security PRs off the grype positive-control fixture

ignore: urllib3 on a pip entry scoped to the fixture directory (ignore applies to
security updates; exclude-paths does not). Clarify that osv-scanner becomes a
required check only after the target ruleset is applied.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Refresh evidence hashes after rebasing onto #95

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Fix the OSV SARIF path under bash -e; keep the zizmor write token away from the analyzer

shell: bash implies -e, so a findings exit ended the OSV step before the SARIF run
(reproduced; found by an independent-implementation comparison and the Codex
cross-family review). zizmor now runs read-only and a tool-free upload job holds
security-events: write. Tests cover both, plus OSV PackageOverrides and grype
review-by dates.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: seathatflowsinourveins <234074349+seathatflowsinourveins@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.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

Development

Successfully merging this pull request may close these issues.

1 participant