T09 · Insecure Skill Coding Practices
- Location
scripts/run_render.py:27- Finding
Access Token Disclosure Through an Unrestricted API Base URL Override
- Content
View full analysis
str: return ( os.environ.get("CHANJING_OPENAPI_BASE_URL") or os.environ.get("CHANJING_API_BASE") or _DEFAULT_OPENAPI_BASE ).rstrip("/") ``` ```python def fetch_audio_task_state(token: str, task_id: str) -> dict[str, Any]: url = f"{API_BASE}/open/v1/audio_task_state" body = json.dumps({"task_id": task_id}).encode("utf-8") req = urllib.request.Request( url, data=body, headers={"access_token": token, "Content-Type": "application/json"}, method="POST", ) with urllib.request.urlopen(req, timeout=60) as resp: return json.loads(resp.read().decode("utf-8")) ``` ### Technical Analysis The API base URL is obtained from `CHANJING_OPENAPI_BASE_URL` or the legacy `CHANJING_API_BASE` environment variable without validating its scheme, hostname, port, or origin. The renderer subsequently obtains a legitimate Chanjing access token from the sibling authentication module and places that token in the `access_token` HTTP header. Consequently, a process that can influence the renderer's environment can redirect the authenticated request to an attacker-controlled server. The code does not require HTTPS, restrict the destination to `open-api.chanjing.cc`, or prevent an allowed endpoint from redirecting the request to another origin. This implementation is also inconsistent with the intended network boundary in `manifest.yaml`, which declares an allowlist containing `open-api.chanjing.cc`. The code itself does not enforce that boundary. The credential lookup is necessary for the declared video-generation workflow. The ability to send the resulting token to any environment-selected origin is not necessary and exceeds the mini ...[truncated 1451 chars]- Remediation
View remediation
str: raw = ( os.environ.get("CHANJING_OPENAPI_BASE_URL") or os.environ.get("CHANJING_API_BASE") or _DEFAULT_OPENAPI_BASE ).rstrip("/") parsed = urlsplit(raw) if ( parsed.scheme != "https" or parsed.hostname not in _ALLOWED_API_HOSTS or parsed.username is not None or parsed.password is not None or parsed.port not in (None, 443) ): raise ValueError("Untrusted Chanjing API endpoint") return raw ``` ]]>
