T09 · Insecure Skill Coding Practices
- Location
scripts/origin_probe.py:128- Finding
API-Derived Origin Address Enables Blind SSRF into the Agent Network
- Content
View full analysis
Vulnerability Details
File Location:
scripts/origin_probe.py, lines 128–141 and 169–186
Vulnerability Type: Blind server-side request forgery (SSRF)
Risk Level: MediumComplete Vulnerable Code
python def check_is_private_address(host): """ Check if the host is a private/loopback/link-local IP address. Returns: True if the host is a private IP literal, False otherwise. """ try: ip = ipaddress.ip_address(host) return ( ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved ) except ValueError: # Domain name — cannot determine without resolution return Falsepython url = "{}://{}:{}/".format(scheme, host, port) try: # Try HEAD first (matching original curl -o /dev/null behavior) response = requests.head( url, timeout=timeout, allow_redirects=False, ) # Fallback to GET if HEAD is not allowed (HTTP 405) if response.status_code == 405: response.close() response = requests.get( url, timeout=timeout, allow_redirects=False, stream=True, )The data flow is established by
references/task-origin-config-query.md, lines 29–44, which directs the Agent to extractorigin_addr,http_port, andhttps_portfromconfigs.sources[0].references/task-origin-probe.md, lines 5–31, then directs the Agent to pass those values toorigin_probe.py.Technical Analysis
The probe accepts a cloud API-derived origin address and uses it as an HTTP or HTTPS destination. Although
check_is_private_address()identifies some private, loopback, link-local, and reserved IP literals, the result is only included as informational output. It does not prevent the request.Domain names are treated as public without resolving and validating their addresses. Consequently, a hostname that resolves to a pr ...[truncated 2395 chars]
- Remediation
View remediation
Remediation Suggestions
- Resolve domain names before making requests and reject every resolved address that is private, loopback, link-local, reserved, multicast, or unspecified.
- Reject private and special-purpose IP literals rather than merely reporting
is_private_address. - Validate the actual connected peer address to mitigate DNS rebinding and time-of-check/time-of-use resolution changes.
- Prefer an explicit allowlist of user-confirmed public origin addresses.
- If probing private origins is an intended feature, require explicit confirmation for each private destination and run the probe in an isolated environment without access to host-local, control-plane, or metadata services.
- Restrict destination ports to those configured and expected for CDN origin traffic where operationally possible.
- Avoid the GET fallback unless it is essential. If retained, require explicit authorization or limit it to destinations that have passed all network-address controls.
- Add regression tests covering direct private IPs, loopback, IPv6 local addresses, link-local addresses, hostnames resolving to private addresses, mixed public/private DNS answers, and DNS rebinding scenarios.
