fix(deps): SCA pass — Go 1.25.10 + go-git 5.19.0 + go-billy 5.9.0 + Caddy 2.11.3#261
Merged
Merged
Conversation
…rabilities) Closes 8 of the vulnerabilities the Scorecard `Vulnerabilities` check flagged (currently scoring 5/10). After this PR + Scorecard rescan, that check should jump close to ✅. ## Reachable vulnerabilities (govulncheck-confirmed) — fixed by Go 1.25.10 | Advisory | Module / path | Severity | |---|---|---| | GO-2026-4986 | `net/mail` consumeComment — quadratic concat | DoS | | GO-2026-4977 | `net/mail` consumePhrase — quadratic concat | DoS | | GO-2026-4982 | `html/template` meta-content URL escaping bypass | XSS | | GO-2026-4980 | `html/template` escaper bypass | XSS | | GO-2026-4971 | `net` Dial / LookupPort NUL-byte panic on Windows | DoS | | GO-2026-4918 | `net/http` HTTP/2 SETTINGS_MAX_FRAME_SIZE infinite loop | DoS | All reachable via call paths govulncheck traced — e.g., `pulumi.init` → `mail.ParseAddress`; `mcp.Start` → `http.Server.Serve` → `template.Execute`; multiple `http.Client.*` paths through gcp / cloudflare / mongo / aws code. Fix: bump `go` directive in go.mod from 1.25.9 to 1.25.10. Per HARDENING.md tracker convention (`feedback_sc_no_toolchain`): bump the `go` directive only, never add a `toolchain` line. ## Scorecard-reported (not reachable) — partly fixed | Advisory | Module | Status | |---|---|---| | GHSA-m3xc-h892-ggx6 | `go-git/go-billy/v5 < 5.9.0` | ✅ fixed (5.8.0 → 5.9.0) | | GHSA-qw64-3x98-g7q2 | `go-git/go-billy/v5 < 5.9.0` | ✅ fixed (same bump) | | GHSA-389r-gv7p-r3rp | `go-git/go-git/v6` alpha | ❌ FALSE POSITIVE — we use v5 (5.18.0) | | GO-2022-0635 | `aws-sdk-go/service/s3/s3crypto` | ❌ FALSE POSITIVE — we import aws-sdk-go v1 but NOT the s3crypto subpackage | | GO-2022-0646 | `aws-sdk-go/service/s3/s3crypto` | ❌ FALSE POSITIVE — same as above | govulncheck agrees on the three false positives (`Found 2 vulnerabilities in modules you require, but your code doesn't appear to call these`). Closing the false-positive flags in Scorecard requires either: (a) Migrating the 3 .go files using aws-sdk-go v1 (cloudtrail-related code in pkg/clouds/{pulumi/,}aws/) to aws-sdk-go-v2 — cleaner, separate PR. The v1 advisories have NO upstream fix; they're architectural (AWS deprecated s3crypto v1 in favor of v3). (b) Document via OpenVEX (Phase 2 deferred — Phase 4-and-after). ## go.sum churn `go mod tidy` also bumped two indirect deps (`cyphar/filepath-securejoin v0.4.1 → v0.6.1` and `golang.org/x/exp` to 2026-04-10). Standard upstream-dep refresh as a side effect of bumping go-billy. ## Validation - `go build ./...` — clean - `go vet ./...` — clean (no output) - `go test -short ./pkg/security/...` — all packages PASS (29 tests; bump didn't break the HMAC integrity cache work from PR #254) - `govulncheck ./...` — **0 reachable vulnerabilities** (was 6) Part of the [OpenSSF score climb plan](https://github.com/simple-container-com/api/blob/main/HARDENING.md) documented in HARDENING.md Phase 8. Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
Semgrep Scan ResultsRepository:
Scanned at 2026-05-16 16:47 UTC |
Security Scan ResultsRepository:
Scanned at 2026-05-16 16:47 UTC |
Comprehensive SCA pass on top of the Go 1.25.10 + go-billy 5.9.0 work in this PR's first commit. Identifies + fixes additional vulnerable deps that the first triage missed. ## go-git/v5 5.18.0 → 5.19.0 CVE-2026-45022 (HIGH) — go-git's improper parsing of specially crafted objects may lead to inconsistent interpretation compared to upstream Git. Trivy fs flagged this; my earlier triage missed it because Scorecard's flag pointed at the v6-alpha advisory and I incorrectly classified the v5 sibling as a false positive too. Same upstream advisory, separate v5 advisory: GHSA-389r-gv7p-r3rp (v6) and CVE-2026-45022 (v5). Fix is in 5.19.0. ## Caddy 2.11.2 → 2.11.3 (caddy.Dockerfile) Caddy 2.11.2 image scan revealed 18 CVEs (2 CRITICAL, 9 HIGH) all in the binary's vendored deps. Caddy 2.11.3 released after our Phase 1 lock; it bumps: - go-jose/v4 4.1.3 → 4.1.4 (CVE-2026-34986 HIGH) - otel + otel/sdk 1.42→1.43 (CVE-2026-29181, CVE-2026-39883 HIGH) - smallstep/certificates 0.30.0-rc3 → 0.30.0 (CVE-2026-30836 CRITICAL) - Plus Caddy core fixes: fastcgi non-PHP execution bug, admin-socket auth-bypass via array-index normalization + path-prefix matching. Source: https://github.com/caddyserver/caddy/releases/tag/v2.11.3 Updated all three sites (builder FROM + final FROM + xcaddy build arg) per the in-file note. New digests resolved via Docker Hub registry API on 2026-05-16. ## Net source-side state after this commit - trivy fs: 0 vulnerabilities (was 1 HIGH = CVE-2026-45022, now fixed) - govulncheck: 0 reachable; 2 unreachable in modules (the documented aws-sdk-go v1 s3crypto false positives) ## Image-side state (verify post-rebuild) Each prod image at v2026.5.14: kubectl 8 (5H/3M) — all upstream kubectl-binary stdlib@1.26.2; no SC action; track upstream rebuild caddy 18 (2C/9H/6M/1L) — should drop to ~6 after rebuild with Caddy 2.11.3 (this PR) github-actions 27 (17H/10M) — 7 fixed by Go 1.25.10 + go-git/go-billy bumps (this PR); remaining 20 are bundled pulumi/gcloud binaries @ 1.26.2 (upstream) cloud-helpers 17 (9H/8M) — glibc 2.34-231.amzn2023.0.4 NOW patched (Phase 1 deferred status closes); rebuild auto-picks via dnf upgrade. Plus stdlib fixed by Go 1.25.10. ## Dependabot reconciliation | PR | What | Verdict | |---|---|---| | #162 | go-git/v5 5.13.1 → 5.16.5 | SUPERSEDED — we're at 5.19.0 now | | #237 | pulumi-command/sdk 0.9.2 → 1.2.1 | LET STAND | | #242 | alpine 3.21 → 3.23 (docker-minor-and-patch group) | LET STAND — fixes Alpine OS-pkg CVEs in kubectl/github-actions images | | #243 | caddy digest bump (still 2.11.2) | SUPERSEDED — this PR bumps to 2.11.3 | | #244 | alpine/kubectl base digest bump | LET STAND | | #245-247 | mkdocs deps | LET STAND | | #248-251 | GitHub Actions bumps | LET STAND | | #252 | gomod-minor-and-patch group (26 deps) | PARTIAL SUPERSEDE — go-billy/go-git/go-jose/otel/grpc bumps from this PR. Dependabot will auto-rebase #252 on top with the remaining 22 non-security minor/patch bumps. | | #233 | reecetech/version-increment | LET STAND | ## Validation - `go build ./...` clean - `go vet ./...` clean - `go test -short ./pkg/security/...` — all 8 packages PASS - `govulncheck ./...` — 0 reachable - `trivy fs` — 0 findings (any severity) Refs HARDENING.md Phase 8 Scorecard climb plan. Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
…ry packs
Closes the SAST coverage gaps surfaced by the parallel-agent audit and
the codex+gemini review. Adds .semgrep/rules/ consumer-rules wired
through the existing simple-container-com/actions semgrep workflow, plus
registry-packs opt-in for community-maintained coverage.
## New rules under .semgrep/rules/
**sigstore.yml** (6 rules) — supply-chain core for Phase 2 attestation:
- gha-cosign-verify-without-identity-flag — `cosign verify*` missing
`--certificate-identity[-regexp]`
- gha-cosign-verify-without-oidc-issuer-flag — missing
`--certificate-oidc-issuer`
- gha-cosign-verify-insecure-flags — `--insecure-ignore-tlog` /
`--insecure-ignore-sct` (Rekor bypass)
- gha-gh-attestation-missing-scope — `gh attestation verify` without
`--repo` or `--owner`
- gha-attest-build-provenance-mutable-subject — `subject-name` with
`:latest` / `:staging` without `subject-digest`
- gha-oidc-id-token-on-untrusted-trigger — `id-token: write` reachable
from `pull_request_target` / `workflow_run`
**gha-extras.yml** (4 rules) — workflow-misuse patterns:
- gha-workflow-level-secret-env — `env: KEY: ${{ secrets.* }}` at file
scope (leaks to every step)
- gha-upload-artifact-secrets-leak — artifact path matches
`.env|.pem|.key|secrets/`
- gha-pull-request-target-implicit-base-ref — `pull_request_target`
checkout without explicit `ref:`
- gha-github-token-in-github-env — `GITHUB_TOKEN` written to
`$GITHUB_ENV` (cross-step persistence)
**pulumi-iac.yml** (5 rules) — IaC patterns beyond AWS-RDS:
- go-pulumi-k8s-privileged-workload — Privileged/HostNetwork/HostPID/
HostPath
- go-pulumi-gcp-storage-public-access — allUsers /
allAuthenticatedUsers / UniformBucketLevelAccess: false
- go-pulumi-gcp-compute-default-sa-cloud-platform — full-project SA
+ cloud-platform scope
- go-pulumi-aws-sg-open-ingress — 0.0.0.0/0 ingress
- go-pulumi-iam-wildcard-policy — `*:*` IAM grants
**go-canon.yml** (8 rules) — gosec / dgryski-semgrep-go misses CodeQL
security-extended doesn't cover:
- go-hmac-not-constant-time — `bytes.Equal` on MAC values
- go-cipher-deterministic-nonce — zero / constant nonce
- go-yaml-unmarshal-into-interface — typed-struct hygiene
- go-jwt-parse-unverified — skipping signature
- go-jwt-none-algorithm — `alg: none`
- go-http-client-no-timeout — missing `Timeout`
- go-tls-min-version-below-1-2 — TLS 1.0/1.1
- go-exec-command-inherits-environ-default — leaks parent env
## Workflow config (.github/workflows/semgrep.yml)
- consumer-rules: '.semgrep/rules'
- registry-packs: 'p/ci,p/secrets,p/golang,p/gosec'
Adds ~300 curated registry rules on top of SC's 30 custom rules + the
existing simple-container-com/actions shared bundle.
## FP triage rounds
| Round | Total | Fixes |
|---|---|---|
| 1 | 81 | initial draft — generic regex with single-line lookahead |
| 2 | 63 | extended lookahead window to span `\` continuations |
| 3 | 43 | excluded markdown + skipped comment lines |
| 4 | invalid | tried metavariable-pattern with negation-in-Or |
| 5 | 36 | switched to YAML structural matching with metavariable-pattern + pattern-not-regex |
Net findings after polish: 0 ERROR-level, 36 WARNING-level. The 36
WARNINGs are real instances of `yaml.Unmarshal into interface{}` and
`exec.Command` without explicit `Env` set — defense-in-depth tech debt
the team can address incrementally. Action's `fail-on-severity: ERROR`
default means they don't block CI.
## Follow-up — promote to shared ruleset
Once these rules survive ~14 days on this PR's CI without further
tuning, promote to simple-container-com/actions/semgrep-scan/rules/
in a separate PR. Drop the `consumer-rules:` line from this workflow
config at the same time.
Refs HARDENING.md Phase 8 score-climb plan (Scorecard SAST + Tier A → S).
Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
…ommand
Option A from the triage on round-5 results (36 WARNING findings, all
real instances but mostly intentional by design):
1. Dropped `go-yaml-unmarshal-into-interface` entirely (21 findings).
SC's untyped-unmarshal sites are intentional — generic YAML
inspection tooling (`obfuscateYAMLCredentials`, `configdiff/
resolver`, `validation/validator`, `chat/commands_project`'s AI
analysis path) needs `interface{}` because the result isn't a
security decision input. Taint-aware coverage for the cases that
DO matter (untrusted-source flow → unmarshal) lives in the
`p/golang` registry pack opted into via .github/workflows/
semgrep.yml. Note retained in go-canon.yml explaining the drop.
2. Tightened `go-exec-command-inherits-environ-default` with:
- File-level excludes for pkg/security/{sbom,scan,tools}/**
(intentional design surface for external-scanner invocation),
pkg/assistant/chat/input.go and pkg/assistant/cicd/utils.go +
pkg/assistant/analysis/git_analyzer.go (terminal-control + git
read-only invocations that need env propagation).
- Metavariable exclusion of trusted-CLI first-argument literals:
git, stty, gh, cosign, syft, trivy, grype, kubectl, docker,
pulumi, sc, welder. These all require env (PATH, HOME, GIT_*,
GH_TOKEN, TERM) to function correctly; flagging them produces
noise without signal.
Round-7 result: 0 findings across all 22 remaining custom rules. The
rules now catch REGRESSIONS (e.g., a new exec.Command invocation of
an untrusted binary without explicit Env) without drowning the signal
on intentional usage.
Refs HARDENING.md Phase 8 score-climb plan.
Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
smecsia
previously approved these changes
May 16, 2026
…t FPs The `p/secrets` pack flagged 26 ERROR-severity false positives in docs/ examples, testdata SSH keys, and example .sc/cfg files — all documented example values, not real secrets. TruffleHog already scans for secrets on this repo (security-scan.yml) and is tuned with the `secret-scan-extra-excludes` list for these exact paths. The shared semgrep-scan action does not expose a per-rule path-exclude knob, so suppressing FPs from a registry pack at the consumer side isn't possible. Net effect: - Custom rules (.semgrep/rules/, 23 rules) still scan as before — 0 findings on this branch. - `p/ci`, `p/golang`, `p/gosec` packs still run, covering CI hardening, Go-stdlib weak-crypto/insecure-deserialization, and gosec G-series. - Secret detection coverage unchanged — handled exclusively by TruffleHog, which has verifier-backed FP filtering. Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
The 22 custom Semgrep rules (sigstore, gha-extras, pulumi-iac, go-canon) that lived in .semgrep/rules/ have been promoted to the shared ruleset at simple-container-com/actions/semgrep-scan/rules/ via simple-container-com/actions#10. Once that lands on the actions repo's `main` branch, the rules are picked up here automatically via the `@main` ref on the reusable workflow — no `consumer-rules:` input needed. Short coverage gap until actions#10 merges: the registry packs (p/ci, p/golang, p/gosec) keep running; only the SC-specific rules pause. Re-enable on the actions side as soon as #10 is merged. Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
smecsia
approved these changes
May 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SCA pass — comprehensive deps + image scan
Goes beyond the initial Scorecard
Vulnerabilitiesfix to address every vulnerable dep found across source + 4 published images, all severities. Per thefeedback_all_severitiesrule.Two commits in this PR:
caddy.Dockerfile2.11.2 → 2.11.3Source-side (govulncheck + trivy fs)
trivy fsReachable Go stdlib (6, all fixed by Go 1.25.10)
net/mailconsumeComment — quadratic concatpulumi.init→mail.ParseAddressnet/mailconsumePhrase — quadratic concathtml/templatemeta-content URL escaping bypassmcp.Start→http.Server.Serve→template.Executehtml/templateescaper bypassnetDial / LookupPort NUL-byte panicnet/httpHTTP/2 SETTINGS_MAX_FRAME_SIZE infinite loopReachable Go-deps (3 fixed, 2 documented)
go-git/go-billy/v5 < 5.9.0go-git/go-billy/v5 < 5.9.0go-git/go-git/v5 < 5.19.0aws-sdk-go v1 service/s3/s3cryptos3crypto. govulncheck reachability confirms 0 hits. No upstream fix (architectural deprecation; AWS recommends migrating to v3 inaws-sdk-go-v2). Documented; standalone migration PR tracked.(GHSA-389r-gv7p-r3rp / CVE-2026-45022 — initial triage misread the GHSA as a v6-alpha flag; the Dependabot record makes clear it is the v5 advisory. Bumping to 5.19.0 closes it.)
Image-side (Trivy + Grype on the 4 v2026.5.14 published images)
kubectlbinary stdlib@1.26.2dnf upgradeauto-picks patched packages; Go 1.25.10 fixes the binaryPhase 1 deferred items — status check
Reviewed all four Phase 1 deferred items per HARDENING.md:
glibcCVE-2026-4046 (HIGH, AL2023 pending)dnf upgradeon next rebuilddocker/dockerCVE-2026-34040 / CVE-2026-33997go list -m -versions github.com/docker/docker— separate triage. Was migrated togithub.com/moby/mobyin PR #238; need to re-verify reachability.Dependabot security alerts addressed
Three OPEN Dependabot alerts as of this PR — all close automatically when this merges to
main:github.com/go-git/go-git/v5go.mod: 5.18.0 → 5.19.0github.com/go-git/go-billy/v5go.mod: 5.8.0 → 5.9.0github.com/go-git/go-billy/v5go.mod: 5.8.0 → 5.9.0What each one is:
weldergit-driver path.welderclone.osfs.ChrootOSdeprecated in v5, removed in v6 — upstream recommendation isosfs.New(path, WithBoundOS())). Reachable viawelderclone.(The 60 historical Dependabot alerts in
state: fixedwere closed by earlier PRs over 2025 — full audit available viagh api repos/simple-container-com/api/dependabot/alerts. No additional outstanding security alerts remain after this PR.)Dependabot PR reconciliation
Scorecard
VulnerabilitiesprojectionValidation
go build ./...cleango vet ./...clean (no output)go test -short ./pkg/security/...— all 8 packages PASS (29 tests; HMAC integrity cache from PR ci+security: Phase 4 repo controls + Phase 5 HMAC-authenticated cache #254 still green)govulncheck ./...— 0 reachable (was 6)trivy fs --severity CRITICAL,HIGH,MEDIUM,LOW— 0 findings (was 1 HIGH)trivy image simplecontainer/caddy:2026.5.14— flagged 18; expected ~6 after Caddy 2.11.3 rebuildtrivy image simplecontainer/cloud-helpers:aws-2026.5.14— flagged 17; expected ~0 after rebuild (AL2023 + Go 1.25.10)Follow-ups out of this PR's scope
.gofiles inpkg/clouds/{pulumi/,}aws/use v1 cloudtrail / cloudwatch / session APIs. The migration is a separate refactor PR; documented false-positives in govulncheck suffice for the security signal.docker/dockerreachability re-check — verify if PR ci(security): enable docker+pip Dependabot, migrate moby modules, pin actions, clear SAST findings #238's moby/moby migration cleared the original CVE.e9acf90to405e713#244 will pick it up.Refs HARDENING.md Phase 8 Scorecard climb plan; the SAST coverage audit produced today is a separate follow-up.