T09 · Insecure Skill Coding Practices
- Location
scripts/fetch-markdown.sh:6- Finding
Unrestricted URL Fetching Enables Local File Disclosure and Server-Side Request Forgery
- Content
View full analysis
" echo "Example: $0 https://developers.cloudflare.com/agents/" exit 1 fi echo "Fetching Markdown from: $URL" echo "---" # Fetch with Accept header for Markdown curl -sSL "$URL" \ -H "Accept: text/markdown, text/html;q=0.9" \ -D - \ --compressed ``` #### `references/examples.md:56-67` ```typescript const url = new URL(request.url); const targetUrl = url.searchParams.get("url"); if (!targetUrl) { return new Response("Missing url parameter", { status: 400 }); } const response = await fetch(targetUrl, { headers: { Accept: "text/markdown, text/html", }, }); ``` #### `references/examples.md:94-101` ```typescript async fetchPage(url: string): Promise<{ markdown: string; tokens: number }> { const response = await fetch(url, { headers: { Accept: "text/markdown, text/html", }, }); const markdown = await response.text(); ``` ### Technical Analysis The executable script accepts a caller-controlled URL and passes it directly to `curl` without validating its scheme, destination hostname, resolved IP address, port, or redirect targets. The use of `curl -L` follows redirects automatically. Consequently, validating only the initial URL outside the script would not be sufficient: an apparently legitimate public endpoint could redirect the request to a local, private, link-local, or otherwise sensitive destination. In addition to HTTP and HTTPS, curl commonly supports schemes such as `file://`. Because the script does not restrict protocols, a caller may be able to make it read a local file that is accessi ...[truncated 2973 chars]- Remediation
View remediation
