Skip to content

Commit 0354775

Browse files
Classic298sermikr0claude
authored
fix: decode terminal proxy path until stable to block multi-encoded traversal (open-webui#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>
1 parent d4030a8 commit 0354775

1 file changed

Lines changed: 8 additions & 1 deletion

File tree

backend/open_webui/routers/terminals.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,14 @@ def _sanitize_proxy_path(path: str) -> str | None:
3535
Trailing slashes are preserved — many upstream frameworks treat
3636
``/path`` and ``/path/`` differently.
3737
"""
38-
decoded = unquote(path)
38+
# Decode until stable: a single unquote pass leaves %252e%252e as %2e%2e,
39+
# which the upstream then re-decodes into '..', bypassing the check below.
40+
decoded = path
41+
for _ in range(8):
42+
once = unquote(decoded)
43+
if once == decoded:
44+
break
45+
decoded = once
3946
had_trailing_slash = decoded.endswith('/')
4047
normalized = posixpath.normpath(decoded)
4148
# Remove any leading slashes that would reset the base

0 commit comments

Comments
 (0)