backend: bump 15 Python deps for ~17 MEDIUM + 1 HIGH + 6 LOW CVEs#7146
backend: bump 15 Python deps for ~17 MEDIUM + 1 HIGH + 6 LOW CVEs#7146
Conversation
cryptography: 46.0.5 -> 46.0.7 fixes CVE-2026-39892 (CVSS 9.8, flagged as MEDIUM by GCP scanner). Patch bump within 46.x — no API changes. Verified with docker test image rebuild + 190-test baseline subset all green; cryptography 46.0.7 confirmed installed.
Jinja2: 3.1.4 -> 3.1.6 fixes: - CVE-2024-56201 (CVSS 8.8) — sandbox escape via custom filename in templates - CVE-2024-56326 (CVSS 7.8) — sandbox escape via str.format in conditional context - CVE-2025-27516 (CVSS 8.8) — sandbox bypass via |attr filter Patch bumps within 3.1.x. Verified with docker test image rebuild + 190-test baseline subset all green; Jinja2 3.1.6 confirmed installed.
aiohttp: 3.13.3 -> 3.13.4 fixes: - CVE-2026-22815 (MEDIUM 7.5) - CVE-2026-34515 (MEDIUM 7.5) - CVE-2026-34516 (MEDIUM 7.5) - CVE-2026-34525 (MEDIUM 5.3) - CVE-2026-34520 (LOW, CVSS 9.1 — GCP severity tag inconsistent with score) - CVE-2026-34513, CVE-2026-34514, CVE-2026-34517, CVE-2026-34518, CVE-2026-34519 (5x LOW) Patch bump within 3.13.x. Verified with docker test image rebuild + 190-test baseline subset all green; aiohttp 3.13.4 confirmed installed.
fonttools: 4.53.1 -> 4.60.2 fixes CVE-2025-66034 (CVSS 9.8, flagged as MEDIUM by GCP scanner) — XML parser issue affecting font subsetting. Minor bump within 4.x. Verified with docker test image rebuild + 190-test baseline subset all green; fonttools 4.60.2 confirmed installed.
Mako: 1.3.5 -> 1.3.11 fixes CVE-2026-41205 (CVSS 7.5, MEDIUM) — ReDoS in template parsing. Patch bumps within 1.3.x. Verified with docker test image rebuild + 190-test baseline subset all green; Mako 1.3.11 confirmed installed.
requests: ~=2.32.5 -> ~=2.33.0 fixes CVE-2026-25645 (CVSS 5.5, MEDIUM) — credential exposure via .netrc when following cross-host redirects. Compatible-release pin allows 2.33.x patches. Verified with docker test image rebuild + 190-test baseline subset all green; requests 2.33.1 confirmed installed.
python-dotenv: 1.0.1 -> 1.2.2 fixes CVE-2026-28684 (CVSS 6.6, MEDIUM) — command injection in CLI when expanding shell variables from untrusted .env files. Minor bump within 1.x. Verified with docker test image rebuild + 190-test baseline subset all green; python-dotenv 1.2.2 confirmed installed.
filelock: 3.15.4 -> 3.20.3 fixes: - CVE-2025-68146 (CVSS 6.5, MEDIUM) — race condition in lock release - CVE-2026-22701 (CVSS 5.3, MEDIUM) — symlink follow during lock acquisition Minor bumps within 3.x. 3.20.3 covers both fixes (>= 3.20.1). Verified with docker test image rebuild + 190-test baseline subset all green; filelock 3.20.3 confirmed installed.
marshmallow: 3.21.3 -> 3.26.2 fixes CVE-2025-68480 (CVSS 5.3, MEDIUM) — schema validation bypass under specific nested-field configurations. Minor bumps within 3.x. Verified with docker test image rebuild + 190-test baseline subset all green; marshmallow 3.26.2 confirmed installed.
python-multipart: 0.0.22 -> 0.0.26 fixes CVE-2026-40347 (CVSS 5.3, MEDIUM) — DoS via malformed boundary parsing. Patch bumps within 0.0.x. Verified with docker test image rebuild + 190-test baseline subset all green; python-multipart 0.0.26 confirmed installed.
streamlit: 1.51.0 -> 1.54.0 fixes CVE-2026-33682 (CVSS 4.8, MEDIUM) — XSS via component-side text rendering. Cascade: streamlit 1.54 requires cachetools >=5.5,<7. Bumped cachetools 5.4.0 -> 5.5.0 (smallest version that satisfies); google-auth's cachetools constraint is <6,>=2.0 so 5.5.0 sits inside both ranges. Verified with docker test image rebuild + 190-test baseline subset all green; streamlit 1.54.0 and cachetools 5.5.0 confirmed installed.
h2: 4.1.0 -> 4.3.0 fixes CVE-2025-57804 (MEDIUM) — HTTP/2 frame buffer growth could cause memory exhaustion. Cascades enforced by h2 4.3's pins: - hyperframe: 6.0.1 -> 6.1.0 (>=6.1 required) - hpack: 4.0.0 -> 4.1.0 (>=4.1 required) Verified with docker test image rebuild + 190-test baseline subset all green; h2 4.3.0, hyperframe 6.1.0, hpack 4.1.0 confirmed installed.
langchain-core: 0.3.81 -> 0.3.84 fixes CVE-2026-40087 (CVSS 5.3, MEDIUM). Patch within 0.3.x — no API changes, does not pull the langchain 1.x major migration. The 1.x bump (HIGH CVE-2026-34070, MEDIUM CVE-2026-26013, LOW CVE-2026-26013) remains parked for the langchain-stack PR. Verified with docker test image rebuild + 190-test baseline subset all green; langchain-core 0.3.84 confirmed installed.
langsmith: 0.4.37 -> 0.7.31 fixes: - CVE-2026-25528 (CVSS 5.8, MEDIUM) - CVE-2026-41182 (CVSS 5.3, MEDIUM) Multiple minor bumps within 0.x. Resolver kept langchain-core at 0.3.84 — no forced upgrade into the langchain 1.x major bump. Verified with docker test image rebuild + 190-test baseline subset all green; langsmith 0.7.31 confirmed installed.
starlette: 0.40.0 -> 0.49.1 fixes: - CVE-2025-62727 (CVSS 7.5, HIGH) — request smuggling via malformed multipart boundary - CVE-2025-54121 (CVSS 5.3, MEDIUM) — DoS in form parsing Cascade: fastapi 0.118 caps starlette <0.49. Bumped fastapi 0.118.0 -> 0.121.0 (smallest version that allows starlette 0.49, constraint <0.50,>=0.40). The MultiPartParser.max_part_size class attribute (set to 200 MB in main.py since starlette 0.40 introduced the 1 MB default) still exists in 0.49 — verified via import + override + FastAPI app instantiation smoke test. Per-route override via Request.form() is available from 0.45 and tracked separately in #7130. Verified with docker test image rebuild + 190-test baseline subset all green; starlette 0.49.1 and fastapi 0.121.0 confirmed installed.
|
@morpheus review — Approved ✅ Single-file diff, 19 version pin changes in Verified:
15 atomic commits, one per package family, each independently revertable. Labels set (backend, python, Security). Clean. |
Greptile SummaryThis PR bumps 15 Python packages in Confidence Score: 4/5Safe to merge; all changes are version bumps with no application code modified and a tested unit-test baseline already green. Only P2 findings: starlette could be bumped two patch levels further to 0.49.3, and fastapi-cli is stale. No logic errors, no security regressions, no breaking API changes detected across all 15 bumped packages. The large langsmith jump (0.4→0.7) only touches stable Client/traceable APIs, and the marshmallow 3.26 removal of ordered=True has no matches in the codebase. backend/requirements.txt — starlette pin at 0.49.1 vs latest 0.49.3 patch Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["starlette 0.40.0 → 0.49.1\nCVE-2025-62727 HIGH\nCVE-2025-54121 MEDIUM"] -->|"caps starlette <0.49\n→ must bump"| B["fastapi 0.118.0 → 0.121.0\n(cascade)"]
C["streamlit 1.51.0 → 1.54.0\nCVE-2026-33682 MEDIUM"] -->|"requires cachetools ≥5.5"| D["cachetools 5.4 → 5.5\n(cascade)"]
E["h2 4.1.0 → 4.3.0\nCVE-2025-57804 MEDIUM"] -->|"requires hyperframe ≥6.1"| F["hyperframe 6.0.1 → 6.1.0\n(cascade)"]
E -->|"requires hpack ≥4.1"| G["hpack 4.0.0 → 4.1.0\n(cascade)"]
H["cryptography 46.0.5 → 46.0.7\nCVE-2026-39892 MEDIUM"]
I["Jinja2 3.1.4 → 3.1.6\n3× MEDIUM sandbox escapes"]
J["aiohttp 3.13.3 → 3.13.4\n4× MEDIUM + 5× LOW"]
K["langsmith 0.4.37 → 0.7.31\n2× MEDIUM"]
L["marshmallow 3.21.3 → 3.26.2\nCVE-2025-68480 MEDIUM"]
Reviews (1): Last reviewed commit: "Bump starlette + fastapi for HIGH CVE-20..." | Re-trigger Greptile |
| stack-data==0.6.3 | ||
| starlette==0.40.0 | ||
| streamlit==1.51.0 | ||
| starlette==0.49.1 |
There was a problem hiding this comment.
Two patch releases — 0.49.2 and 0.49.3 — shipped on Nov 1, 2025, three days after 0.49.1. starlette 0.49.3 specifically relaxes the
Middleware type strictness, which is directly relevant to the custom TimeoutMiddleware and BYOKMiddleware added via app.add_middleware() in main.py. While the type-relaxation is unlikely to cause a runtime crash, pinning to 0.49.3 closes the gap at no extra cost and is the latest safe 0.49.x release that fastapi 0.121.0 supports.
| starlette==0.49.1 | |
| starlette==0.49.3 |
| fal_client==0.4.1 | ||
| fastapi==0.118.0 | ||
| fastapi==0.121.0 | ||
| fastapi-cli==0.0.5 |
There was a problem hiding this comment.
fastapi-cli is pinned at 0.0.5 (released Aug 2024) while fastapi was bumped to 0.121.0 and fastapi-cli is now up to 0.0.24. The pin satisfies fastapi's >=0.0.5 requirement so it won't fail on install, but it's 9 minor releases behind and may miss bugfixes relevant to the fastapi dev / fastapi run CLI paths used in local development.
| fastapi-cli==0.0.5 | |
| fastapi-cli==0.0.7 |
## Summary 2 atomic commits closing the deferred langchain-stack CVEs from the Artifact Registry scan on `gcr.io/based-hardware/backend@sha256:348e17d6…`. langchain ecosystem moves from the 0.3.x line to 1.x as one resolver-satisfiable set; tight inter-package pins (e.g. `langgraph-prebuilt 1.0.8` requires `langchain-core>=1.0.0`, `langchain-text-splitters 1.1.2` requires `langchain-core>=1.2.31`) make a partial bump impossible. | Commit | Scope | CVEs | |---|---|---| | 1 | Refactor `utils/llm/persona.py` — single deprecated `from langchain.schema` import → `from langchain_core.messages` (no-op under 0.3.x; required for 1.x where `langchain.schema` is removed) | — | | 2 | langchain ecosystem 0.3 → 1.x (11 packages) + 4 cascade pins | 2 HIGH + 3 MEDIUM | **Closed:** | Package | Was → Now | CVE | Severity | |---|---|---|---| | langchain-core | 0.3.84 → 1.3.2 | CVE-2026-34070 | HIGH 7.5 | | langgraph-checkpoint | 2.1.2 → 4.0.0 | CVE-2025-64439 | HIGH | | langgraph | 0.6.10 → 1.0.10 | CVE-2026-28277 | MEDIUM 7.2 | | langgraph-checkpoint | 2.1.2 → 4.0.0 | CVE-2026-27794 | MEDIUM 6.6 (covered by same bump) | | langchain-text-splitters | 0.3.11 → 1.1.2 | CVE-2026-41481 | MEDIUM 6.5 | ## Locked-in cascade (langchain stack) | Package | Was → Now | Reason | |---|---|---| | langchain | 0.3.27 → 1.2.9 | locked to langchain-core 1.x | | langchain-community | 0.3.31 → 0.4.1 | locked to langchain-core 1.x | | langchain-openai | 0.3.35 → 1.1.9 | locked; held below 1.1.10 to defer the openai 2.x cascade | | langchain-google-genai | 2.1.12 → 3.2.0 | locked to langchain-core 1.x (3.x is the 1.x-compatible series) | | langchain-pinecone | 0.2.12 → 0.2.13 | 0.2.13 opens its langchain-core cap to 1.x | | langgraph-prebuilt | (transitive 0.6.5) → 1.0.8 (new explicit pin) | required by langgraph 1.0 | | langgraph-sdk | 0.2.9 → 0.3.0 | required by langgraph 1.0 | ## Cascade pins outside the langchain stack | Package | Was → Now | Reason | |---|---|---| | openai | 1.104.2 → 1.109.1 | langchain-openai 1.1.9 requires openai>=1.109.1; held within 1.x to keep the openai 2.x SDK migration out of scope | | pydantic | 2.8.2 → 2.11.10 | langchain-pinecone 0.2.13 requires pydantic>=2.11.1 | | pydantic_core | 2.20.1 → 2.33.2 | pydantic 2.11.10 hard-pins pydantic-core==2.33.2 | | typing_extensions | 4.12.2 → 4.15.0 | **regression fix** — langchain-core 1.x uses the TypedDict `extra_items` keyword (added in typing_extensions 4.13). Without this bump, every `utils/llm/*` and `utils/retrieval/*` module fails at import with `_TypedDictMeta.__new__() got an unexpected keyword argument 'extra_items'`. Caught via post-bump module-import smoke test, not the unit subset | All cascade bumps held to the smallest version that resolves the conflict. ## Code change in commit 1 The single deprecated path in our code (`from langchain.schema import SystemMessage, HumanMessage, AIMessage` in `utils/llm/persona.py:5`) moves to `from langchain_core.messages import …`. The classes are identical (verified with `is` comparison): `langchain.schema` has been a re-export of `langchain_core.messages` since 0.1.x and is removed entirely in the langchain 1.x line. Doing the migration under the existing 0.3.x pin keeps the bump commit a pure dep change. ## Out of scope (deferred) | Package | CVE | Why deferred | |---|---|---| | langchain-openai 1.1.9 → 1.1.14 | CVE-2026-41488 | LOW; fix at 1.1.14 requires openai>=2.26.0, which is a major SDK migration. Covered separately. | | openai 1.109.1 → 2.x | (no CVE itself) | Belongs with the langchain-openai 1.1.14 bump above | ## Test plan For the bump commit: 1. Update `requirements.txt` (15 pinned + 1 new pin) 2. Rebuild local `Dockerfile.test` (Python 3.11-slim, requirements.txt minus the source-built `lc3py`) — only the pip install layer rebuilds 3. Run baseline 190-test subset (same 11 files used in #7126/#7127/#7146) 4. **Additional:** smoke-import every module under `utils/llm/`, `utils/retrieval/`, `utils/observability/` that imports any langchain-* package (28 modules) — catches API/typing regressions that the baseline subset doesn't exercise All commits individually green: - 190-test baseline subset all pass - 28 langchain-using modules all import cleanly (only `DefaultCredentialsError` on modules that touch GCP at import time, expected in test env without service account) ## Verifying after deploy - [ ] Re-scan rebuilt image; expect the listed CVEs to clear. - [ ] Smoke `/health`, an LLM-powered route (chat or memory generation), and a retrieval-tool route (calendar or memory search) to confirm the langchain 1.x runtime APIs behave correctly under real LLM traffic.
Summary
15 atomic commits, one per package family, closing the Python-only MEDIUM CVEs flagged by the Artifact Registry scan on the deployed backend image (
gcr.io/based-hardware/backend@sha256:348e17d6…, revisionbackend-00984-2nf). One bump (starlette) also closes a HIGH CVE that surfaced after #7126/#7127 merged.Net: 17 MEDIUM + 1 HIGH + 6 LOW CVEs closed, all atomic / independently revertible.
Cascade summary
All cascade bumps held to the minimum version that resolves the conflict.
Notes on starlette + main.py
starlette 0.40 (introduced in #7127) shipped a default 1 MB cap per multipart form part. The startup-time
MultiPartParser.max_part_size = 200 MBpatch inbackend/main.pycontinues to work in starlette 0.49 — verified via import + override + FastAPI app instantiation smoke test. Per-route caps (tracked in #7130) become available now that we're past starlette 0.45.Deferred
The langchain ecosystem majors (langgraph 0.6 → 1.x, langgraph-checkpoint 2 → 4, langchain-text-splitters 0.3 → 1.x) remain parked for a separate PR. Those bumps require API migration in
backend/utils/llm/andbackend/utils/retrieval/.Test plan
For each commit:
requirements.txtDockerfile.test(Python 3.11-slim, requirements.txt minus the source-builtlc3py) — only the pip install layer rebuildsAll 15 commits individually green. Cascade bumps were discovered by attempting the headline bump, reading the resolver error, and pinning the smallest version that resolves it.
Verifying after deploy
/health, an auth route, and a multipart upload route (voice-message or persona thumbnail) to confirm the starlette/fastapi bump didn't regress request handling.