{"id":"CVE-2025-54121","aliases":["GHSA-2c2j-9gv5-cj73","PYSEC-2026-1941"],"url":"https://o3.security/vulnerability/CVE-2025-54121","summary":"Starlette has possible denial-of-service vector when parsing large files in multipart forms","details":"### Summary\nWhen parsing a multi-part form with large files (greater than the [default max spool size](https://github.com/encode/starlette/blob/fa5355442753f794965ae1af0f87f9fec1b9a3de/starlette/formparsers.py#L126)) `starlette` will block the main thread to roll the file over to disk. This blocks the event thread which means we can't accept new connections.\n\n### Details\nPlease see this discussion for details: https://github.com/encode/starlette/discussions/2927#discussioncomment-13721403. In summary the following UploadFile code (copied from [here](https://github.com/encode/starlette/blob/fa5355442753f794965ae1af0f87f9fec1b9a3de/starlette/datastructures.py#L436C5-L447C14)) has a minor bug. Instead of just checking for `self._in_memory` we should also check if the additional bytes will cause a rollover.\n\n```python\n\n    @property\n    def _in_memory(self) -> bool:\n        # check for SpooledTemporaryFile._rolled\n        rolled_to_disk = getattr(self.file, \"_rolled\", True)\n        return not rolled_to_disk\n\n    async def write(self, data: bytes) -> None:\n        if self.size is not None:\n            self.size += len(data)\n\n        if self._in_memory:\n            self.file.write(data)\n        else:\n            await run_in_threadpool(self.file.write, data)\n```\n\nI have already created a PR which fixes the problem: https://github.com/encode/starlette/pull/2962\n\n\n### PoC\nSee the discussion [here](https://github.com/encode/starlette/discussions/2927#discussioncomment-13721403) for steps on how to reproduce.\n\n### Impact\nTo be honest, very low and not many users will be impacted. Parsing large forms is already CPU intensive so the additional IO block doesn't slow down `starlette` that much on systems with modern HDDs/SSDs. If someone is running on tape they might see a greater impact.","published":"2025-07-21T20:06:03.818Z","modified":"2026-10-28T02:30:56.952315950Z","cvss":{"score":5.3,"severity":"MEDIUM","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"},"epss":{"score":0.0053,"percentile":0.41924,"asOf":"2026-08-09"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"PyPI","name":"starlette","fixedVersion":"0.47.2"}],"fix":{"url":"https://github.com/encode/starlette/commit/9f7ec2eb512fcc3fe90b43cb9dd9e1d08696bec1","label":"encode/starlette@9f7ec2e"},"references":[{"type":"WEB","url":"https://github.com/encode/starlette/blob/fa5355442753f794965ae1af0f87f9fec1b9a3de/starlette/datastructures.py#L436C5-L447C14"},{"type":"WEB","url":"https://github.com/encode/starlette/discussions/2927#discussioncomment-13721403"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2025/54xxx/CVE-2025-54121.json"},{"type":"ADVISORY","url":"https://github.com/encode/starlette/security/advisories/GHSA-2c2j-9gv5-cj73"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-54121"},{"type":"FIX","url":"https://github.com/encode/starlette/commit/9f7ec2eb512fcc3fe90b43cb9dd9e1d08696bec1"},{"type":"PACKAGE","url":"https://github.com/encode/starlette"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-10-28T02:30:56.952315950Z"}}