Skip to content

chore(agent): //agent:security:image red on 14 fixable HIGH/CRITICAL — bundled gh/uv/npm binaries, hidden behind the masking short-circuit #897

Description

@scottschreckengaust

Summary

mise run security — the task the pre-push hook runs (hooks:pre-push:security) — has a
failing leg that nobody has seen, because the aggregate stops at the first failure and
security:sast:masking (4th of 8) fails first. Running the legs individually exposes it:

MISE_EXPERIMENTAL=1 mise //agent:securityrc=1, at its security:image step. bandit
passes ("No issues identified"). Trivy reports 14 HIGH/CRITICAL fixable vulnerabilities, none
of them in this repo's own source, and none in the Debian base (debian 13.7 → 0 findings).

Measured 2026-09-15 on fix/879-insecure-object-assign @ a382fca2 (a merge of main
25330c72), mise 2026.9.9, trivy 0.70.0. That branch's diff vs main is two files, both under
cdk/zero files under agent/ or any Dockerfile — so the image inputs are byte-identical
to main and this is a main-state finding, not a PR regression.

Scanner invocation (from agent/mise.toml):

docker build --build-arg TARGETPLATFORM=linux/arm64 -f Dockerfile -t bgagent-local:latest ..
trivy image --scanners vuln --ignore-unfixed --ignorefile .trivyignore --severity HIGH,CRITICAL --exit-code 1 bgagent-local:latest

Findings, grouped by what actually ships them

# Target Type Provenance
9 usr/local/bin/gh gobinary agent/Dockerfile:2 ARG GH_VERSION=2.93.0, built from source in the gh-builder stage (line 27)
1 usr/local/bin/uv rustbinary agent/Dockerfile:99 COPY --from=ghcr.io/astral-sh/uv:0.11.14@sha256:1025398…
4 usr/lib/node_modules/npm/** node-pkg agent/Dockerfile:89 npm install -g npm@latest — npm's own bundled deps

gh 2.93.0 — vendored Go modules (9)

Library Advisory Installed Fixed
github.com/sigstore/rekor CVE-2026-48702 v1.5.0 1.5.2
golang.org/x/crypto CVE-2026-56854 v0.52.0 0.55.0
golang.org/x/mod CVE-2026-56864, CVE-2026-56865 v0.36.0 0.40.0
golang.org/x/net CVE-2026-46600 v0.55.0 0.56.0
golang.org/x/text CVE-2026-56852 v0.37.0 0.39.0
google.golang.org/grpc CVE-2026-84304, CVE-2026-84445, GHSA-hrxh-6v49-42gf v1.81.1 1.83.1 / 1.82.2 / 1.82.1

uv 0.11.14 (1)

Library Advisory Installed Fixed
quinn-proto GHSA-4w2j-m93h-cj5j (remote memory exhaustion, unbounded out-of-order stream reassembly) 0.11.14 0.11.15

npm's bundled dependencies (4)

Package Advisory Installed Fixed
brace-expansion CVE-2026-14257, CVE-2026-69152 5.0.7 5.0.8 / 5.0.9
ip-address CVE-2026-69192 10.2.0 10.3.1
tar CVE-2026-73566 7.5.19 7.5.21

Why this has stayed invisible

Three independent reasons, which is why it needs its own issue rather than a note on an existing one:

  1. Aggregate short-circuit. mise run security runs security:secretsdepssast
    sast:maskinggryperetiregh-actions//agent:security. Whole-repo
    sast:masking is red on main (6 pre-existing findings, chore(security): clean up 21 pre-existing silent-success-masking findings on main #756/25 pre-existing masking findings on main fail the pre-push gate, forcing --no-verify for every contributor #766), so execution never reaches
    the last leg. The practical consequence: "fix the masking findings and pre-push goes green" is
    false
    — the next wall is this one.
  2. CI never runs it on a PR. Per feat(ci): scan container image + SAST on PRs — weekly-only cadence let a HIGH CVE sit on main for 6 days #235, build.yml sets
    MISE_DISABLE_TOOLS: "aqua:aquasecurity/trivy,grype,semgrep", and image scanning happens only in
    the weekly security.yml cron. So PR checks are 8/8 green with these 14 live.
  3. --ignore-unfixed means every one of these has a published fix. They are not
    wait-for-upstream noise.

Proposed remedies

Per target, because they are three different kinds of problem:

  • gh — bump ARG GH_VERSION past 2.93.0 to a release whose go.mod carries the fixed
    golang.org/x/*, grpc, and rekor versions, and confirm by re-scanning rather than by
    changelog. Because the binary is compiled from source in-image (go install …@vX), the vendored
    set is whatever that tag pins — a version bump is the only lever; there is no separate dep file
    to patch.
  • uv — bump the pinned digest to ≥ 0.11.15 (ghcr.io/astral-sh/uv:0.11.15@sha256:…).
    Smallest, most mechanical fix of the three.
  • npm's bundled depsnpm@latest already ships them, so there is nothing to bump. The repo
    already has a precedent for exactly this at agent/Dockerfile:92
    (npm --prefix "${CLAUDE_NPM_ROOT}" update tar minimatch glob cross-spawn picomatch for the
    claude-code tree). Extending that treatment to npm's own node_modules, or dropping targeted
    .trivyignore entries with an expiry and a linked upstream issue (the lifecycle feat(agent): CVE suppression lifecycle — scheduled re-scan of .grype.yaml ignores #131 asks
    for), are the two honest options.

Acceptance criteria

  • MISE_EXPERIMENTAL=1 mise //agent:security exits 0 on main.
  • Any residual suppression lives in .trivyignore with a justification, an upstream link, and
    an expiry date — not a blanket severity downgrade.
  • A regression note records that mise run security's short-circuit hides later legs, so future
    "the security gate passes" claims are made leg-by-leg.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

approvedWhen an issue has been approved and readybugSomething isn't workingsecurityCedar/HITL, IAM least-privilege, secrets, PII/DLP, guardrails, supply-chain/CVEv1Version 1

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions