T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/_logistics_api_runner.py:258
- Finding
- Generic ERP proxy exceeds the Skill's declared read-only scope<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/_shop_logistics_common.py:25` - `scripts/_shop_logistics_common.py:108-122` - `scripts/_logistics_api_runner.py:258-308` - `scripts/logistics_proxy.py:12-20` **Vulnerability Type**: Excessive API authorization scope and insufficient endpoint/method restrictions **Risk Level**: High ### Vulnerable Code ```python # scripts/_shop_logistics_common.py:25 ALLOWED_PATH_PREFIXES = ("logistics", "authorization") ``` ```python # scripts/_shop_logistics_common.py:108-122 def assert_path_allowed(path: str) -> None: normalized = path.lstrip("/").replace("\\", "/") if ".." in normalized or "//" in normalized: print(f"Error: invalid path {path!r}", file=sys.stderr) sys.exit(1) if not any( normalized == prefix or normalized.startswith(prefix + "/") for prefix in ALLOWED_PATH_PREFIXES ): print( f"Error: path must start with one of {ALLOWED_PATH_PREFIXES}, got {path!r}", file=sys.stderr, ) sys.exit(1) ``` ```python # scripts/_logistics_api_runner.py:258-308 def run_logistics_proxy(params: dict, caller: str = "logistics_proxy.py") -> dict: """Generic proxy: path + method + openId (+ optional shop_cipher).""" if not params.get("skipDepCheck"): ensure_auth_skill_available(caller) path = params.get("path") method = params.get("method") if not path or not method: print("Missing required fields: path, method", file=sys.stderr) sys.exit(1) open_id = require_open_id(params) shop_cipher = None needs_cipher = str(path).lstrip("/").startswith("logistics/") if needs_cipher: shop_cipher = resolve_shop_cipher(params, open_id) query_string = params.get("queryString") if shop_cipher: pairs = dict(parse_qsl(str(query_string or "").lstrip("?"), keep_blank_values=True)) pairs["shop_cipher"] = shop_cipher query_string = urlencode(pair ...[truncated 3981 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `logistics_proxy.py` if generic proxy functionality is not essential to the declared Skill. 2. Replace namespace-prefix validation with an exact endpoint and method allowlist: - `GET authorization/202309/shops` - `GET logistics/202309/warehouses` 3. Reject all request bodies for these two GET endpoints. 4. Reject unsupported query fields instead of forwarding arbitrary `queryString` values. 5. Validate methods before sending requests and permit only methods explicitly registered for each path. 6. Enforce the same endpoint/method allowlist at the LinkFox gateway so bypassing the local wrapper cannot grant additional access. 7. Separate any future state-changing APIs into independently reviewed capabilities with explicit user confirmation and narrowly scoped authorization. 8. Add automated negative tests proving that unregistered paths and `POST`, `PUT`, `PATCH`, and `DELETE` requests are rejected. ]]>
