T09 · Insecure Skill Coding Practices
- Location
scripts/firecrawl-wrap.sh:21- Finding
Unrestricted HTTP(S) Targets Permit Server-Side Request Forgery
- Content
View full analysis
&2 exit 1 fi # Run Firecrawl only when a bounded timeout command is available. TIMEOUT_BIN="$(command -v timeout 2>/dev/null || command -v gtimeout 2>/dev/null || true)" if [[ -z "$TIMEOUT_BIN" ]]; then echo "FIRECRAWL_UNAVAILABLE" exit 0 fi result=$("$TIMEOUT_BIN" 30 firecrawl scrape -- "$URL" --format markdown 2>/dev/null || echo "") ``` The related agent instructions apply similarly unrestricted URLs to all fetch tiers: ```text **Tier 1 — web_fetch (fast):** Call web_fetch(url) If content length >= 200 chars → accept, trim to max_chars_per_source **Tier 2 — Firecrawl (deep/JS):** If Tier 1 fails or returns < 200 chars: Run: bash "{baseDir}/scripts/firecrawl-wrap.sh" If output != "FIRECRAWL_UNAVAILABLE" and != "FIRECRAWL_EMPTY" → accept **Tier 3 — Browser (last resort):** If Tier 2 fails: Call browser(action="open", url=url) Call browser(action="snapshot") ``` ### Technical Analysis The Firecrawl wrapper validates only whether a URL begins with `http://` or `https://`. It does not parse and validate the destination hostname or resolved address. Consequently, it does not reject: - IPv4 or IPv6 loopback addresses. - RFC 1918 private network addresses. - Link-local addresses. - Cloud metadata service addresses. - Reserved, multicast, or otherwise non-public destinations. - Public hostnames that resolve to non-public addresses. - Redirects from an initially public URL to a prohibited destination. The same untrusted URL is used by `web_fetch`, Firecrawl, and browser-based fallbac ...[truncated 1658 chars]- Remediation
View remediation
