fix: reject backslash in the terminal proxy path sanitizer (#27198)

_sanitize_proxy_path decodes the path and then relies on posixpath.normpath plus a leading '..' check. posixpath splits on '/' only, so a backslash run is treated as part of a single path component: 'foo/..\..\etc' normalizes to itself, does not start with '..' and is forwarded unchanged, reaching the upstream as '/foo/..%5C..%5Cetc'. An upstream that treats the backslash as a separator would resolve those '..' sequences.

Reject any path containing a backslash after decoding, matching the existing fail-closed behaviour for paths that are still encoded past the decode cap. A backslash is not meaningful in the upstream API paths this route proxies, so legitimate requests are unaffected.

Co-authored-by: babakizo420 <babakizo420@users.noreply.github.com>
This commit is contained in:
Classic298
2026-07-27 07:01:10 +02:00
committed by GitHub
parent e30ed01b05
commit b40b6fd698
+4
View File
@@ -49,6 +49,10 @@ def _sanitize_proxy_path(path: str) -> str | None:
# Fail closed: still encoded after the cap means the upstream would decode further into traversal.
if unquote(decoded) != decoded:
return None
# posixpath splits on '/' only, so 'a/..\..\b' survives normpath as one component.
# Upstreams that treat '\' as a separator would resolve it, so reject outright.
if '\\' in decoded:
return None
had_trailing_slash = decoded.endswith('/')
normalized = posixpath.normpath(decoded)
# Remove any leading slashes that would reset the base