{"record":{"id":"4586f878b8db52b9","repo":"iflytek/astron-agent","slug":"only-http-and-https-remote-resources-are-allowed","errorCode":null,"errorMessage":"Only HTTP and HTTPS remote resources are allowed","messagePattern":"Only HTTP and HTTPS remote resources are allowed","errorType":"exception","errorClass":"RemoteResourcePolicyError","httpStatus":null,"severity":"error","filePath":"core/plugin/aitools/common/clients/safe_download.py","lineNumber":209,"sourceCode":"    except (TypeError, ValueError) as exc:\n        raise RemoteResourcePolicyError(\"Remote resource URL is malformed\") from exc\n    _validate_parsed_resource_url(parsed, port)\n    return parsed\n\n\ndef _validate_url_characters(url: str) -> None:\n    if not isinstance(url, str) or any(\n        ord(character) < 0x20 or ord(character) == 0x7F for character in url\n    ):\n        raise RemoteResourcePolicyError(\"Remote resource URL is malformed\")\n\n\ndef _validate_parsed_resource_url(\n    parsed: SplitResult,\n    port: Optional[int],\n) -> 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","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/plugin/aitools/common/clients/safe_download.py#L191-L227","documentation":"_validate_parsed_resource_url only permits http and https schemes (_ALLOWED_SCHEMES). Any other scheme — ftp, file, data, gopher, jar, ws, etc. — is rejected with 'Only HTTP and HTTPS remote resources are allowed'. This blocks non-HTTP protocols that enable local-file reads or exotic SSRF vectors.","triggerScenarios":"Passing 'file:///etc/passwd', 'ftp://...', 'data:text/html,...', 'gopher://...' or an empty/missing scheme ('example.com/file') to fetch_public_resource.","commonSituations":"Trying to download local files through the downloader; frontend sending scheme-less URLs assuming the server will add https://; internal tooling that traditionally uses ftp mirrors; mixed-case schemes are fine (checked lowercased), but typos like 'hthps' are not.","solutions":["Use an https:// (or http://) URL; re-host the file on an HTTP server if it currently lives on ftp or local disk.","If the caller may omit the scheme, normalize it first: prepend 'https://' when '://' is absent.","Check for typos in the scheme string."],"exampleFix":"// before\nawait fetch_public_resource(\"ftp://files.example.com/report.pdf\")\n// after\nawait fetch_public_resource(\"https://files.example.com/report.pdf\")","handlingStrategy":"validation","validationCode":"from urllib.parse import urlsplit\nassert urlsplit(url).scheme.lower() in (\"http\", \"https\")","typeGuard":"def is_http_url(u):\n    try:\n        return urlsplit(u).scheme.lower() in (\"http\", \"https\")\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":"try:\n    data = await fetch_public_resource(url)\nexcept HTTPClientException as e:\n    if \"HTTP and HTTPS\" in str(e):\n        ...  # normalize or reject non-http(s) inputs","preventionTips":["Default to https:// when the scheme is missing","Whitelist http/https in your own input validation","Re-host ftp/local files behind an HTTP endpoint"],"tags":["url","validation","security","ssrf","scheme"],"backgroundTag":"invalid-url","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"}