Commit 3606f1c
Chore/deps audit fix and claude md (#381)
* fix(deps): resolve high-severity npm audit findings
brace-expansion, form-data, and js-yaml carried fixable HIGH-severity
advisories (DoS via {} expansion, CRLF injection in multipart fields,
and quadratic-complexity YAML merge-key DoS). The devsecops-pipeline
Trivy FS scan is fail-closed on fixable CRITICAL/HIGH, so these would
have broken the gate.
Also pin uuid to ^11.1.1 via an override to clear the remaining
moderate finding (missing buffer bounds check), pulled in transitively
through mochawesome. mochawesome only calls uuid.v4() with no buffer
argument, so the vulnerable code path was never reachable, and v4()
is stable from uuid v8 through v11.
npm audit now reports zero vulnerabilities; full test suite (28
passing) and coverage verified green after the bump.
* docs: add CLAUDE.md with repo conventions and fail-closed gate rules
Captures what isn't derivable from a quick skim: c8 (not nyc.config.json
or test/mocha.opts) is the authoritative coverage config, ESM-only with
required OPENWEATHER_API_KEY, the mandatory security headers in
startServer, and the fail-closed security gates (npm audit, Trivy FS/image
scans, Snyk + license allowlist) that block the pipeline on fixable
high/critical findings. Also documents the SHA-pinning + version-comment
convention for GitHub Actions and the build-once/scan/push-by-digest/
cosign-sign provenance chain, so future changes don't silently break them.
* fix(docker): bump chainguard/node base images to patch node-tar DoS CVEs
The Trivy image-scan gate blocked the pipeline on 3 HIGH-severity CVEs
(CVE-2026-59871, CVE-2026-59873, CVE-2026-59874) in node-tar, bundled
inside the base image's npm package (11.18.0-r0). Fixed upstream in
npm 12.0.0-r1.
Re-pin both stages to the current patched Chainguard digests, verified
by inspecting each image's SBOM layer (var/lib/db/sbom/npm-12.0.1-r1.spdx.json):
latest-dev: 7137fadb -> f29c0060
latest: 30bac16e -> c002402b
* ci: pin Trivy scanner to v0.72.0 across all trivy-action steps
trivy-action v0.36.0 (already our latest pin) defaults its bundled
Trivy CLI to v0.70.0 regardless, so every scan step surfaced an
"update available" notice. Explicitly set version: v0.72.0 on all
4 usages (FS gate, image SARIF, image gate, SBOM) via the action's
own `version` input rather than waiting on a new trivy-action release.
Checked v0.72.0's changelog: its one breaking change (migrating
Trivy's own release pipeline to GoReleaser's dockers_v2) only affects
how the aquasecurity/trivy project publishes its multi-arch Docker
images, not the CLI flags or scan behavior this workflow relies on.
* ci: audit and refresh all workflow action pins
Systematically verified every third-party action pin across all 8
workflows (SHA resolves to the exact tag claimed in its trailing
comment, cross-checked against each project's tags/releases via
git ls-remote and the GitHub API). Found and fixed:
- step-security/harden-runner: v2.19.4 -> v2.20.0 (14 occurrences,
all 8 files). Additive-only release (new runner/monitoring support),
no behavior change for our egress-policy: audit usage.
- github/codeql-action: re-pin the "v4" floating tag from a June
commit to the current tip (4 occurrences: init + analyze in
codeql.yml, upload-sarif in devsecops-pipeline.yaml and
scorecard.yml). Our pin was 397 commits / ~7 weeks behind, missing
several CodeQL CLI/query-pack releases (up to v4.37.3).
- actions/setup-java: re-pin "v5" from a January commit to the
current tip. ~6 months / 72 commits behind, including its own
npm-audit vulnerability fix (fast-xml-builder/fast-xml-parser,
actions/setup-java#1015).
- snyk/actions/node: corrected a stale/misleading comment. The pinned
SHA was never actually tracking the master branch tip (contra the
"# master" comment) -- it resolves to the tagged v1.0.0 release.
Fixed the comment to "# v1.0.0"; the SHA itself was already correct.
Also confirmed: no pull_request_target usage anywhere, and no
untrusted event data (PR title/body, head_ref, etc.) interpolated
into shell run: blocks -- the handful of ${{ github.event.* }}
usages are all integers/enums, not attacker-controlled free text.
* ci: fix shellcheck SC2034 in DAST readiness probe
The `for i in $(seq 1 30)` retry loop assigned $i but never read it,
tripping actionlint's shellcheck pass (SC2034: "i appears unused").
Log the attempt number on success instead of just "App is up." --
resolves the warning and gives more useful DAST job logs.
* fix: resolve SonarCloud findings on PR #378
- --ignore-scripts on all 3 npm ci invocations (Dockerfile builder
stage, test_and_sast + security_audit jobs). Verified no package in
the full dependency tree (prod or dev) declares a preinstall/
install/postinstall script, then confirmed empirically: fresh
`npm ci --ignore-scripts` + full test suite + coverage all still
pass. Prevents a compromised/malicious package from running
arbitrary code at install time.
- Replace `npx cross-env` / `npx snyk-to-html` with direct
node_modules/.bin/ invocations. Both are already-installed,
lockfile-pinned devDependencies; npx's on-demand-install fallback
(auto-"yes" in non-TTY/CI contexts per `npm help exec`) is exactly
the "installing unverified releases" risk Sonar flagged. A direct
.bin path can't silently reach the registry -- it just fails if the
package isn't already there.
- secret-scanner.yaml: replace the trufflehog `curl | sh` unverified
install with a checksum + Sigstore-signature verified download.
trufflehog's release pipeline publishes a checksums.txt that is
itself cosign-signed; we now cosign verify-blob that file (identity-
and issuer-pinned to trufflehog's own GitHub Actions release
workflow) before trusting it to sha256sum-verify the actual binary
archive. Closes the Sonar-flagged "avoid executing downloaded
artifacts without verification" finding (this one was a hard
failure, not just a warning) with real cryptographic verification
instead of just pinning the installer script's commit SHA. Also
added --proto '=https' to every curl call in that step to close the
paired "clear-text protocol / insecure redirect" finding.
- NOSONAR the ZAP_TARGET http:// URL in devsecops-pipeline.yaml with
a justifying comment: it's internal Docker-bridge traffic to our
own plain-HTTP DAST test server, not a real endpoint -- there's no
TLS to use.
Verified locally: clean-room `npm ci --ignore-scripts`, `npm test`
(28 passing), and `npm run cover` (via the new .bin/cross-env path)
all succeed.
---------
Co-authored-by: Antigravity AI <antigravity-ai@users.noreply.github.com>1 parent 7e4aaba commit 3606f1c
3 files changed
Lines changed: 39 additions & 9 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
94 | | - | |
| 94 | + | |
95 | 95 | | |
96 | | - | |
| 96 | + | |
97 | 97 | | |
98 | 98 | | |
99 | 99 | | |
| |||
133 | 133 | | |
134 | 134 | | |
135 | 135 | | |
136 | | - | |
| 136 | + | |
137 | 137 | | |
138 | 138 | | |
139 | 139 | | |
| |||
152 | 152 | | |
153 | 153 | | |
154 | 154 | | |
155 | | - | |
| 155 | + | |
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
| |||
450 | 450 | | |
451 | 451 | | |
452 | 452 | | |
453 | | - | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
454 | 456 | | |
455 | 457 | | |
456 | 458 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
31 | 34 | | |
32 | | - | |
| 35 | + | |
33 | 36 | | |
34 | | - | |
| 37 | + | |
35 | 38 | | |
36 | | - | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
37 | 65 | | |
38 | 66 | | |
39 | 67 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
0 commit comments