{"record":{"id":"540d5837b948289d","repo":"iflytek/astron-agent","slug":"remote-resource-url-port-is-invalid","errorCode":null,"errorMessage":"Remote resource URL port is invalid","messagePattern":"Remote resource URL port is invalid","errorType":"exception","errorClass":"RemoteResourcePolicyError","httpStatus":null,"severity":"error","filePath":"core/plugin/aitools/common/clients/safe_download.py","lineNumber":225,"sourceCode":") -> None:\n    if parsed.scheme.lower() not in _ALLOWED_SCHEMES:\n        raise RemoteResourcePolicyError(\n            \"Only HTTP and HTTPS remote resources are allowed\"\n        )\n    if not parsed.hostname:\n        raise RemoteResourcePolicyError(\"Remote resource URL must include a hostname\")\n    if parsed.username is not None or parsed.password is not None:\n        raise RemoteResourcePolicyError(\n            \"Remote resource URL must not include user information\"\n        )\n    if \"\\\\\" in parsed.netloc:\n        raise RemoteResourcePolicyError(\"Remote resource URL authority is invalid\")\n    if parsed.fragment:\n        raise RemoteResourcePolicyError(\n            \"Remote resource URL must not include a fragment\"\n        )\n    if port is not None and not 1 <= port <= 65535:\n        raise RemoteResourcePolicyError(\"Remote resource URL port is invalid\")\n\n\ndef _normalize_hostname(hostname: str) -> str:\n    value = hostname.strip().lower().rstrip(\".\")\n    if _parse_ip(value) is not None:\n        return value\n    try:\n        normalized = URL.build(scheme=\"http\", host=value).raw_host\n    except (TypeError, ValueError, UnicodeError) as exc:\n        raise RemoteResourcePolicyError(\"Remote resource hostname is invalid\") from exc\n    if not normalized:\n        raise RemoteResourcePolicyError(\"Remote resource hostname is invalid\")\n    return normalized.rstrip(\".\")\n\n\ndef _parse_ip(value: str) -> Optional[IpAddress]:\n    try:\n        return ipaddress.ip_address(value)","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/plugin/aitools/common/clients/safe_download.py#L207-L243","documentation":"RemoteResourcePolicyError raised when the URL specifies a port outside the valid 1-65535 range. Note that urlsplit().port itself raises on out-of-range/undecodable ports; this explicit check in _validate_parsed_resource_url is a defense-in-depth guard for the parsed port value reaching the validator with an invalid value.","triggerScenarios":"Calling fetch_public_resource with a URL containing a port like ':0' or ':70000' that survived parsing, or an integer-cast port variable interpolated into the URL that is out of range.","commonSituations":"Configuration or code that computes a port (e.g. defaulting to 0 when unset) and formats it into the URL; hand-built URLs in tests or scripts with placeholder ports; misconfigured proxy ports in environment settings.","solutions":["Fix the URL to use a valid port (1-65535) or omit the port to use the scheme default (80/443)","Check the code/config that generates the port; ensure missing ports default to scheme defaults instead of 0","Validate the port with 1 <= port <= 65535 before building the URL"],"exampleFix":"// before\nport = int(os.getenv(\"DOWNLOAD_PORT\", \"0\"))\nurl = f\"https://cdn.example.com:{port}/file\"\n// after\nport = int(os.getenv(\"DOWNLOAD_PORT\", \"443\"))\nif not 1 <= port <= 65535:\n    raise ValueError(f\"invalid port {port}\")\nurl = f\"https://cdn.example.com:{port}/file\" if port != 443 else \"https://cdn.example.com/file\"","handlingStrategy":"validation","validationCode":"def has_valid_port(url: str) -> bool:\n    from urllib.parse import urlsplit\n    try:\n        port = urlsplit(url).port\n    except ValueError:\n        return False\n    return port is None or 1 <= port <= 65535","typeGuard":null,"tryCatchPattern":"try:\n    data = await fetch_public_resource(url)\nexcept RemoteResourcePolicyError as e:\n    if \"port is invalid\" in str(e):\n        raise ValueError(f\"configured download port in '{url}' is out of range\") from e\n    raise","preventionTips":["Validate generated ports (1-65535) before formatting them into URLs","Default missing ports to scheme defaults (80/443) rather than 0","Prefer omitting the port for standard schemes"],"tags":["url-validation","ssrf","port","python"],"backgroundTag":"value-out-of-range","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}