T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:65- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
Vulnerability Details
File Location:
scripts/main.py, lines 65–72 and 230–243
Vulnerability Type: Server-Side Request Forgery and unbounded remote resource retrieval
Risk Level: MediumVulnerable code:
python def scan_from_url(self, url: str, format_json: bool = False) -> Union[str, List[str], Dict]: try: with urllib.request.urlopen(url, timeout=30) as response: data = response.read() img = Image.open(io.BytesIO(data)) return self._scan_image(img, format_json) except Exception as e: raise ValueError(f"Failed to fetch image from URL: {e}")The URL-fetching method is reached through the following dispatch logic:
python if input_type == 'file': return scanner.scan_from_file(input_data, format_json) elif input_type == 'url': return scanner.scan_from_url(input_data, format_json) elif input_type == 'base64': return scanner.scan_from_base64(input_data, format_json) if _is_url(input_data): return scanner.scan_from_url(input_data, format_json) elif _is_base64(input_data): return scanner.scan_from_base64(input_data, format_json) else: return scanner.scan_from_file(input_data, format_json)Technical Analysis
The URL scanner passes caller-controlled input directly to
urllib.request.urlopen. It does not validate the destination hostname, resolved IP address, port, redirect destinations, response content type, or response size.A caller can therefore cause the process to send requests from the Agent's network context to loopback, private-network, link-local, or otherwise sensitive HTTP services. Although the response is subsequently interpreted as an image, the outbound request itself is still made. Status differences, response timing, error messages, and image-like responses can expose information about internal services.
Passing
input_type='url'directly also bypasses_is_url(), so ...[truncated 2218 chars]- Remediation
View remediation
Remediation Suggestions
- Accept only explicit
httpandhttpsschemes in the network-fetching method itself. - Reject URLs containing embedded credentials or unexpected ports.
- Resolve the hostname before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 addresses.
- Revalidate the resolved destination immediately before connection to reduce DNS-rebinding risk.
- Disable automatic redirects or validate the scheme, hostname, port, and resolved address of every redirect target.
- Apply an allowlist of trusted image hosts where the deployment model permits it.
- Enforce a strict maximum response size by checking
Content-Lengthand reading incrementally with a byte limit. - Require an expected image media type and validate the file signature before invoking image-processing libraries.
- Apply connection and read timeouts separately where supported.
- Run remote image parsing in a resource-constrained sandbox with current, pinned image-processing dependencies.
- Require explicit user authorization before accessing a remote URL and consider disabling URL input in environments where only local QR scanning is required.
- Accept only explicit
