Starlette has Path Traversal vulnerability in StaticFiles
Summary
When using StaticFiles, if there's a file or directory that starts with the same name as the StaticFiles directory, that file or directory is also exposed via StaticFiles which is a path traversal vulnerability.
Details
The root cause of this issue is the usage of os.path.commonprefix():
https://github.com/encode/starlette/blob/4bab981d9e870f6cee1bd4cd59b87ddaf355b2dc/starlette/staticfiles.py#L172-L174
As stated in the Python documentation (https://docs.python.org/3/library/os.path.html#os.path.commonprefix) this function returns the longest prefix common to paths.
When passing a path like /static/../static1.txt, os.path.commonprefix([full_path, directory]) returns ./static which is the common part of ./static1.txt and ./static, It refers to /static/../static1.txt because it is considered in the staticfiles directory. As a result, it becomes possible to view files that should not be open to the public.
The solution is to use os.path.commonpath as the Python documentation explains that os.path.commonprefix works a character at a time, it does not treat the arguments as paths.
PoC
In order to reproduce the issue, you need to create the following structure:
├── static
│ ├── index.html
├── static_disallow
│ ├── index.html
└── static1.txt
And run the Starlette app with:
import uvicorn
from starlette.applications import Starlette
from starlette.routing import Mount
from starlette.staticfiles import StaticFiles
routes = [
Mount("/static", app=StaticFiles(directory="static", html=True), name="static"),
]
app = Starlette(routes=routes)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
And running the commands:
curl --path-as-is 'localhost:8000/static/../static_disallow/'
curl --path-as-is 'localhost:8000/static/../static1.txt'
The static1.txt and the directory static_disallow are exposed.
Impact
Confidentiality is breached: An attacker may obtain files that should not be open to the public.
Credits
Security researcher Masashi Yamane of LAC Co., Ltd reported this vulnerability to JPCERT/CC Vulnerability Coordination Group and they contacted us to coordinate a patch for the security issue.
Affected software
Click a technology to see all vulnerabilities affecting it.
| Platform | Package | Vulnerable versions | Fixed in |
|---|---|---|---|
| Python (PyPI) | starlette | >= 0.13.5, < 0.27.0 | 0.27.0 |
References
- https://github.com/encode/starlette/releases/tag/0.27.0
- https://jvn.jp/en/jp/JVN95981715/
- https://github.com/encode/starlette/security/advisories/GHSA-v5gw-mw7f-84px
- https://nvd.nist.gov/vuln/detail/CVE-2023-29159
- https://github.com/encode/starlette/commit/1797de464124b090f10cf570441e8292936d63e3
- https://github.com/encode/starlette
- https://github.com/encode/starlette/blob/4bab981d9e870f6cee1bd4cd59b87ddaf355b2dc/starlette/staticfiles.py#L172-L174
- https://github.com/pypa/advisory-database/tree/main/vulns/starlette/PYSEC-2023-83.yaml
- https://jvn.jp/en/jp/JVN95981715
- CVSS vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N- Weakness (CWE)
CWE-22- Platform
- Python (PyPI)
- Package
starlette- Disclosed
- 17.05.2023
- Updated
- 11.10.2026 13:19
Sources and licenses
OSV / GitHub Advisory Database - PYSEC-2023-83 - PyPA Advisory Database; CC BY 4.0
OSV / GitHub Advisory Database - GHSA-v5gw-mw7f-84px - CC BY 4.0
Vulnerability history: starlette
All published vulnerabilities of this package (Python (PyPI)), newest first. Shows whether this is a one-off slip or a package that needs watching.
- Total entries
- 10
- First → latest
- 02.2023 06.2026
- Without a fix
- 0
- Exploited in attacks
- 1
Severity breakdown
- High 5
- Medium 4
- Low 1
Disclosures per year
- 2023: 2
- 2024: 1
- 2025: 2
- 2026: 5
-
Starlette has Path Traversal vulnerability in StaticFiles this entry
Know which vulnerabilities affect your application
With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.