Skip to content

Move to Starlette 1.3.1 and pin it explicitly - #15

Merged
dabeckham merged 1 commit into
chore/dependency-security-updatesfrom
chore/starlette-1x-upgrade
Jul 26, 2026
Merged

Move to Starlette 1.3.1 and pin it explicitly#15
dabeckham merged 1 commit into
chore/dependency-security-updatesfrom
chore/starlette-1x-upgrade

Conversation

@dabeckham

Copy link
Copy Markdown
Owner

Stacked on #14 — this PR targets chore/dependency-security-updates and will
retarget to main automatically once that merges.

What

Starlette isn't listed in requirements.txt, so the version that actually ships
is whatever FastAPI's range resolves to. In the running image that is 0.41.3,
which carries seven advisories. Clearing all of them needs 1.3.1, which in
turn needs FastAPI 0.140.0 to allow the 1.x range. Starlette is now pinned
explicitly so it stops being invisible.

Reachability

Two of the seven are reachable without authenticating:

Advisory Severity Why it applies here
CVE-2025-62727 HIGH Quadratic-time Range header merging in FileResponse. Every share download is served by FileResponse (app/main.py), so anyone holding a link can drive it.
CVE-2026-54283 HIGH Form-body limits silently ignored for application/x-www-form-urlencoded. FastAPI parses the body during dependency resolution, i.e. before the handler's own authorization check runs.

The remainder — Host-header handling that can poison request.url
(CVE-2026-48710, CVE-2026-54282), arbitrary methods dispatched to HTTPEndpoint
attributes (CVE-2026-48817), UNC paths in StaticFiles on Windows
(CVE-2026-48818) — are lower risk in this deployment but land in the same
upgrade.

Code changes this forced

Starlette 1.0 removed the deprecated TemplateResponse(name, context)
signature. Rather than repeat the new three-argument form at all seven call
sites, they now go through a render() helper that merges the shared base
context, plus an error_page() wrapper for the three error renders. The context
no longer carries request explicitly — Starlette injects it.

Net effect on app/main.py is a small reduction in line count.

Verification

  • Backend suite: 26 tests pass (real PostgreSQL), including a new regression
    test that a request arriving with an unexpected Host still lands on the
    canonical origin — Host parsing is one of the things that changed underneath.
  • Browser end-to-end suite: 4 tests pass against a staging container built
    from this branch.
  • Live identity-provider check: the app still builds a valid authorization
    request and Authentik accepts it and hands off to its login flow.
  • Still not exercised: the post-login callback. That needs an interactive
    sign-in after deploy.

Starlette is not listed in requirements.txt, so the version that actually
ships is whatever FastAPI's range resolves to — 0.41.3 in the current image.
Seven advisories apply to it, and two are reachable from unauthenticated
requests:

- CVE-2025-62727: quadratic-time Range-header merging in FileResponse. Every
  share download is served by FileResponse, so anyone holding a link can drive
  it.
- CVE-2026-54283: form-body limits silently ignored for
  application/x-www-form-urlencoded. FastAPI parses the body before the
  handler runs, so the form endpoints are reachable before their own
  authorization checks are reached.

The rest (Host-header handling that can poison request.url, arbitrary methods
dispatched to HTTPEndpoint attributes, UNC paths in StaticFiles on Windows)
are lower risk here but land in the same upgrade. Clearing all of them
requires 1.3.1, which needs FastAPI 0.140.0 to allow the 1.x range.

Starlette 1.0 removed the deprecated TemplateResponse(name, context)
signature, so the seven call sites move to the current
TemplateResponse(request, name, context) form. Rather than repeat that at
every site, they now go through a render() helper that merges the shared base
context, plus an error_page() wrapper for the three error renders. Context no
longer carries "request" explicitly; Starlette injects it.

Added a regression test asserting that a request arriving with an unexpected
Host still lands on the canonical origin, since Host parsing is one of the
things that changed underneath.

Verified with the backend suite (26 tests) and the browser end-to-end suite
against a staging container built from this branch, plus the same live
Authentik authorization-request check as the previous dependency update.
@dabeckham
dabeckham merged commit 7b23fb1 into chore/dependency-security-updates Jul 26, 2026
2 checks passed
@dabeckham
dabeckham deleted the chore/starlette-1x-upgrade branch July 26, 2026 21:37
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