Require starlette>=1.0.1 for Host header parsing fix#67326
Open
potiuk wants to merge 3 commits into
Open
Conversation
Starlette 1.0.1 carries a Host-header parsing fix (Kludex/starlette#3279): when the `Host` header contains characters that are invalid per RFC 9110 §7.2 (`/`, `?`, `#`, `@`, `\`, spaces, ...), the URL string Starlette builds before calling `urlsplit` would push parts of `scope["path"]` into the netloc / query / fragment, leaving `request.url.path` disagreeing with the ASGI `scope["path"]` that downstream apps and `StaticFiles` actually serve. Airflow has two places that authorise off `request.url.path` and dispatch off `scope["path"]`: - `airflow-core/src/airflow/utils/serve_logs/log_server.py` — `JWTAuthStaticFiles.validate_jwt_token` compares `request.url.path` against the JWT's `filename` claim; the `StaticFiles` superclass then serves the file at `scope["path"]`. A malformed `Host` header makes those two disagree, letting a holder of any valid log-read token read any other task log on the same worker. - `providers/edge3/src/airflow/providers/edge3/worker_api/auth.py` — `jwt_token_authorization_rest` derives the called "method" from `request.url.path` while FastAPI routes by `scope["path"]`. Same shape of bypass on the Edge3 worker control plane. Bumping the floor to 1.0.1 closes both. A matching `[tool.uv.exclude-newer-package]` override is added so the security floor can be resolved before 1.0.1 ages past the project's global 4-day cooldown — the next commit teaches `upgrade_important_versions.py` to retire that override automatically once the cooldown catches up.
… script `upgrade_important_versions.py` enforced its own 4-day PyPI cooldown (`COOLDOWN_DAYS = 4`), which mirrored the root pyproject.toml's global `exclude-newer = "4 days"`. When a per-package override was added under `[tool.uv.exclude-newer-package]` (e.g. `uv = "12 hours"`) to let a freshly-published release through the global window, the script kept applying its broader cooldown and would pick a stale version that disagreed with what `uv lock` would resolve against pyproject.toml. This change makes the script: 1. Parse manual override blocks (the lines after the "# End of automatically generated …" sentinels under `[tool.uv.exclude-newer-package]` and `[tool.uv.pip.exclude-newer-package]`) and use any duration-shaped override as the per-package cooldown when checking PyPI. 2. Sweep up overrides whose target package is already older than the global 4-day window — the entry, plus its `# REMOVE BY …` markers, are removed from pyproject.toml so the workaround retires itself without anyone having to remember the calendar date in the comment. The "Manual overrides" header and broader context comments are left in place on purpose — the diff makes them obviously orphaned for a reviewer to prune in the same PR, but the script doesn't try to guess which surrounding lines belonged to which entry.
jscheffl
approved these changes
May 23, 2026
bugraoz93
approved these changes
May 23, 2026
1 task
Contributor
|
Quickest fix: git fetch upstream main && git rebase upstream/main
rm uv.lock && uv lock
git add uv.lock && git rebase --continue
git push --force-with-leaseAutomated nudge — ignore if you're not ready to rebase. This comment is updated in place on future |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
starlettefloor inairflow-core/pyproject.tomlfrom>=0.45.0to>=1.0.1to pick up the Host-header parsing fix inKludex/starlette#3279.
[tool.uv.exclude-newer-package]override(
starlette = "6 hours") so the bump can resolve before 1.0.1ages past the project's global 4-day cooldown.
scripts/ci/prek/upgrade_important_versions.pyto honourmanual cooldown overrides when checking PyPI and to retire those
overrides automatically once the global window catches up, so each
workaround line — and its
# REMOVE BY …marker — clean themselvesout without anyone watching the calendar.
Why this matters for Airflow
The upstream PR closes a case where
request.url.pathcould divergefrom the ASGI
scope["path"]when theHostheader containscharacters that are invalid per RFC 9110 §7.2 (
/,?,#,@,\, space). Airflow has authorisation paths that compare againstrequest.url.pathwhile the downstream app serves the file atscope["path"]:airflow-core/src/airflow/utils/serve_logs/log_server.py(
JWTAuthStaticFiles)providers/edge3/src/airflow/providers/edge3/worker_api/auth.py(
jwt_token_authorization_rest)Bumping the floor closes the underlying divergence. Defence-in-depth
follow-ups (comparing
scope["path"]directly instead ofrequest.url.path) can come in a separate PR.Test plan
uv run --project scripts pytest scripts/tests/ci/prek/test_upgrade_important_versions.py— 19 passed (5 existing + 14 new covering_parse_duration_hours,_parse_manual_overrides,_remove_override_entry, and the per-package cooldown branch).prek run --files …on every touched file — all hooks pass (ruff, ruff-format, mypy-scripts, license headers, codespell, uv.lock sync, …).uv lockresolvesstarlette==1.0.1once the per-package override is in place; verified by diffinguv.lock.Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Opus 4.7) following the guidelines
Drafted-by: Claude Code (Opus 4.7); reviewed by @potiuk before posting