T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/_fulfillment_api_runner.py:259- Finding
Generic fulfillment proxy permits operations beyond the Skill's read-only purpose
- Content
View full analysis
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("fulfillment/") 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(pairs) body = params.get("body") if body is not None and not isinstance(body, str): body = json.dumps(body, ensure_ascii=False, separators=(",", ":")) if "requestBody" in params and body is None: rb = params["requestBody"] body = rb if isinstance(rb, str) else json.dumps(rb, ensure_ascii=False, separators=(",", ":")) proxy = developer_proxy_call( open_id, str(path), str(method).upper(), region=params.get("region"), query_string=query_string, body=body, content_type=str(params.get("contentType") or "application/json"), ) ``` The applicable path validation is: ```python def assert_path_allowed(path: str) -> None: normalized = path.lstrip("/").replace("\\", "/") if ".." in normalized or "//" in normali ...[truncated 3436 chars]- Remediation
View remediation
