T09 · Insecure Skill Coding Practices
- Location
scripts/cli.py:19- Finding
Bearer API Key and User Queries Can Be Transmitted to an Arbitrary or Plaintext Endpoint
- Content
View full analysis
Vulnerability Details
File Location:
scripts/cli.py, lines 19–20 and 66–72
Vulnerability Type: Unrestricted destination for sensitive network transmission
Risk Level: HighVulnerable Code
python BASE_URL = os.environ.get("IWENCAI_BASE_URL", "https://openapi.iwencai.com").rstrip("/") API_KEY = os.environ.get("IWENCAI_API_KEY", "")python def _post(url: str, payload: dict, timeout: int = 30) -> dict: headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } body = json.dumps(payload, ensure_ascii=False).encode("utf-8") req = urllib.request.Request(url, data=body, headers=headers, method="POST")The affected URL construction and invocation occur at lines 88 and 100:
python url = f"{BASE_URL}/v1/query2data"python url = f"{BASE_URL}/v1/comprehensive/search"Technical Analysis
The Skill must communicate with the remote iWenCai API to provide its declared financial-query functionality. Sending a bearer API key and the user's financial query to the legitimate API is therefore functionally necessary.
However,
IWENCAI_BASE_URLis trusted without validating its scheme, hostname, port, or other URL components. The_postfunction attaches the bearer credential to every request made to the resulting URL. A custom value may consequently redirect both the credential and user-supplied query to an unrelated server.The implementation also permits an
http://endpoint. In that case, the bearer token and query can be transmitted without transport encryption and may be observable by systems on the network path. This behavior exceeds minimum privilege because the credential should only be disclosed to the intended API service or an explicitly trusted endpoint.Attack Path
- An attacker gains influence over the environment used to launch the Skill, such as a deployment configuration, wra ...[truncated 1509 chars]
- Remediation
View remediation
Remediation Suggestions
- Require the
httpsscheme before transmitting credentials. - Allowlist
openapi.iwencai.comas the default and production destination. - If custom endpoints are a legitimate requirement, maintain an explicit trusted-host allowlist rather than accepting arbitrary URLs.
- Reject URLs containing embedded credentials, fragments, unexpected ports, or ambiguous hostname forms.
- Normalize and parse the URL with
urllib.parse.urlsplitbefore validation; do not validate using substring or suffix checks alone. - Avoid forwarding the production credential when the configured destination is outside the approved trust boundary.
- Fail closed with a clear error when validation fails.
- Document that queries are transmitted to the remote service and may contain user-provided information.
- Consider isolating endpoint selection from ordinary environment configuration so less-trusted launch contexts cannot silently redirect authenticated traffic.
Example hardening pattern:
python from urllib.parse import urlsplit DEFAULT_BASE_URL = "https://openapi.iwencai.com" ALLOWED_HOSTS = {"openapi.iwencai.com"} candidate = os.environ.get("IWENCAI_BASE_URL", DEFAULT_BASE_URL).rstrip("/") parsed = urlsplit(candidate) if ( parsed.scheme != "https" or parsed.hostname not in ALLOWED_HOSTS or parsed.username is not None or parsed.password is not None or parsed.fragment or parsed.port not in (None, 443) ): raise RuntimeError("IWENCAI_BASE_URL is not an approved HTTPS endpoint") BASE_URL = candidate- Require the
