{"record":{"id":"d27ed67ce913537b","repo":"iflytek/astron-agent","slug":"tool-path-parameter-is-unsafe","errorCode":null,"errorMessage":"Tool path parameter is unsafe","messagePattern":"Tool path parameter is unsafe","errorType":"exception","errorClass":"OutboundPolicyError","httpStatus":null,"severity":"error","filePath":"core/plugin/link/infra/tool_exector/process.py","lineNumber":131,"sourceCode":"        url = self.server\n\n        # Substitute OpenAPI path parameters as individual path segments. urljoin is unsafe here:\n        # an absolute value, a scheme-relative value, or a dot segment can replace/escape the\n        # persisted endpoint path.\n        for name, value in self.path.items():\n            placeholder = \"{\" + str(name) + \"}\"\n            if placeholder not in url:\n                raise OutboundPolicyError(\n                    f\"Tool path parameter has no matching placeholder: {name}\"\n                )\n            raw_value = str(value)\n            if (\n                raw_value in {\".\", \"..\"}\n                or \"/\" in raw_value\n                or \"\\\\\" in raw_value\n                or any(ord(character) < 0x20 for character in raw_value)\n            ):\n                raise OutboundPolicyError(\"Tool path parameter is unsafe\")\n            url = url.replace(placeholder, quote(raw_value, safe=\"\"))\n\n        if _PATH_PARAMETER_PATTERN.search(url):\n            raise OutboundPolicyError(\"Tool URL has unresolved path parameters\")\n\n        # Authentication method selection and URL construction\n        if self._is_authorization_md5:\n            url = public_query_url(url)\n            if self.query:\n                url = url + \"&\" + \"&\".join([f\"{k}={v}\" for k, v in self.query.items()])\n        elif self._is_auth_hmac:\n            url, headers = assemble_ws_auth_url(\n                url, self.method, self.auth_con_js, self.body\n            )\n            self.header = headers\n        else:\n            if self.query:\n                url = url + \"?\" + \"&\".join([f\"{k}={v}\" for k, v in self.query.items()])","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/plugin/link/infra/tool_exector/process.py#L113-L149","documentation":"Path parameter values that could escape the endpoint path are rejected before substitution. Values equal to '.' or '..', containing '/' or '\\\\', or containing control characters (< 0x20) would allow path traversal or URL structure manipulation, so the library raises OutboundPolicyError('Tool path parameter is unsafe') and fails the request closed.","triggerScenarios":"do_call → _build_url with a path parameter whose string value is '.', '..', contains a forward slash or backslash (e.g. '../admin', 'a/b', 'C:\\\\temp'), or includes control characters such as newline or tab.","commonSituations":"User-controlled input passed straight into a tool path parameter without sanitization; values pulled from file paths or Windows paths; injection attempts in chat-driven tool calls.","solutions":["Sanitize or split the value at the caller: pass only the path segment (e.g. the file name or ID), not a full path","If the value legitimately contains slashes, encode it beforehand as a single identifier (e.g. base64 or URL-safe encoding) and decode server-side","Validate parameter values against an allow-list pattern before invoking the tool"],"exampleFix":"// before\npath = {\"name\": \"../../etc/passwd\"}\n// after\npath = {\"name\": quote(os.path.basename(user_input), safe=\"\")}","handlingStrategy":"validation","validationCode":"def is_safe_path_segment(value):\n    v = str(value)\n    return bool(v) and v not in ('.', '..') and '/' not in v and '\\\\' not in v and all(ord(c) >= 0x20 for c in v)","typeGuard":null,"tryCatchPattern":"try:\n    result = await run.do_call(span)\nexcept CallThirdApiException as e:\n    if 'path parameter is unsafe' in str(e.err):\n        raise InvalidUserInput('path parameter rejected') from e\n    raise","preventionTips":["Sanitize user input before binding it to path parameters","Pass IDs/names, never raw file-system paths","Encode multi-segment values (e.g. base64) when slashes are inherent"],"tags":["security","path-traversal","openapi"],"backgroundTag":"path-traversal-blocked","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}