T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/fetch_url.py:12
- Finding
- Unvalidated URLs and URL-Embedded Secrets Are Disclosed to Third-Party Fetch Services<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch_url.py`, lines 12–16 and 34–37; documented workflow in `SKILL.md`, lines 22–38 **Vulnerability Type**: Unrestricted external URL forwarding and sensitive URL disclosure **Risk Level**: Medium ### Vulnerable Code ```python METHODS = [ ('r.jina.ai', lambda u: f'https://r.jina.ai/http://{u.removeprefix("https://").removeprefix("http://")}'), ('markdown.new', lambda u: f'https://markdown.new/{u}'), ('defuddle', lambda u: f'https://defuddle.md/{u}'), ] ``` ```python attempts = [] for name, builder in METHODS: target = builder(args.url) try: text = fetch(target, args.timeout) ``` The corresponding documented invocation is: ```markdown For deterministic retries, use the bundled script: ```bash python {baseDir}/scripts/fetch_url.py "https://example.com/article" ``` ``` ### Technical Analysis The script accepts an arbitrary URL from the command line and embeds its complete value into requests sent to as many as three independent third-party services. It does not validate: - The URL scheme. - Embedded username or password information. - Sensitive query parameters or signed URL tokens. - Localhost, private, link-local, loopback, or reserved destinations. - Internal DNS names. - Encoded or obfuscated destination forms. - Whether the user has consented to disclosing the URL to external providers. Consequently, password-reset links, presigned object-storage URLs, authentication tokens in query strings, internal service names, and other sensitive URL components can be disclosed to `r.jina.ai`, `markdown.new`, and `defuddle.md`. If an earlier service fails or returns insufficient content, the same URL may be disclosed to additional providers. The third-party services are also instructed to retrieve the supplied destination. Whether private resources are reachable depends on each provider's network controls, so this code does not by itself establish local server-side requ ...[truncated 1499 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse input with `urllib.parse.urlsplit` and permit only explicit `http` and `https` schemes. 2. Reject URLs containing username or password information. 3. Reject localhost names and loopback, private, link-local, multicast, unspecified, and reserved IP addresses. 4. Resolve hostnames before use and validate every returned address. Revalidate after redirects to reduce DNS rebinding and redirect-based bypasses. 5. Reject malformed, encoded, or ambiguous host representations. 6. Detect sensitive query parameters such as `token`, `key`, `signature`, `sig`, `auth`, and presigned-URL fields. Reject them by default or require explicit user confirmation before forwarding. 7. Warn users clearly that the complete URL will be shared with named third-party providers. 8. Consider direct retrieval under controlled network policy instead of disclosing URLs to multiple external services. 9. Apply an allowlist when the deployment has a known set of permitted public domains. 10. Avoid recording full sensitive URLs in output attempt histories; redact credentials and query values before including URLs in JSON. ]]>
