chore(security): target dependency lock for CVE fixes - #182
Conversation
1a048a9 to
dd4191c
Compare
There was a problem hiding this comment.
Thanks! I'm doing the CI side separately on main (install extras so the mcp tests stop being skipped, plus a uv lock --check gate). Please rebase once this is in: #184.
Your questions:
-
3.15 should be its own PR, wheel availability plus our matrix stops at 3.13.
-
The
google-adk<2.2pin is the more interesting one since it holds back a HIGH starlette CVE on the request path. Opening an issue for that.
| [project.optional-dependencies] | ||
| live = [ | ||
| "mcp>=1.26.0", | ||
| "mcp>=1.28.1,<2", |
There was a problem hiding this comment.
uv.lock isn't shipped in the wheel and we publish to PyPI, so pip install agentevals-cli still resolves the vulnerable versions.
Please floor both at the locked versions. python-multipart especially, it parses the upload endpoints.
| # pip so its vendored packages (msgpack, pkg_resources) don't ship unused. | ||
| && rm -rf /usr/local/lib/python*/site-packages/pip \ | ||
| /usr/local/lib/python*/site-packages/pip-*.dist-info \ | ||
| /usr/local/bin/pip* \ |
There was a problem hiding this comment.
Good change, two things:
- This regresses silently.
rm -rfon a non-matching glob exits 0, so a base image or Python minor change quietly restores pip and its vendored CVEs with nothing failing. Add to the same layer:&& ! /usr/local/bin/python -c "import pip" 2>/dev/null \ - Please call out the pip removal in the PR body. The title says lock bumps only, so this image change is currently invisible in the release notes.
Qq: newer pip doesn't vendor pkg_resources, that comes from setuptools. Which path did the scanner actually flag?
There was a problem hiding this comment.
pip 26.2.1 (which the image has) has a vendored copy of pkg_resources (/usr/local/lib/python3.14/site-packages/pip/_vendor/pkg_resources/), and it's recorded in pip/_vendor/vendor.txt as setuptools==70.3.0. That manifest line is what the scanner keyed on
| resolution-markers = [ | ||
| "python_full_version < '3.13' and sys_platform == 'win32'", | ||
| "python_full_version < '3.13' and sys_platform == 'emscripten'", | ||
| "python_full_version < '3.13' and sys_platform != 'emscripten' and sys_platform != 'win32'", | ||
| ] | ||
| dependencies = [ | ||
| { name = "google-api-core" }, | ||
| { name = "google-auth" }, | ||
| { name = "google-cloud-core" }, | ||
| { name = "google-crc32c" }, | ||
| { name = "google-resumable-media" }, | ||
| { name = "requests" }, | ||
| { name = "google-api-core", marker = "python_full_version < '3.13'" }, | ||
| { name = "google-auth", marker = "python_full_version < '3.13'" }, | ||
| { name = "google-cloud-core", marker = "python_full_version < '3.13'" }, | ||
| { name = "google-crc32c", marker = "python_full_version < '3.13'" }, | ||
| { name = "google-resumable-media", marker = "python_full_version < '3.13'" }, | ||
| { name = "requests", marker = "python_full_version < '3.13'" }, |
There was a problem hiding this comment.
This forks the lock by Python version: google-cloud-storage only moves to 3.13.1 on 3.13+, and stays at 2.19.0 below that.
So if you scanned the built image, that's 3.14 and only covers one side of the fork. Do you know if anything scanned the 3.11/3.12 graph, which is what a pip install user gets?
There was a problem hiding this comment.
Ah good call-out, i just scanned the image so it would have been 3.14!
I now did a trivy scan of 3.11 requirements (exported via uv export --frozen --no-dev --all-extras -p 3.11 ) which were just the known starlette cves.
Signed-off-by: Fabian Gonzalez <fabian.gonzalez@solo.io>
dd4191c to
384e416
Compare
Signed-off-by: Fabian Gonzalez <fabian.gonzalez@solo.io>
krisztianfekete
left a comment
There was a problem hiding this comment.
Thanks, two small things:
- Can you drop
cryptography>=50.0.0? It's the floor most likely to make us unresolvable next to something else, it's compiled, and we never import it. The lock still pins 50.0.0 for the image. - The comment says google-adk[eval] pulls all of these, which is not quite right. litellm comes via a google-cloud-aiplatform extra, aiohttp via litellm and kubernetes, idna via httpx and requests. Can you please reword these to not confuse future readers?
Signed-off-by: Fabian Gonzalez <fabian.gonzalez@solo.io>
|
Dropped the cryptography floor and reworded the comment (made it generalized, i don't think specifics really matter there) |
Resolves CVEs with targeted
uv lock --upgrade-packagebumps for dependencies with medium+ CVE fixes.Dockerfile
pipremovalRemoved the base image's bundled
pip(unused) as it resulted in CVEs being caught due to its vendored packages - at least using Trivy, which checkspip/_vendor/vendor.txt.Resolved CVEs Summary
70 fixed
Notes
Unresolved CVEs
The remaining CVEs are unresolvable (~96 Debian bookworm OS packages with no published fix, 4 starlette blocked by the google-adk<2.2 pin, python-interpreter CVEs fixed only in 3.15 line)
Debian OS packages — no fix shipped in bookworm:
CPython interpreter — fixes exist only in the 3.15 line (no 3.14 backport published): HIGH CVE-2026-11940, CVE-2026-11972, CVE-2026-15308; MEDIUM CVE-2025-15366, CVE-2025-15367, CVE-2026-0864, CVE-2026-12003; plus CVE-2026-4360 (no fix anywhere yet). Fixable only by migrating the base to python:3.15-slim. Do we want to / are we OK with upgrading to python 3.15?
starlette — fix exists but is unreachable: MEDIUM CVE-2026-48710 (fixed 1.0.1), CVE-2026-48817 + HIGH CVE-2026-48818 (1.1.0), HIGH CVE-2026-54283 (1.3.1) — all require starlette 1.x, blocked by agentevals' google-adk<2.2 pin (google-adk ≥2.6 is what allows starlette ≥1.3.1).
Local Verification
test_mcp_server.py::test_evaluate_sessions_posts_builtin_evaluator_overrides) reproduced identically onmainwith the unmodified lock (expected payload predates the credentialRef/judgeBaseUrl fields), so it's pre-existing, not introduced here.