Skip to content

backend: bump 15 Python deps for ~17 MEDIUM + 1 HIGH + 6 LOW CVEs#7146

Merged
mdmohsin7 merged 15 commits intomainfrom
charles/fix-backend-python-vulns-mediums
May 3, 2026
Merged

backend: bump 15 Python deps for ~17 MEDIUM + 1 HIGH + 6 LOW CVEs#7146
mdmohsin7 merged 15 commits intomainfrom
charles/fix-backend-python-vulns-mediums

Conversation

@mdmohsin7
Copy link
Copy Markdown
Member

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…, revision backend-00984-2nf). One bump (starlette) also closes a HIGH CVE that surfaced after #7126/#7127 merged.

Commit Package Was → Now CVEs (sev)
1 cryptography 46.0.5 → 46.0.7 CVE-2026-39892 (MEDIUM, CVSS 9.8)
2 Jinja2 3.1.4 → 3.1.6 CVE-2024-56201, CVE-2024-56326, CVE-2025-27516 (3× MEDIUM, sandbox escapes)
3 aiohttp 3.13.3 → 3.13.4 CVE-2026-22815, CVE-2026-34515, CVE-2026-34516, CVE-2026-34525 (4× MEDIUM) + CVE-2026-34520 + 5× LOW
4 fonttools 4.53.1 → 4.60.2 CVE-2025-66034 (MEDIUM, CVSS 9.8)
5 Mako 1.3.5 → 1.3.11 CVE-2026-41205 (MEDIUM 7.5)
6 requests ~=2.32.5 → ~=2.33.0 CVE-2026-25645 (MEDIUM 5.5)
7 python-dotenv 1.0.1 → 1.2.2 CVE-2026-28684 (MEDIUM 6.6)
8 filelock 3.15.4 → 3.20.3 CVE-2025-68146, CVE-2026-22701 (2× MEDIUM)
9 marshmallow 3.21.3 → 3.26.2 CVE-2025-68480 (MEDIUM 5.3)
10 python-multipart 0.0.22 → 0.0.26 CVE-2026-40347 (MEDIUM 5.3)
11 streamlit (+ cachetools 5.4 → 5.5) 1.51.0 → 1.54.0 CVE-2026-33682 (MEDIUM 4.8)
12 h2 (+ hyperframe 6.0.1 → 6.1.0, hpack 4.0.0 → 4.1.0) 4.1.0 → 4.3.0 CVE-2025-57804 (MEDIUM)
13 langchain-core 0.3.81 → 0.3.84 CVE-2026-40087 (MEDIUM 5.3, patch only — does not pull 1.x major)
14 langsmith 0.4.37 → 0.7.31 CVE-2026-25528, CVE-2026-41182 (2× MEDIUM)
15 starlette (+ fastapi 0.118 → 0.121) 0.40.0 → 0.49.1 CVE-2025-62727 (HIGH 7.5) + CVE-2025-54121 (MEDIUM 5.3)

Net: 17 MEDIUM + 1 HIGH + 6 LOW CVEs closed, all atomic / independently revertible.

Cascade summary

Cascade Reason
cachetools 5.4 → 5.5 streamlit 1.54 requires cachetools >=5.5,<7
hyperframe 6.0.1 → 6.1.0 h2 4.3 requires hyperframe >=6.1
hpack 4.0.0 → 4.1.0 h2 4.3 requires hpack >=4.1
fastapi 0.118 → 0.121 fastapi 0.118 caps starlette <0.49; 0.121 is the smallest version that allows starlette 0.49

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 MB patch in backend/main.py continues 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/ and backend/utils/retrieval/.

Test plan

For each commit:

  1. Update requirements.txt
  2. Rebuild local Dockerfile.test (Python 3.11-slim, requirements.txt minus the source-built lc3py) — only the pip install layer rebuilds
  3. Run a baseline-green subset of unit tests (190 tests across 11 files; same subset as backend: bump 10 Python deps for 1 CRITICAL + 16 HIGH CVEs #7126/backend: bump Python deps with major-version cascades for 7 HIGH CVEs #7127)
  4. Confirm bumped package version installed correctly

All 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

  • Re-scan rebuilt image; expect the listed CVEs to clear.
  • Smoke /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.

mdmohsin7 added 15 commits May 3, 2026 10:36
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.
@mdmohsin7 mdmohsin7 added backend Backend Task (python) python Security labels May 3, 2026
@mdmohsin7
Copy link
Copy Markdown
Member Author

@morpheus review — Approved

Single-file diff, 19 version pin changes in backend/requirements.txt. Same review checklist as #7126/#7127.

Verified:

  • All 15 headline bumps stay within same major version. No major crossings.
  • 4 cascade pins (cachetools, hyperframe, hpack, fastapi) each held to minimum version that resolves the constraint. Cascade logic confirmed against upstream dependency specs.
  • requests pin correctly uses ~=2.33.0 (compatible release, allows 2.33.x patches).
  • langsmith 0.4→0.7 is the biggest jump — pre-1.0, resolver kept langchain-core at 0.3.84 (no forced 1.x migration). Acceptable for 2 MEDIUM CVEs.
  • starlette 0.40→0.49 justified by HIGH CVE-2025-62727. MultiPartParser.max_part_size patch verified working in 0.49 per commit message.
  • langchain majors correctly deferred for separate API-migration PR.

15 atomic commits, one per package family, each independently revertable. Labels set (backend, python, Security). Clean.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 3, 2026

Greptile Summary

This PR bumps 15 Python packages in backend/requirements.txt to remediate 17 MEDIUM + 1 HIGH + 6 LOW CVEs flagged in the deployed Artifact Registry scan, with four cascade bumps driven by the new minimum requirements of the headline packages. No application code is changed. The MultiPartParser.max_part_size = 200 MB override already present in main.py (from #7127) continues to work in starlette 0.49.1 as verified by the author.

Confidence Score: 4/5

Safe 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

Filename Overview
backend/requirements.txt 15 targeted CVE-fix version bumps plus 4 cascade bumps; starlette is pinned to 0.49.1 while 0.49.3 (Middleware type fix) is already available

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"]
Loading

Reviews (1): Last reviewed commit: "Bump starlette + fastapi for HIGH CVE-20..." | Re-trigger Greptile

Comment thread backend/requirements.txt
stack-data==0.6.3
starlette==0.40.0
streamlit==1.51.0
starlette==0.49.1
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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.

Suggested change
starlette==0.49.1
starlette==0.49.3

Comment thread backend/requirements.txt
fal_client==0.4.1
fastapi==0.118.0
fastapi==0.121.0
fastapi-cli==0.0.5
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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.

Suggested change
fastapi-cli==0.0.5
fastapi-cli==0.0.7

@mdmohsin7 mdmohsin7 merged commit 8188dac into main May 3, 2026
3 checks passed
@mdmohsin7 mdmohsin7 deleted the charles/fix-backend-python-vulns-mediums branch May 3, 2026 12:31
mdmohsin7 added a commit that referenced this pull request May 3, 2026
## 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Backend Task (python) python Security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant