T09 · Insecure Skill Coding Practices
Warning
- Location
- manifest.json:9
- Finding
- Unrestricted Network Scope Without Public-Address Validation## Vulnerability Details **File Location**: `manifest.json:9-12` **Related Locations**: `runner.py:16-24`, `schemas/input.json:5-10` **Vulnerability Type**: Server-Side Request Forgery (SSRF) / Missing Network-Destination Validation **Risk Level**: Medium ### Vulnerable Code `manifest.json:9-12`: ```json "permissions": { "browser": false, "network_domains": ["*"] } ``` `runner.py:16-24`: ```python query = str(inputs.get("query", "")) if not query: return {"ok": False, "error": "missing 'query' in inputs"} parsed = parse_query_to_run(query) engine = AutomationEngine(_REPO_ROOT) script_dir = resolve_script_dir(_REPO_ROOT, parsed.script_dir) result = engine.run(script_dir, parsed.inputs) ``` `schemas/input.json:5-10`: ```json "properties": { "query": { "type": "string", "description": "Natural-language request, e.g. 'check yahoo.com for the word finance'" } } ``` ### Technical Analysis The skill documentation limits its operation to public websites, but this boundary is not enforced by the supplied implementation: - The manifest authorizes network access to every domain through `network_domains: ["*"]`. - The input schema accepts an unrestricted natural-language string. - The runner passes the query through `parse_query_to_run()` and into `AutomationEngine.run()` without validating the resulting URL, scheme, hostname, resolved IP address, port, or redirects. - There are no explicit controls rejecting loopback, private, link-local, reserved, multicast, or cloud-metadata destinations. This creates a potential SSRF or confused-deputy condition if the delegated `openclaw_automation` implementation accepts arbitrary URLs. An attacker may be able to make the runtime issue requests to services that are inaccessible from the attacker's own network position. The external `openclaw_automation` package was not included in the reviewed project, so its internal protections could not be verified. The finding is therefore based on the absence ...[truncated 1479 chars]
- Remediation
- ## Remediation Suggestions 1. **Restrict network permissions** - Replace `network_domains: ["*"]` with the narrowest practical domain allowlist. - If arbitrary public websites are a functional requirement, enforce a dedicated public-internet egress policy rather than unrestricted destination access. 2. **Validate parsed destinations** - Permit only `http` and `https`. - Reject URLs containing embedded credentials or malformed hostnames. - Restrict ports to those required by the skill. - Normalize hostnames before applying policy. 3. **Validate resolved addresses** - Resolve every hostname and reject loopback, private, link-local, multicast, unspecified, reserved, and other non-public address ranges for both IPv4 and IPv6. - Explicitly deny known cloud metadata destinations. - Perform this enforcement in the network request layer rather than relying solely on natural-language parsing. 4. **Secure redirects and DNS handling** - Revalidate the destination after every redirect. - Limit redirect depth. - Pin validated DNS resolutions where supported or otherwise mitigate DNS rebinding and time-of-check/time-of-use inconsistencies. 5. **Harden input controls** - Add a reasonable `maxLength` constraint to the `query` property. - Prefer extracting a structured URL field and validating it against a strict schema before execution. - Reject requests that cannot be unambiguously classified as public-site operations. 6. **Add security tests** - Test loopback, RFC 1918, link-local, IPv6-local, integer/hexadecimal IP representations, redirect chains, user-information URL syntax, alternate ports, and DNS-rebinding scenarios. - Verify that all such requests fail before any network connection is made.
