Skip to content

feat: harden CodeQL findings gate + fix cookie-suppression comment placement - #1218

Merged
Wikid82 merged 7 commits into
developmentfrom
fix/codeql-cookie-suppression-gate-hardening
Aug 4, 2026
Merged

feat: harden CodeQL findings gate + fix cookie-suppression comment placement#1218
Wikid82 merged 7 commits into
developmentfrom
fix/codeql-cookie-suppression-gate-hardening

Conversation

@Wikid82

@Wikid82 Wikid82 commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • The go/cookie-secure-not-set finding at auth_handler.go:191 (already tracked in docs/issues/codeql-cookie-suppression-not-honored.md) was surfacing as a live warning because its // codeql[go/cookie-secure-not-set] suppression comment was placed as a trailing same-line comment — CodeQL's suppression syntax requires a standalone comment exactly one line before the alert. Repositioned at this site plus 3 more with the identical bug (crowdsec_handler.go ×3, backup_handler.go ×1). Comment-only change, zero behavior change; the underlying cookie logic (secure=false only for local/private-network origins over plain HTTP) was independently re-verified sound.
  • Even correctly placed, a local CodeQL CLI/query-pack limitation still doesn't populate the native suppressions field for this call shape — disclosed transparently rather than assumed fixed.
  • Root process fix: CodeQL findings of any severity now fail the local/CI gate by default. Exceptions require an entry in a new, dated, justified, expiry-enforced .github/codeql/codeql-suppressions.yml — the same pattern this repo already uses for Trivy via .trivyignore. This closes the gap that let the cookie finding ride silently to main as a "non-blocking warning."
  • Consolidated two independently-drifting copies of the gate's blocking logic (local pre-commit script + CI workflow) into one shared, parity-checked scripts/security/codeql-findings-gate.sh.

Test plan

  • 8/8 bats tests pass (scripts/security/tests/codeql-findings-gate.bats), including a regression case proving warning-level findings now correctly fail, and a path-normalization case for local-vs-CI SARIF path conventions
  • Fresh lefthook run codeql (Go + JS): end-to-end pass, cookie finding shown as SUPPRESSED with dated justification (review by 2026-11-04); zero unsuppressed findings
  • Deliberate regression test: an unsuppressed test finding was reintroduced and the hardened gate correctly hard-failed it (NEW FINDING (no exception on file)) — proving this is a real behavior change, not just documentation
  • scripts/ci/check-codeql-parity.sh passes, including a new assertion that local and CI reference the same shared gate script
  • go build ./..., go test ./internal/api/handlers/... pass
  • lefthook run pre-commit (shellcheck, semgrep, etc.) clean

Wikid82 added 4 commits August 4, 2026 02:58
…and backup handlers

CodeQL's codeql[rule-id] inline suppression syntax requires a standalone
comment line positioned exactly one line before the flagged statement.
The go/cookie-secure-not-set comment in auth_handler.go was a same-line
trailing comment on c.SetCookie(, and four go/log-injection comments in
crowdsec_handler.go/backup_handler.go had their tagged line two lines
above the flagged statement instead of one. Reposition all five to
standalone lines at the correct offset; fold the auth_handler.go truth-
table justification into setSecureCookie's own doc comment so it no
longer cites the rotating docs/plans/current_spec.md plan file.

No behavior/logic change anywhere - comment placement only, verified by
the existing ~24-test auth_handler_test.go suite passing unmodified.

A fresh SARIF scan after the placement fix still shows no suppressions
key on the cookie finding (true for every result in the file, not just
this one) - a local CodeQL CLI/query-pack limitation for this call shape,
not a placement error. Registered as a dated, reviewable exception in
.github/codeql/codeql-suppressions.yml instead. Closes out
docs/issues/codeql-cookie-suppression-not-honored.md.

Claude-Session: https://claude.ai/code/session_01GAy1VnK6QW7U19vMmDFZgZ
…ented exceptions

Flip .github/security-severity-policy.yml's codeql.blocking_levels from
[error] to [error, warning, note] so every CodeQL finding blocks by
default, with a documented exceptions mechanism
(.github/codeql/codeql-suppressions.yml or a native in-source
suppression) as the only way out. Wire both
scripts/pre-commit-hooks/codeql-check-findings.sh and
.github/workflows/codeql.yml to call the shared
scripts/security/codeql-findings-gate.sh instead of their own
independently-duplicated inline jq, and add a parity assertion in
scripts/ci/check-codeql-parity.sh so local and CI can't drift back apart.

Also fixes a real bug found while verifying this end-to-end: local scans
(--source-root=backend/frontend) produce module-relative SARIF paths
while CI produces repo-root-relative paths matching the ignore-list's own
convention, so a valid, non-expired exception that correctly matched CI
never matched the identical finding locally. codeql-findings-gate.sh now
normalizes SARIF paths to the repo-root-relative form before matching or
printing, with a new bats fixture covering the exact scenario.

Claude-Session: https://claude.ai/code/session_01GAy1VnK6QW7U19vMmDFZgZ
@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-advanced-security

Copy link
Copy Markdown
Contributor

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

✅ Supply Chain Verification Results

PASSED

📦 SBOM Summary

  • Components: 1495

🔍 Vulnerability Scan

Severity Count
🔴 Critical 0
🟠 High 0
🟡 Medium 5
🟢 Low 2
Total 14

📎 Artifacts

  • SBOM (CycloneDX JSON) and Grype results available in workflow artifacts

Generated by Supply Chain Verification workflow • View Details

Wikid82 added 3 commits August 4, 2026 12:21
…ecs and fixtures

CodeQL's js/unused-local-variable and js/automatic-semicolon-insertion
queries flagged dead imports, unused destructured variables, and a
missing statement-terminating semicolon across the core/, integration/,
fixtures/, and utils/ E2E test files. Removes genuinely dead code and
fixes the ASI hazard with an explicit semicolon; a few spots (proxy
toggle state, SSL indicator check) got real assertions instead of being
silently unused.

Claude-Session: https://claude.ai/code/session_01GAy1VnK6QW7U19vMmDFZgZ
…E specs

Applies the same js/unused-local-variable cleanup to security-enforcement/
and security/ specs: dead auth/fixture imports, unused SELECTORS/mock
objects that were never referenced, and unused destructured resource IDs
from testData helper calls. A handful of spots got real assertions instead
of a silent unused read (WAF toggle state actually flips, accessible-name
checks are enforced, emergency-token status is verified unchanged).

Claude-Session: https://claude.ai/code/session_01GAy1VnK6QW7U19vMmDFZgZ
…sks E2E specs

Rounds out the js/unused-local-variable cleanup across settings/, tasks/,
and the remaining misc specs (modal-dropdown-triage, uptime-monitoring,
theme). Removes dead imports and unused destructured locals; a few spots
gained real assertions where the unused read was clearly meant to check
something (password-strength indicator, tab-order role check, WAF rule
toggle, dropdown z-index result, scroll-container sizing) rather than
just being deleted outright.

Claude-Session: https://claude.ai/code/session_01GAy1VnK6QW7U19vMmDFZgZ
@Wikid82
Wikid82 merged commit b20b9dd into development Aug 4, 2026
44 checks passed
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.

2 participants