fix: decode terminal proxy path until stable to block multi-encoded traversal (#25157)
_sanitize_proxy_path decoded the proxy path once before the '..' check, so a double-encoded payload (%252e%252e) survived the check as %2e%2e and was then re-decoded into '..' by the upstream terminal server, defeating the traversal guard. Decode until stable so no encoded traversal sequence can reach the upstream. Single-encoded payloads were already rejected; this closes the double (and deeper) encoding bypass. Co-authored-by: sermikr0 <230672901+sermikr0@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
sermikr0
Claude Opus 4.7
parent
d4030a8aa5
commit
0354775917
@@ -35,7 +35,14 @@ def _sanitize_proxy_path(path: str) -> str | None:
|
||||
Trailing slashes are preserved — many upstream frameworks treat
|
||||
``/path`` and ``/path/`` differently.
|
||||
"""
|
||||
decoded = unquote(path)
|
||||
# Decode until stable: a single unquote pass leaves %252e%252e as %2e%2e,
|
||||
# which the upstream then re-decodes into '..', bypassing the check below.
|
||||
decoded = path
|
||||
for _ in range(8):
|
||||
once = unquote(decoded)
|
||||
if once == decoded:
|
||||
break
|
||||
decoded = once
|
||||
had_trailing_slash = decoded.endswith('/')
|
||||
normalized = posixpath.normpath(decoded)
|
||||
# Remove any leading slashes that would reset the base
|
||||
|
||||
Reference in New Issue
Block a user