iflytek/astron-agent · error · RemoteResourcePolicyError

Remote resource URL must not include user information

Error message

Remote resource URL must not include user information

What it means

_validate_parsed_resource_url rejects URLs containing userinfo (user:password@host). Embedding credentials in the URL is both a credential-leak risk (logged, proxied) and a parser-differential SSRF vector (browsers and servers may disagree on where the host begins), so the library refuses such URLs.

Solutions

  1. Remove credentials from the URL; authenticate via presigned query parameters or headers instead.
  2. Use a public, unauthenticated URL for the resource.
  3. If the upstream requires basic auth, fetch it yourself with an authenticated aiohttp/httpx call rather than this SSRF-guarded downloader.

Example fix

// before
await fetch_public_resource("https://user:pass@files.example.com/report.pdf")
// after
await fetch_public_resource("https://files.example.com/signed/report.pdf?token=...")
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlsplit
p = urlsplit(url)
assert p.username is None and p.password is None, "strip credentials from URL"

Type guard

def is_credential_free(u):
    try:
        p = urlsplit(u)
        return p.username is None and p.password is None
    except (TypeError, ValueError):
        return False

Try / catch

try:
    data = await fetch_public_resource(url)
except HTTPClientException as e:
    if "user information" in str(e):
        ...  # strip credentials, use presigned URL instead

Prevention

When it happens

Trigger: URL like 'https://user:pass@files.example.com/file' or 'http://admin@host/x' — parsed.username or parsed.password is not None.

Common situations: Old-style basic-auth-in-URL object storage links; copy-pasted URLs from tools that embed tokens in the authority; attempts to smuggle a different host via 'https://evil.com\@good.com/' style payloads.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/006429e8ad875516. Report an issue: GitHub.

Appendix: source

Thrown at core/plugin/aitools/common/clients/safe_download.py:215

def _validate_url_characters(url: str) -> None:
    if not isinstance(url, str) or any(
        ord(character) < 0x20 or ord(character) == 0x7F for character in url
    ):
        raise RemoteResourcePolicyError("Remote resource URL is malformed")


def _validate_parsed_resource_url(
    parsed: SplitResult,
    port: Optional[int],
) -> None:
    if parsed.scheme.lower() not in _ALLOWED_SCHEMES:
        raise RemoteResourcePolicyError(
            "Only HTTP and HTTPS remote resources are allowed"
        )
    if not parsed.hostname:
        raise RemoteResourcePolicyError("Remote resource URL must include a hostname")
    if parsed.username is not None or parsed.password is not None:
        raise RemoteResourcePolicyError(
            "Remote resource URL must not include user information"
        )
    if "\\" in parsed.netloc:
        raise RemoteResourcePolicyError("Remote resource URL authority is invalid")
    if parsed.fragment:
        raise RemoteResourcePolicyError(
            "Remote resource URL must not include a fragment"
        )
    if port is not None and not 1 <= port <= 65535:
        raise RemoteResourcePolicyError("Remote resource URL port is invalid")


def _normalize_hostname(hostname: str) -> str:
    value = hostname.strip().lower().rstrip(".")
    if _parse_ip(value) is not None:
        return value
    try:
        normalized = URL.build(scheme="http", host=value).raw_host

View on GitHub (pinned to 5e758547a8)