Your message dated Sat, 14 Mar 2026 11:48:36 +0000
with message-id <[email protected]>
and subject line Released with 13.4
has caused the Debian Bug report #1126926,
regarding trixie-pu: package starlette/0.46.1-3+deb13u1
to be marked as done.
This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.
(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)
--
1126926: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1126926
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:starlette
User: [email protected]
Usertags: pu
[ Reason ]
Fix CVE-2025-62727 [1], a denial of service vulnerability in
FileResponse triggered by crafted HTTP Range headers.
[ Impact ]
An attacker can exploit specially crafted Range headers to cause
excessive resource consumption, potentially leading
to service unavailability.
[ Tests ]
The upstream project added tests to validate the fix.
The package builds successfully and all build-time tests pass.
The proof of concept [2] provided for CVE-2025-62727 was
reproduced on the vulnerable version and is no longer
effective after applying the patch.
[ Risks ]
The change is limited in scope and only affects the handling of
HTTP Range headers in FileResponse.
[ Checklist ]
[x] *all* changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in (old)stable
[x] the issue is verified as fixed in unstable
[ Changes ]
Update the handling of HTTP Range headers in FileResponse to
properly parse and validate byte ranges, preventing
denial of service via crafted headers.
[ Other info ]
@tijuca has reviewed this backport and will sponsor it.
[1] https://security-tracker.debian.org/tracker/CVE-2025-62727
[2] https://github.com/Kludex/starlette/security/advisories/GHSA-7f5h-v6xp-fcq8
diff -Nru starlette-0.46.1/debian/changelog starlette-0.46.1/debian/changelog
--- starlette-0.46.1/debian/changelog 2025-07-28 09:42:53.000000000 +0000
+++ starlette-0.46.1/debian/changelog 2026-01-19 19:57:07.000000000 +0000
@@ -1,9 +1,19 @@
+starlette (0.46.1-3+deb13u1) trixie; urgency=medium
+
+ * Team upload.
+ * d/p/CVE-2025-62727.patch: Backport Upstream patch to fix CVE-2025-62727
+ (denial of service via crafted HTTP Range header in FileResponse)
+ * d/changelog: Fix changelog indentation
+ * d/gbp.conf: Update to Trixie
+
+ -- Matheus Polkorny <[email protected]> Mon, 19 Jan 2026 16:57:07 -0300
+
starlette (0.46.1-3) unstable; urgency=high
- [ Yang Wang ]
- * Fix CVE-2025-54121: Avoid event loop blocking during multipart file uploads
- by writing to disk using thread pool to prevent synchronous blocking when
- SpooledTemporaryFile rolls over to disk. (Closes: #1109805)
+ [ Yang Wang ]
+ * Fix CVE-2025-54121: Avoid event loop blocking during multipart file uploads
+ by writing to disk using thread pool to prevent synchronous blocking when
+ SpooledTemporaryFile rolls over to disk. (Closes: #1109805)
-- Piotr Ożarowski <[email protected]> Mon, 28 Jul 2025 11:42:53 +0200
diff -Nru starlette-0.46.1/debian/gbp.conf starlette-0.46.1/debian/gbp.conf
--- starlette-0.46.1/debian/gbp.conf 2025-07-28 09:40:03.000000000 +0000
+++ starlette-0.46.1/debian/gbp.conf 2026-01-19 19:57:07.000000000 +0000
@@ -1,3 +1,3 @@
[DEFAULT]
pristine-tar = True
-debian-branch = debian/master
+debian-branch = debian/trixie
diff -Nru starlette-0.46.1/debian/patches/CVE-2025-62727.patch
starlette-0.46.1/debian/patches/CVE-2025-62727.patch
--- starlette-0.46.1/debian/patches/CVE-2025-62727.patch 1970-01-01
00:00:00.000000000 +0000
+++ starlette-0.46.1/debian/patches/CVE-2025-62727.patch 2026-01-19
19:57:07.000000000 +0000
@@ -0,0 +1,135 @@
+From: Marcelo Trylesinski <[email protected]>
+Date: Tue, 28 Oct 2025 18:14:01 +0100
+Subject: Merge commit from fork
+
+Origin: upstream,
https://github.com/Kludex/starlette/commit/4ea6e22b489ec388d6004cfbca52dd5b147127c5
+No changes in the backport.
+---
+ starlette/responses.py | 46 ++++++++++++++++++++++++++++++++--------------
+ tests/test_responses.py | 28 ++++++++++++++++++++++++++++
+ 2 files changed, 60 insertions(+), 14 deletions(-)
+
+diff --git a/starlette/responses.py b/starlette/responses.py
+index 81e89fa..dbb087a 100644
+--- a/starlette/responses.py
++++ b/starlette/responses.py
+@@ -4,7 +4,6 @@ import hashlib
+ import http.cookies
+ import json
+ import os
+-import re
+ import stat
+ import typing
+ import warnings
+@@ -283,9 +282,6 @@ class RangeNotSatisfiable(Exception):
+ self.max_size = max_size
+
+
+-_RANGE_PATTERN = re.compile(r"(\d*)-(\d*)")
+-
+-
+ class FileResponse(Response):
+ chunk_size = 64 * 1024
+
+@@ -443,8 +439,8 @@ class FileResponse(Response):
+ def _should_use_range(self, http_if_range: str) -> bool:
+ return http_if_range == self.headers["last-modified"] or
http_if_range == self.headers["etag"]
+
+- @staticmethod
+- def _parse_range_header(http_range: str, file_size: int) ->
list[tuple[int, int]]:
++ @classmethod
++ def _parse_range_header(cls, http_range: str, file_size: int) ->
list[tuple[int, int]]:
+ ranges: list[tuple[int, int]] = []
+ try:
+ units, range_ = http_range.split("=", 1)
+@@ -456,14 +452,7 @@ class FileResponse(Response):
+ if units != "bytes":
+ raise MalformedRangeHeader("Only support bytes range")
+
+- ranges = [
+- (
+- int(_[0]) if _[0] else file_size - int(_[1]),
+- int(_[1]) + 1 if _[0] and _[1] and int(_[1]) < file_size else
file_size,
+- )
+- for _ in _RANGE_PATTERN.findall(range_)
+- if _ != ("", "")
+- ]
++ ranges = cls._parse_ranges(range_, file_size)
+
+ if len(ranges) == 0:
+ raise MalformedRangeHeader("Range header: range must be
requested")
+@@ -495,6 +484,35 @@ class FileResponse(Response):
+
+ return result
+
++ @classmethod
++ def _parse_ranges(cls, range_: str, file_size: int) -> list[tuple[int,
int]]:
++ ranges: list[tuple[int, int]] = []
++
++ for part in range_.split(","):
++ part = part.strip()
++
++ # If the range is empty or a single dash, we ignore it.
++ if not part or part == "-":
++ continue
++
++ # If the range is not in the format "start-end", we ignore it.
++ if "-" not in part:
++ continue
++
++ start_str, end_str = part.split("-", 1)
++ start_str = start_str.strip()
++ end_str = end_str.strip()
++
++ try:
++ start = int(start_str) if start_str else file_size -
int(end_str)
++ end = int(end_str) + 1 if start_str and end_str and
int(end_str) < file_size else file_size
++ ranges.append((start, end))
++ except ValueError:
++ # If the range is not numeric, we ignore it.
++ continue
++
++ return ranges
++
+ def generate_multipart(
+ self,
+ ranges: typing.Sequence[tuple[int, int]],
+diff --git a/tests/test_responses.py b/tests/test_responses.py
+index 0a00e93..fad0b4b 100644
+--- a/tests/test_responses.py
++++ b/tests/test_responses.py
+@@ -746,6 +746,34 @@ def
test_file_response_insert_ranges(file_response_client: TestClient) -> None:
+ ]
+
+
++def test_file_response_range_without_dash(file_response_client: TestClient)
-> None:
++ response = file_response_client.get("/", headers={"Range": "bytes=100,
0-50"})
++ assert response.status_code == 206
++ assert response.headers["content-range"] == f"bytes
0-50/{len(README.encode('utf8'))}"
++
++
++def test_file_response_range_empty_start_and_end(file_response_client:
TestClient) -> None:
++ response = file_response_client.get("/", headers={"Range": "bytes= - ,
0-50"})
++ assert response.status_code == 206
++ assert response.headers["content-range"] == f"bytes
0-50/{len(README.encode('utf8'))}"
++
++
++def test_file_response_range_ignore_non_numeric(file_response_client:
TestClient) -> None:
++ response = file_response_client.get("/", headers={"Range":
"bytes=abc-def, 0-50"})
++ assert response.status_code == 206
++ assert response.headers["content-range"] == f"bytes
0-50/{len(README.encode('utf8'))}"
++
++
++def test_file_response_suffix_range(file_response_client: TestClient) -> None:
++ # Test suffix range (last N bytes) - line 523 with empty start_str
++ response = file_response_client.get("/", headers={"Range": "bytes=-100"})
++ assert response.status_code == 206
++ file_size = len(README.encode("utf8"))
++ assert response.headers["content-range"] == f"bytes {file_size -
100}-{file_size - 1}/{file_size}"
++ assert response.headers["content-length"] == "100"
++ assert response.content == README.encode("utf8")[-100:]
++
++
+ @pytest.mark.anyio
+ async def test_file_response_multi_small_chunk_size(readme_file: Path) ->
None:
+ class SmallChunkSizeFileResponse(FileResponse):
diff -Nru starlette-0.46.1/debian/patches/series
starlette-0.46.1/debian/patches/series
--- starlette-0.46.1/debian/patches/series 2025-07-28 09:42:53.000000000
+0000
+++ starlette-0.46.1/debian/patches/series 2026-01-19 19:57:07.000000000
+0000
@@ -1,2 +1,3 @@
json-format.patch
0002-fix-cve-2024-28849-async-write.patch
+CVE-2025-62727.patch
--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 13.4
This update has been released as part of Debian 13.4.
--- End Message ---