Skip to content

fix(OMN-16355): clear the 3 blocking lockfile CVEs (click, kafka-python) reddening every infra PR - #2834

Merged
github-actions[bot] merged 3 commits into
devfrom
jonah/omn-16355-lockfile-cve-click-kafka
Aug 21, 2026
Merged

github-actions[bot] merged 3 commits into
devfrom
jonah/omn-16355-lockfile-cve-click-kafka

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Aug 21, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes OMN-16355
Refs OMN-16228 (the gate that surfaced this), OMN-16170 (sqlparse/Trivy lineage), OMN-16351 / #2833

Why

Lockfile CVE Scan (OMN-16228) went required and is RED on every open infra PR. It is a fleet-wide merge blocker. The scanner is correct — the lockfile is genuinely vulnerable. This is the one root fix for the fleet.

The three blocking findings

Reproduced locally with osv-scanner v2.5.1 — the exact pinned binary ci.yml downloads — piped into scripts/ci/check_lockfile_cve.py evaluate:

package locked advisory gate severity fixed in
click 8.3.1 PYSEC-2026-2132 / CVE-2026-7246 / GHSA-47fr-3ffg-hgmw HIGH (gate-computed CVSS 7.2) 8.3.3
kafka-python 2.3.0 PYSEC-2026-2190 / CVE-2026-10142 UNKNOWN + fix-available → BLOCK 2.3.2
kafka-python 2.3.0 PYSEC-2026-2191 / CVE-2026-10143 UNKNOWN + fix-available → BLOCK 2.3.2
  • click — command injection in click.edit(): the editor command was handed to subprocess with shell=True. 8.3.3 splits pager/editor commands with shlex.split() into an argv list and drops shell=True. Verified in the installed 8.4.2: shell=True is gone from the editor path.
  • kafka-python ×2 — DoS. (10142) a 4-byte protocol frame length used without bounds validation → multi-GB allocation or an uncaught ValueError that leaves the connection wedged. (10143) a broker-supplied SCRAM iteration count passed straight to hashlib.pbkdf2_hmac() → frozen client event loop, consumer-group eviction. Both are malicious- or MITM-broker vectors, i.e. precisely the deploy-agent control-bus surface. 2.3.2 carries exactly those two fixes (upstream chore(OMN-16180): bound work_events.summary in schema and scrub the LAN literal from 0001 #3019 frame-size validation, docs(OMN-17143): reserve collaborator lane for Lakshman on .201 #3026 SCRAM iteration validation).

On the UNKNOWN classification — deliberately left alone

The two kafka-python advisories classify as UNKNOWN rather than HIGH because they ship only a CVSS_V4 vector and _classify_severity parses CVSS_V3* only. They still block, via the gate's intended fail-closed UNKNOWN + fix-available → BLOCK rule. No scanner change here on purpose: teaching the classifier CVSS v4 would reclassify these two as HIGH (still blocking, no gain) while any partial/incorrect attempt risks turning them report-only — a fail-open on the exact gate this PR exists to satisfy. Worth its own ticket, not a rider on the unblock.

What changed

click 8.3.1 → 8.4.2, kafka-python 2.3.0 → 2.3.2. The uv.lock diff moves exactly those two packages (plus this repo's own version line).

kafka-python ceiling tightened <4.0.0 → <3.0.0, deliberately. 3.0.0 is a breaking major: producer defaults flip to enable_idempotence=True/acks='all', consumer session_timeout_ms 10s→45s, api_version_auto_timeout_ms renamed to bootstrap_timeout_ms, Serializer/Partitioner signatures changed, KafkaError no longer subclasses RuntimeError, NoBrokersAvailableError removed, kafka.sasl → kafka.net.sasl, kafka.client_async/kafka.conn deleted. Our kafka-python surface is scripts/deploy-agent/ (KafkaProducer/KafkaConsumer on the live deploy control bus) plus tests/integration/test_dispatch_roundtrip.py; the runtime itself is on aiokafka, untouched here. Verified against installed 2.3.2 that every kwarg the deploy-agent passes still exists, poll(timeout_ms=) is intact, and producer defaults are unchanged (enable_idempotence=False, acks=1) — exactly the semantics 3.0 would have flipped underneath a live control bus. A 3.x migration is its own change with its own proof; the ceiling lifts when that lands.

click took no ceiling change. No ParamType/Parameter subclassing anywhere in this repo, so 8.4.0's typing rework does not reach us — confirmed by mypy --strict clean over 2813 files and 496 passing CLI tests.

The 0.38.8 bump is folded in, and why it has to be

The local check-release-identity hook is pass_filenames: false with no --base, so it always enforces version-ahead — it fails on unmodified origin/dev today, and this diff touches pyproject.toml, so it fires here. The dedicated bump PR (#2833, OMN-16351) cannot land first: it is itself blocked by this very Lockfile CVE Scan. Folding the bump in breaks the cycle. #2833 becomes redundant once this lands.

Note CI's own release-identity check (fresh-deploy-fitness, which passes --base origin/$BASE) was already exempt for this diff — OK: no packaged src/** change in this diff. The bump is here to satisfy the stricter local hook without bypassing it.

dod_evidence

Gate, before → after (osv-scanner v2.5.1 scan --lockfile=uv.lock --format=json → check_lockfile_cve evaluate):

  • before (origin/dev lock): BLOCKING: 3 HIGH/CRITICAL finding(s) — exit 1
  • after (this lock): zero blocking findings — exit 0

Remaining 4 findings are report-only and correctly non-blocking: h2 4.3.0 ×2 (MEDIUM), pygments 2.19.2 ×2 (LOW).

Tests

  • 496 passed across the click/CLI surface (tests/unit/cli, catalog/registry/fingerprint/verification/gateway-auth CLI tests)
  • 198 passed deploy-agent unit tests (the real kafka-python KafkaProducer/KafkaConsumer consumers)
  • 55 passed version-compatibility + check_lockfile_cve own unit tests; update_version_matrix.py --check clean
  • mypy --strict: Success: no issues found in 2813 source files; ruff check: All checks passed!
  • Governed pre-push selector escalated and ran 23575 passed, 40 skipped (11m04s) — impacted tests passed; allowing push. No PREPUSH_FULL_SUITE, no ENABLE_SMART_TESTS=off, no bypass.

Kafka integration, causation controlled. pytest -m kafka -n 0 on this branch: 13F/67P. Same command on a detached origin/dev baseline worktree (kafka-python 2.3.0, click 8.3.1): 14F/66P. The failure sets are identical minus one — this branch fails one fewer test. Every failure is a pre-existing .201 dev-lane-not-running environment failure (111 subscribe topic(s) have no active consumer group, Topic ... not found in cluster metadata), all on aiokafka paths untouched by this change. Nothing here regresses; no test passes on dev and fails on this branch.

Pre-commit clean on the real changed-file scope (--files pyproject.toml uv.lock) and clean through the commit hook chain. The two --all-files failures are scope artifacts that reproduce identically on unmodified dev: check-release-identity (fixed by the folded-in bump) and onex-imperative-orchestrator-ratchet (fires on 13 node dirs this diff does not touch).

Evidence-Ticket: OMN-16355
Evidence-Source: OCC#6835

…fra PR

Lockfile CVE Scan (OMN-16228) went required and is RED on every open PR --
a fleet-wide merge blocker. The scanner is correct; the lockfile is
genuinely vulnerable. Raise the floors past the fixed versions and relock.

Blocking findings cleared (osv-scanner v2.5.1 -> check_lockfile_cve):

  click 8.3.1  PYSEC-2026-2132 / CVE-2026-7246 / GHSA-47fr-3ffg-hgmw
    HIGH (gate-computed CVSS 7.2). Command injection in click.edit():
    the editor command was handed to subprocess with shell=True.
    Fixed in 8.3.3 (shlex.split into an argv list, shell=True dropped).

  kafka-python 2.3.0  PYSEC-2026-2190 / CVE-2026-10142
    DoS: 4-byte protocol frame length used unvalidated -> multi-GB
    allocation, or an uncaught ValueError that wedges the connection.

  kafka-python 2.3.0  PYSEC-2026-2191 / CVE-2026-10143
    DoS: broker-supplied SCRAM iteration count passed straight to
    hashlib.pbkdf2_hmac() -> frozen client event loop, consumer-group
    eviction.

  Both kafka-python advisories are fixed in 2.3.2 (upstream #3019 frame-size
  validation + #3026 SCRAM iteration validation). They classify as UNKNOWN
  rather than HIGH because they carry only a CVSS_V4 vector and the gate
  parses CVSS_V3* only -- they still block via the intended fail-closed
  "UNKNOWN + fix-available -> BLOCK" rule. Left alone deliberately: narrowing
  that rule would turn these two into report-only, i.e. fail-open.

Resolution: click 8.3.1 -> 8.4.2, kafka-python 2.3.0 -> 2.3.2. The lock diff
moves exactly those two packages.

kafka-python ceiling tightened 4.0.0 -> 3.0.0 deliberately. 3.0.0 is a
breaking major: producer defaults flip to enable_idempotence=True/acks='all',
consumer session_timeout_ms 10s->45s, api_version_auto_timeout_ms renamed to
bootstrap_timeout_ms, Serializer/Partitioner signatures changed, KafkaError no
longer subclasses RuntimeError, NoBrokersAvailableError removed, kafka.sasl ->
kafka.net.sasl, kafka.client_async/kafka.conn deleted. Our kafka-python surface
is scripts/deploy-agent/ (KafkaProducer/KafkaConsumer on the live deploy control
bus) plus one integration test; the runtime itself is on aiokafka, untouched
here. Verified on 2.3.2 that every kwarg the deploy-agent passes still exists,
poll(timeout_ms=) is intact, and producer defaults are unchanged
(enable_idempotence=False, acks=1) -- exactly the semantics 3.0 would have
flipped under a live control bus. A 3.x migration is its own change with its
own proof, not a rider on a CVE unblock.

click took no ceiling change: no ParamType/Parameter subclassing in this repo,
so 8.4.0's typing rework does not reach us. mypy --strict clean over 2813 files.

Also carries the 0.38.7 -> 0.38.8 bump. The local check-release-identity hook
(pass_filenames: false, no --base) always enforces version-ahead and fails on
unmodified dev today, and this diff touches pyproject.toml so it fires here.
The dedicated bump PR (#2833, OMN-16351) cannot land first -- it is itself
blocked by this very Lockfile CVE Scan. Folding the bump in breaks the cycle;
#2833 becomes redundant. CI's own release-identity check (--base origin/dev)
was already exempt for this diff (no src/** change).

Evidence:
  before: 3 blocking findings, gate exit 1
  after:  0 blocking findings, gate exit 0 (4 MEDIUM/LOW report-only remain:
          h2 4.3.0 x2, pygments 2.19.2 x2 -- correctly non-blocking)
  496 passed CLI/click test surface; 198 passed deploy-agent unit
  mypy --strict clean; ruff clean; pre-commit clean on the real file scope
  kafka -m marker, serial, vs an origin/dev baseline worktree: branch 13F/67P
  vs baseline 14F/66P -- identical failure set minus one, all pre-existing
  .201 dev-lane-not-running failures, none introduced here

Fixes OMN-16355
Refs OMN-16228, OMN-16170, OMN-16351
@coderabbitai

coderabbitai Bot commented Aug 21, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your current included review allowance is based on your included PR review attempts over the past 7 days.

Next review available in: 4 minutes

Limit details: You’ve used the included review currently available. Your 117 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4632d65f-a9d6-4c0e-a347-d50e20b807e7

📥 Commits

Reviewing files that changed from the base of the PR and between 6729ba4 and 3256e46.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • docker/runners/runner-image.lock.json
  • pyproject.toml

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

✅ Hostile Reviewer — PASSED

Blocking findings (critical): 0
Total findings: 0
Models succeeded: qwen3-review,qwen3-review-b


Gate semantics (pilot phase)

Verdict Meaning Blocks merge?
passed No critical findings No
blocked CRITICAL findings found Yes
degraded All models unavailable (infra) No (pilot)

Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8468/OMN-8524)

@jonahgabriel

Copy link
Copy Markdown
Collaborator Author

Heads up: runner-image-build-smoke is failing here because this PR's uv.lock change invalidates the recorded shared_env_digest in docker/runners/runner-image.lock.json. Fix: uv run python scripts/ci/runner_image_identity.py --mode generate and commit the updated lock file (same fix I needed on OMN-16351 / #2833 after touching uv.lock).

…/kafka-python bump

uv.lock content changed with the click 8.3.1 -> 8.4.2 and kafka-python
2.3.0 -> 2.3.2 CVE-fix bump, which invalidates the recorded
shared_env_digest fingerprint in docker/runners/runner-image.lock.json.
Regenerated via scripts/ci/runner_image_identity.py --mode generate to
unblock runner-image-build-smoke and the Tests split jobs that assert
identity parity (test_runner_image_identity.py) -- same root cause and
fix as OMN-16351 / omnibase_infra#2833 hit after its own uv.lock change.
jonahgabriel added a commit to OmniNode-ai/onex_change_control that referenced this pull request Aug 21, 2026
#6835)

* evidence: OCC companion pass 1 for OmniNode-ai/omnibase_infra#2834

* evidence: OCC companion self-bind for #6835

---------

Co-authored-by: node-occ-companion-effect <occ-companion-effect@omninode.ai>
Co-authored-by: jonahgabriel <jonah@omninode.ai>
@github-actions
github-actions Bot merged commit 87fdd1a into dev Aug 21, 2026
180 of 183 checks passed
@github-actions
github-actions Bot deleted the jonah/omn-16355-lockfile-cve-click-kafka branch August 21, 2026 18:45
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