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:
Classic298 2026-06-01 00:11:19 +02:00 • committed by GitHub
parent d4030a8aa5
commit 0354775917
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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