fix(security): floor litellm/wandb/lxml past known CVEs; relax stale click cap - #1507
fix(security): floor litellm/wandb/lxml past known CVEs; relax stale click cap#1507nicgupta-nvidia wants to merge 13 commits into
Conversation
…click cap - litellm[caching] 1.83.14 -> 1.84.10: GHSA-4xpc-pv4p-pm3w (Critical) — 1.83.x leaks the API key to an arbitrary attacker-controlled Host header; fixed in 1.84.0. Minimal exact-pin jump; resolves with the existing httpx[http2]>=0.28.1 override (litellm 1.84.10 needs httpx>=0.28.0). - wandb -> >=0.27.1: the bundled wandb-core Go binary in older wheels ships golang.org/x/crypto 0.50.0 + Go 1.26.2 stdlib with 7 Critical / 13 High CVEs (incl. GHSA-x527-x647-q7gg et al.); 0.27.1 is the first release embedding patched x/crypto 0.52.0 (verified on both arches). - click < 8.2.0 cap removed + typer >= 0.16: the cap guarded against the typer/click-8.2 make_metavar break (ai-dynamo/dynamo#1039, closed 2025-06-26, fixed in typer >=0.16); wandb>=0.27.1 requires click>=8.2, and requires-python >=3.10 satisfies click 8.2's floor. - lxml -> >=6.1.0 (stem extra): GHSA-vfmq-68hx-4jfw (High). Validation: uv pip compile of core+pipeline (py3.10, with the pyproject overrides) resolves cleanly — litellm 1.84.10 / wandb 0.28.0 / click 8.4.2 / typer 0.26.8 / httpx 0.28.1; stem extra resolves with lxml 6.1.1. Runtime smoke on the resolved set: litellm/wandb import clean; typer --help rendering (the exact make_metavar crash path) passes under click 8.4. Signed-off-by: Nick Gupta <nicgupta@nvidia.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughDependency requirements now include security floors and compatibility pins, BFCL uses the updated code generator version, Nemo Skills builds and installs a pinned W&B core binary, and regression plus functional tests validate the updated dependency behavior. ChangesDependency security and compatibility updates
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Comment |
|
Note Unit test generation is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
2 similar comments
|
Note Unit test generation is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
|
Note Unit test generation is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
|
✅ Unit tests committed locally. Commit: |
|
✅ Unit tests committed locally. Commit: |
|
✅ Created PR with unit tests: #1508 |
CodeRabbit's test generation ran twice and committed two near-duplicate suites (test_dependency_pins.py + test_requirements_versions.py) covering the same pins. Keep the more robust one (operator-keyed specifier parsing instead of next(iter(specifier)), which is order-fragile on multi-spec requirements) and graft the three tests unique to the deleted file: pyproject stale-comment guards, pipeline-lines-parseable, and the wandb/typer click-comment consistency check. Also: - fix the copyright year (2026, not 2025) - add tomli (python_version < 3.11) to common-tests.txt so the pyproject override tests actually RUN on the CI's Python 3.10 instead of silently skipping (tomllib is stdlib only from 3.11) - add the missing trailing newline that failed the pre-commit end-of-file-fixer hook on the generated files 17 tests pass on Python 3.10 with the CI's -m 'not gpu' selection; pre-commit (pinned ruff) clean. Signed-off-by: Nick Gupta <nicgupta@nvidia.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/test_requirements_versions.py (1)
95-96: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueExtract a shared helper for specifier-floor extraction.
The
{spec.operator: spec.version for spec in req.specifier}pattern is repeated across four test methods. A small helper reduces duplication and keeps the assertions consistent if the extraction logic ever needs to change (e.g., handling multiple specifiers of the same operator).♻️ Proposed helper
+def _get_specifier(req: Requirement, operator: str) -> Version: + """Return the parsed Version for the given specifier operator, asserting it's present.""" + specs = {spec.operator: spec.version for spec in req.specifier} + assert operator in specs, f"expected a '{operator}' specifier for {req.name}, got {req.specifier}" + return Version(specs[operator]) + + class TestCoreRequirements: ... def test_litellm_pin_fixes_ghsa_4xpc_pv4p_pm3w(self): req, comment = _find_requirement(CORE_REQUIREMENTS, "litellm") assert "caching" in req.extras, "litellm[caching] extra must be preserved" - - # Must be pinned to an exact version (== specifier) so the resolver is deterministic. - specs = {spec.operator: spec.version for spec in req.specifier} - assert "==" in specs, f"expected an exact pin for litellm, got specifier {req.specifier}" - - pinned_version = Version(specs["=="]) + pinned_version = _get_specifier(req, "==")Also applies to: 113-114, 156-157, 178-179
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_requirements_versions.py` around lines 95 - 96, The specifier extraction logic is duplicated across multiple test methods in the requirements version tests, so add a shared helper for turning a requirement’s specifiers into a usable mapping or floor value. Update the affected assertions in the test class that currently build specs from req.specifier so they call this helper instead, keeping the exact-pin checks unchanged while centralizing the extraction behavior in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tests/test_requirements_versions.py`:
- Around line 95-96: The specifier extraction logic is duplicated across
multiple test methods in the requirements version tests, so add a shared helper
for turning a requirement’s specifiers into a usable mapping or floor value.
Update the affected assertions in the test class that currently build specs from
req.specifier so they call this helper instead, keeping the exact-pin checks
unchanged while centralizing the extraction behavior in one place.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 0ea160ee-449e-4976-b41b-78cdb3607f1a
📒 Files selected for processing (2)
requirements/common-tests.txttests/test_requirements_versions.py
…ed deps
test_requirements_versions.py only asserts the pins statically. Add functional
coverage that drives litellm 1.84.10, typer/click, and wandb through NeMo-Skills'
own code paths (CPU-only, hermetic — no sandbox, no live endpoint, no API keys)
so a resolve to a behavior-divergent version fails CI, not a production run:
* litellm: OpenAIModel.litellm_kwargs binds api_key to the configured
base_url/api_base only (GHSA-4xpc-pv4p-pm3w regression), generate_async
calls litellm.acompletion with those credentials and parses the 1.84
response, and the imported litellm exception/type surface still exists.
* typer/click: ns CLI --help + per-command help render Parameter.make_metavar
(the click 8.2 break typer>=0.16 fixes) and unknown commands are usage errors.
* wandb: log_random_samples matches the wandb 0.28 init/save/summary/finish
contract, and a real offline init/finish cycle runs with no account.
* lxml: importorskip-guarded real parse (optional stem extra).
Signed-off-by: Nick Gupta <nicgupta@nvidia.com>
Bring in #1509 (drop deleted vedas pin) so the sandbox image build — and therefore this PR's CI — is unblocked. Signed-off-by: Nick Gupta <nicgupta@nvidia.com>
Cherry-picked from #1507 (fix/security-dependency-floors), which is the last configuration in which the full CPU suite passed (725 passed, 0 failed on 2026-07-14). With click pinned below 8.2 the ns CLI stops accepting underscore-style option names, so every test that shells out to `ns eval --output_dir=...` or `ns summarize_results --max_seq_len=...` fails with "Missing option '--output-dir'" / "No such option: --max_seq_len". The typer floor moves to 0.16 alongside it because that is the first release compatible with click 8.2 (fixes the make_metavar break that motivated the original pin). Only the CLI-relevant pair is taken here. #1507's litellm, wandb and stem security floors are left to that PR. Signed-off-by: gwarmstrong <gwarmstrong@users.noreply.github.com>
Dropping the click<8.2 cap alone was not enough: wandb 0.26.1 only requires click>=8.0.1, so uv still settled on click 8.1.8 and the CPU suite failed identically (10 failed, 685 passed). wandb 0.27.1 is the first release requiring click>=8.2.0, which is what actually moves the resolver. Taken from #1507, the last configuration in which the full suite passed. Signed-off-by: gwarmstrong <gwarmstrong@users.noreply.github.com>
This is the actual root cause of the CPU suite failures, and the reason
removing the repo's own `click < 8.2.0` cap changed nothing: litellm
1.83.14 declares an exact `click==8.1.8` dependency, capping the entire
tree below click 8.2 regardless of what this repo asks for.
uv spelled it out when wandb>=0.27.1 was added:
Because wandb>=0.27.1 depends on click>=8.2.0 and litellm==1.83.14
depends on click==8.1.8, we can conclude that litellm==1.83.14 and
wandb>=0.27.1 are incompatible.
litellm 1.84.10 relaxes that to click>=8.0.0,<9.0 (and clears
GHSA-4xpc-pv4p-pm3w). With it, `uv pip install -e .[dev]` resolves to
click 8.4.2 / typer 0.27.0 / wandb 0.28.1.
Taken from #1507 together with the wandb floor and the click cap removal;
the three only work as a set.
Signed-off-by: gwarmstrong <gwarmstrong@users.noreply.github.com>
…cy-floors # Conflicts: # core/requirements.txt # requirements/pipeline.txt
Signed-off-by: Nick Gupta <nicgupta@nvidia.com>
Signed-off-by: Nick Gupta <nicgupta@nvidia.com>
Signed-off-by: Nick Gupta <nicgupta@nvidia.com>
Signed-off-by: Nick Gupta <nicgupta@nvidia.com>
Signed-off-by: Nick Gupta <nicgupta@nvidia.com>
Signed-off-by: Nick Gupta <nicgupta@nvidia.com>
|
August 6 High-severity follow-up (commit 75d0c6a):
Focused validation: 35 security tests passed, Ruff lint/format passed (excluding one pre-existing C408 on an untouched line), the Ray private import resolved |
What
Remediates all 17 High findings from the July 30 Trivy scan of:
nvcr.io/0953339617667984/nemo-skills:4fbf5d54GitPythonGitPython>=3.1.55datamodel-code-generator>=0.64.0; BFCL runtime pin also moved to==0.64.0wandb-coreGo stdlibwandb-coregRPCwandb-corex/textJuly 30 nSpect reconciliation
The nSpect scan of the same exact image reports:
All 16 detailed nSpect High advisories are covered by this PR:
datamodel-code-generatoradvisoriesnSpect also reports a non-CVE global-policy warning for
.gitmetadata under/root/.cache/uv/sdists-v9. Commit8817cf64removes the build-only uv cache from the final image.Why W&B needs a patched core
wandb==0.28.1is the latest W&B release, but its published core still uses Go 1.26.4, gRPC 1.82.0, and x/text 0.38.0. A normal package bump therefore does not clear the final three Trivy findings.The Dockerfile now:
e1184091520c9b44aa1096fdb27b2f4bf52f26d7;wandb-corein agolang:1.26.5builder stage using W&B's upstream build tags and vendored modules;go version -mreports Go 1.26.5, gRPC 1.82.1, and x/text 0.40.0;wandbis pinned to 0.28.1 so its Python package remains a deterministic protocol pair with the patched core.Advisory coverage
Existing PR scope retained
litellm[caching]==1.84.10for GHSA-4xpc-pv4p-pm3wlxml>=6.1.0for GHSA-vfmq-68hx-4jfwtyper>=0.16compatibility floorThe branch has also been merged with current
main.Validation
Completed locally:
tests/test_requirements_versions.py: 26 passedinit/log/finishsmoke test: passedgit diff --check: passedCompleted in GitHub Actions before the final cache-cleanup commit:
wandb-coreGo/module assertions and embedded commit-SHA smoke check: passedGitPython==3.1.57,datamodel-code-generator==0.71.0, andwandb==0.28.1The latest commit must complete the same required checks. A fresh published-image nSpect and Trivy scan is still required before release.
Security regression tests
Notes
nltk(GHSA-p4gq-832x-fm9v) remains outside this PR because the advisory has no patched release.July 31 follow-up: msgpack and setuptools
A fresh Trivy 0.71.2 multi-architecture scan of the NVFlow release-baseline image found two additional distinct High findings on both platforms:
nvcr.io/0953339617667984/nemo-skills:dev-f23ae32dOCI index:
sha256:11e67bb94e941329681cb4b600ba03440c3344df05becc8de9974126fcd16414msgpack>=1.2.1setuptools>=78.1.1These are four architecture-aware rows but two unique advisory/package findings.
Commit
672a6d80adds durable upstream enforcement:uvoverrides keep the complete environment atmsgpack>=1.2.1andsetuptools>=78.1.1;setuptools>=78.1.1;The current lock already resolves
msgpack==1.2.1andsetuptools==83.0.0; the explicit floors make those safe choices policy rather than incidental resolver output.July 31 validation
tests/test_requirements_versions.py: 32 passedmsgpack==1.2.1,setuptools==83.0.0uv lock --check: passed (294 packages)git diff --check: passedA rebuilt multi-architecture image and fresh Trivy/nSpect scan are still required to verify the published-image result.