T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/search.py:2196
- Finding
- Authenticated Provider Requests Can Be Redirected to Arbitrary Endpoints<![CDATA[ ## Vulnerability Details **File Location**: `scripts/search.py:2196-2247`, `scripts/search.py:3237-3247`, `scripts/search.py:3574-3595`, `scripts/search.py:3628-3686`, `config.example.json:36-39`, `config.example.json:42-47`, `config.example.json:55-62`, `config.example.json:74-86` **Vulnerability Type**: Unvalidated authenticated endpoint override, credential disclosure, and server-side request forgery **Risk Level**: High ### Vulnerable Code ```python def search_querit( query: str, api_key: str, max_results: int = 5, language: str = "en", country: str = "us", time_range: Optional[str] = None, include_domains: Optional[List[str]] = None, exclude_domains: Optional[List[str]] = None, base_url: str = "https://api.querit.ai", base_path: str = "/v1/search", timeout: int = 30, ) -> dict: endpoint = base_url.rstrip("/") + base_path body: Dict[str, Any] = { "query": query, "count": max_results, } headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", } data = make_request(endpoint, headers, body, timeout=timeout) ``` The endpoint is also exposed through ordinary command-line arguments: ```python querit_config = config.get("querit", {}) parser.add_argument( "--querit-base-url", default=querit_config.get("base_url", "https://api.querit.ai"), help="Querit API base URL" ) parser.add_argument( "--querit-base-path", default=querit_config.get("base_path", "/v1/search"), help="Querit API path" ) ``` Other authenticated providers similarly receive endpoint values directly from configuration: ```python return search_linkup( query=args.query, api_key=key, max_results=args.max_results, api_url=linkup_config.get("api_url", "https://api.linkup.so/v1/search"), timeout=int(linkup_config.get("timeout", 30)), ) ``` ```python return search_firecrawl( query=args.query, api_key=key, max ...[truncated 2683 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Maintain an exact HTTPS hostname allowlist for every authenticated provider: - Querit: `api.querit.ai` - Linkup: `api.linkup.so` - Firecrawl: `api.firecrawl.dev` - SerpBase: `api.serpbase.com` - Keenable: `api.keenable.ai` 2. Validate an endpoint before creating a request or attaching credentials. 3. Reject userinfo, fragments, unsupported ports, non-HTTPS schemes, and hostname suffix tricks. 4. Resolve the hostname and reject loopback, private, link-local, multicast, unspecified, reserved, CGNAT, IPv4-mapped IPv6, and metadata addresses. 5. Revalidate redirect destinations or disable automatic redirects for requests carrying credentials. 6. Remove `--querit-base-url` from the normal CLI unless custom endpoints are an explicit requirement. 7. If development overrides must remain, require a separate, clearly named opt-in and never reuse production credentials with an untrusted host. 8. Add tests proving that credentials cannot be sent to look-alike domains, private addresses, metadata hosts, HTTP endpoints, or redirected destinations. ]]>
