T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/crossref_works_search_scraper_api.py:17
- Finding
- Unrestricted Browser Target Exceeds the Declared Crossref Scope<![CDATA[ ## Vulnerability Details **File Location**: `scripts/crossref_works_search_scraper_api.py`, lines 17–36 and 102–105 **Vulnerability Type**: Unrestricted user-controlled remote browsing target **Risk Level**: Medium ### Vulnerable Code ```python def run_task(api_key, base_url='https://search.crossref.org/search/works', keyword='machine learning', count='1'): headers = {"Authorization": f"Bearer {api_key}"} payload = { "input": { "base_url": base_url, "keyword": keyword, "count": count, } } print("Start Task", flush=True) try: response = requests.post( f"{API_BASE_URL}/templates/{TEMPLATE_ID}/runs", json=payload, headers=headers, timeout=30, ).json() ``` The target is populated directly from a command-line argument: ```python base_url = sys.argv[1] if len(sys.argv) > 1 else 'https://search.crossref.org/search/works' keyword = sys.argv[2] if len(sys.argv) > 2 else 'machine learning' count = sys.argv[3] if len(sys.argv) > 3 else '1' output = run_task(api_key, base_url, keyword, count) ``` ### Technical Analysis The Skill declares that it searches public Crossref Works records, for which the expected target is `https://search.crossref.org/search/works`. However, the implementation accepts an arbitrary `base_url` and forwards it to a fixed BrowserAct browser-automation template without validating its scheme, hostname, port, embedded credentials, or resolved address. This allows an invocation to direct the remotely operated browser toward a destination unrelated to Crossref. Depending on the BrowserAct execution environment and template behavior, this could include attacker-controlled sites, internal service names, IP literals, private or link-local addresses, or credential-bearing URLs. Redirects may also allow an initially acceptable URL to lead outside the intended domain unless redirect destinations are independen ...[truncated 2004 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove arbitrary target selection if it is unnecessary. Use the fixed Crossref endpoint internally rather than accepting `base_url` from the command line: ```python CROSSREF_WORKS_URL = "https://search.crossref.org/search/works" ``` 2. If configurability is required, parse the URL with `urllib.parse.urlsplit` and enforce all of the following: - The scheme must be exactly `https`. - The normalized hostname must be exactly `search.crossref.org`. - User information in the URL must be rejected. - Unexpected ports, fragments, and malformed URLs must be rejected. - IP literals and private, loopback, link-local, multicast, reserved, and unspecified addresses must be rejected. - The permitted path should be restricted to `/search/works` unless additional Crossref paths are explicitly required. 3. Configure the BrowserAct template itself with the same destination allowlist. Local validation alone cannot prevent the remote template or a server-side redirect from navigating elsewhere. 4. Reject or stop redirects that leave the approved Crossref origin, validating every redirect destination. 5. Apply bounds and format checks to `count` to prevent unexpected resource consumption, and constrain keyword length to a reasonable maximum. 6. Do not encourage users to paste API keys into an agent conversation. Update `SKILL.md` and the script's onboarding message to instruct users to configure `BROWSERACT_API_KEY` directly through an environment variable or approved secret manager. ]]>
