T09 · Insecure Skill Coding Practices
- Location
scripts/bp-audit/bp_api.py:37- Finding
Unrestricted API Base URL Override Can Exfiltrate the appKey and Business Data
- Content
View full analysis
Vulnerability Details
File Location:
scripts/bp-audit/bp_api.py:37-41, 48-60
Vulnerability Type: Credential exfiltration through an unvalidated network destination
Risk Level: HighVulnerable Code
python BASE_URL = os.environ.get( "BP_OPEN_API_BASE_URL", "https://sg-al-cwork-web.mediportal.com.cn/open-api", ) APP_KEY = os.environ.get("BP_OPEN_API_APP_KEY", "") TIMEOUT = 30 def _request(method, path, *, params=None, json_body=None): if not APP_KEY: return {"error": "BP_OPEN_API_APP_KEY is not configured. Set it as an environment variable."} url = f"{BASE_URL}{path}" headers = {"appKey": APP_KEY} try: if method == "GET": resp = requests.get(url, params=params, headers=headers, timeout=TIMEOUT) else: headers["Content-Type"] = "application/json" resp = requests.post( url, params=params, json=json_body, headers=headers, timeout=TIMEOUT, )Technical Analysis
The script allows
BP_OPEN_API_BASE_URLto determine the complete destination to which the authentication credential is sent. No validation restricts this value to the documented production origin,https://sg-al-cwork-web.mediportal.com.cn/open-api.In particular, the implementation does not:
- Require HTTPS.
- Allowlist the expected hostname.
- Reject loopback, private, or attacker-controlled destinations.
- Reject unexpected ports or embedded URL credentials.
- Prevent cross-origin HTTP redirects.
- Normalize and verify the final request origin.
Every API request attaches
BP_OPEN_API_APP_KEYas theappKeyheader. Therefore, control over the process environment is sufficient to redirect the credential to an arbitrary server. POST requests can additionally disclose business payloads containing internal task IDs, em ...[truncated 1985 chars]- Remediation
View remediation
Remediation Suggestions
- Remove the
BP_OPEN_API_BASE_URLoverride from the published production Skill and use a fixed, audited API origin. - If an override is operationally required, parse the URL and strictly allowlist:
- Scheme:
https - Hostname:
sg-al-cwork-web.mediportal.com.cn - Expected port:
443or no explicit port - Expected base path:
/open-api
- Scheme:
- Reject URLs containing user information, fragments, unexpected query strings, IP-literal hosts, loopback addresses, or private-network destinations.
- Disable redirects with
allow_redirects=False, or manually verify that every redirect remains on the exact approved origin before resending credentials. - Build endpoints using a validated URL-joining function rather than direct string concatenation.
- Use a narrowly scoped, short-lived credential if supported by the service. Separate read-only audit credentials from write-capable credentials.
- Add automated tests proving that HTTP URLs, alternate hosts, unexpected ports, and cross-origin redirects are rejected.
- Rotate the appKey if there is any possibility that the override has previously pointed to an untrusted destination.
- Remove the
