T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/zy_platform.py:894
- Finding
- Generic Request Route Allowlist Bypass Through Non-Canonical Paths<![CDATA[ ## Vulnerability Details **File Location**: `scripts/zy_platform.py:894-925` and `scripts/zy_platform.py:937-946` **Vulnerability Type**: Improper URL path canonicalization before authorization checks **Risk Level**: High ### Vulnerable Code ```python def _split_segments(path): p = path.split("?", 1)[0].split("#", 1)[0] return [seg for seg in p.split("/") if seg] def _passthrough_check(method, path): segs = _split_segments(path) if not segs: fail(1, "pass-through path is empty.") denied = [s for s in segs if s.lower() in DENY_SEGMENTS] if denied: fail(1, "security policy: the pass-through path contains sensitive/admin route segments ({}); refused.".format( ", ".join(denied))) if segs[0].lower() == "health": return families = {s.lower() for s in segs} if method in SAFE_METHODS: if not (families & READ_PASS_THROUGH_FAMILIES): fail(1, "security policy: the read-only pass-through path is not in the allowlist. Allowed families: {}.".format( ", ".join(sorted(READ_PASS_THROUGH_FAMILIES)))) else: if segs[0].lower() not in WRITE_PASS_THROUGH_FAMILIES: fail(1, "security policy: pass-through writes are only allowed in the {} families " "(e.g. chat, ontology/semantic-search); use built-in commands for other writes.".format( ", ".join(sorted(WRITE_PASS_THROUGH_FAMILIES)))) ``` ```python origin = parse_origin(args.base_url, product) path = args.path.strip().lstrip("/") if "|" in path or "\\" in path or re.search(r"[\x00-\x1f\x7f]", path): fail(1, "--path contains illegal characters.") if "#" in path: fail(1, "security policy: --path must not contain a fragment (#).") _passthrough_check(method, path) if path.startswith("health"): url = origin.server_root() + "/" + path else: url = origin.api_root() + "/" + path ``` ### Technical Analysis The pass-through authorization pol ...[truncated 2857 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Percent-decode the path exactly once before applying any route policy. 2. Reject paths that retain percent escapes after decoding when double-decoding by downstream systems cannot be ruled out. 3. Reject literal or encoded `.` and `..` segments rather than relying on downstream normalization. 4. Reject encoded path separators such as `%2f` and `%5c`, including case-insensitive variants. 5. Canonicalize the path before both policy evaluation and URL construction, ensuring that the exact same representation is checked and transmitted. 6. Require the canonical **first** segment to belong to the relevant allowlist. Do not approve a request merely because any later segment matches an allowed family. 7. Apply the sensitive-segment denylist to every canonical, decoded segment. 8. Safely quote canonical path segments when reconstructing the outgoing URL. 9. Add regression tests covering: - `%61uth` - `%2e%2e` - `%2f` and `%5c` - double-encoded values such as `%252e%252e` - mixed-case encodings - allowed names appearing only in later path segments 10. Continue enforcing authorization independently on the server. The client-side allowlist should provide defense in depth, not serve as the primary access-control boundary. ]]>
