T09 · Insecure Skill Coding Practices
- Location
scripts/housing_scout/housing_scout.mjs:231- Finding
Unrestricted User-Supplied URL Disclosure Through a Third-Party Fetch Proxy
- Content
View full analysis
String(x.url || "").replace(/\/$/, "") === String(redfinUrl || "").replace(/\/$/, "")); if (hit) return buildSubjectFromListing(hit, { status: "for_sale" }); const mirror = `https://r.jina.ai/http://${String(redfinUrl).replace(/^https?:\/\//, "")}`; const res = await fetch(mirror, { headers: { "user-agent": "Mozilla/5.0" } }); if (!res.ok) throw new Error(`Failed to fetch redfin-url subject (${res.status})`); const text = await res.text(); return parseRedfinTitleSubject(text, redfinUrl); } ``` A second unrestricted forwarding helper is present in the Redfin provider: ```js async function fetchViaJina(url) { const mirror = `https://r.jina.ai/http://${url.replace(/^https?:\/\//, "")}`; const res = await fetch(mirror, { headers: { "user-agent": "Mozilla/5.0" } }); if (!res.ok) throw new Error(`Jina fetch failed ${res.status}`); return res.text(); } ``` ### Technical Analysis The `--redfin-url` argument is treated as an arbitrary string and embedded into a request to the external `r.jina.ai` fetch service. The implementation does not use `new URL()` to validate the input and does not enforce: - An HTTPS source URL. - A Redfin-owned hostname. - Standard destination ports. - The absence of embedded usernames or passwords. - Rejection of localhost, private, link-local, reserved, or cloud metadata destinations. - Redirect restrictions. - Removal of sensitive URL query parameters or fragments. The documentation warns users not to supply private or internal URLs, but this warning is not an enforceable security boundary. A caller can still pass such a URL di ...[truncated 2776 chars]- Remediation
View remediation
