T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/prepare_task_assets.js:47
- Finding
- Automatic image localization permits server-side request forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/prepare_task_assets.js`, lines 47-64 and 92-113 **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Vulnerable Code ```javascript function extractMarkdownImages(text) { const matches = []; const regex = /!\[([^\]]*)\]\((https?:\/\/[^\s)]+)(?:\s+"[^"]*")?\)/g; let match; let order = 0; while ((match = regex.exec(text)) !== null) { order += 1; matches.push({ order, alt: String(match[1] || "").trim(), url: String(match[2] || "").trim(), source_excerpt: String(match[0] || "").slice(0, 240), }); } return matches; } ``` ```javascript async function fetchBuffer(url) { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), 60000); try { const response = await fetch(url, { redirect: "follow", signal: controller.signal, headers: { "user-agent": "openclaw-pipeline/prepare-task-assets", }, }); if (!response.ok) { throw new Error(`http ${response.status}`); } const arrayBuffer = await response.arrayBuffer(); return { buffer: Buffer.from(arrayBuffer), contentType: response.headers.get("content-type") || "", finalUrl: response.url || url, }; } finally { clearTimeout(timer); } } ``` The public runner invokes asset preparation automatically unless the user supplies `--skip-assets`. ### Technical Analysis Any HTTP or HTTPS URL embedded using Markdown image syntax is fetched from the machine running the skill. The implementation does not validate the destination hostname or resolved IP address before making the request. Consequently, an untrusted paper or Markdown document can cause requests to: - Loopback services such as `127.0.0.1` or `[::1]`. - Private network ranges. - Link-local services, including cloud metadata endpoints. - Internal DNS names unavailable to the document author. - Service ...[truncated 1919 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse every URL with `new URL()` and allow only explicitly approved protocols and destinations. 2. Resolve hostnames before connecting and reject all loopback, private, link-local, multicast, unspecified, reserved, and carrier-grade NAT address ranges for both IPv4 and IPv6. 3. Revalidate the hostname and resolved addresses after every redirect. Prefer `redirect: "manual"` and implement a small, bounded redirect loop. 4. Block common metadata hostnames and addresses, including link-local metadata endpoints, as defense in depth. 5. Consider making remote asset downloads opt-in rather than automatic for untrusted documents. 6. Provide a hostname allowlist option for controlled deployments. 7. Run asset retrieval in a sandbox without access to internal networks or cloud metadata. 8. Do not pass downloaded content to an agent until its type and integrity have been validated. 9. Add automated tests covering direct private addresses, DNS rebinding, IPv4-mapped IPv6 addresses, encoded IP formats, and public-to-private redirects. ]]>
