T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/_common.py:10
- Finding
- Bearer Access Key Can Be Transmitted to an Attacker-Controlled Server<![CDATA[ ## Vulnerability Details **File Location**: `scripts/_common.py`, lines 10-11 and 53-84; the same URL construction is used at lines 107-117 **Vulnerability Type**: Unrestricted authenticated API destination **Risk Level**: High ### Vulnerable Code ```python BASE_URL = os.environ.get("VOOOAI_BASE_URL", "https://voooai.com") ACCESS_KEY = os.environ.get("VOOOAI_ACCESS_KEY", "") ``` ```python def _headers(content_type: str = "application/json") -> dict: access_key = _ensure_access_key() headers = { "Authorization": f"Bearer {access_key}", } if content_type: headers["Content-Type"] = content_type return headers def api_get(path: str, timeout: int = 30) -> dict: validate_api_path(path) url = f"{BASE_URL.rstrip('/')}{path}" req = urllib.request.Request(url, method="GET", headers=_headers()) try: with urllib.request.urlopen(req, timeout=timeout) as resp: return json.loads(resp.read().decode("utf-8")) ``` The corresponding POST implementation uses the same pattern: ```python validate_api_path(path) url = f"{BASE_URL.rstrip('/')}{path}" data = json.dumps(body).encode("utf-8") req = urllib.request.Request( url, data=data, method="POST", headers=_headers(), ) try: with urllib.request.urlopen(req, timeout=timeout) as resp: return json.loads(resp.read().decode("utf-8")) ``` ### Technical Analysis `VOOOAI_BASE_URL` is accepted without validating its scheme, hostname, port, credentials, or relationship to the expected VoooAI origin. The API path allowlist only validates the path supplied to `api_get()` or `api_post()`; it does not validate the destination represented by `BASE_URL`. Every request adds `VOOOAI_ACCESS_KEY` as a bearer token. Consequently, a modified environment can direct authenticated requests to an arbitrary HTTP or HTTPS server. A non-HTTPS URL also exposes the token to network interception. Redirect behavior is not explicitly constrained, so ...[truncated 1377 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove arbitrary production overrides or maintain an explicit allowlist of approved API origins. 2. Parse the configured URL using `urllib.parse.urlsplit()` and require: - The `https` scheme. - An exact approved hostname, such as `voooai.com`, or a narrowly defined subdomain allowlist. - No embedded username or password. - No fragment. - Only an explicitly approved port. 3. Construct URLs using safe URL-joining logic rather than string concatenation. 4. Install a redirect handler that rejects cross-origin redirects for authenticated requests. 5. Never forward the `Authorization` header after a scheme, host, or port change. 6. If development servers are required, use a separate development credential and explicit configuration flag rather than accepting an unrestricted environment value. 7. Add tests covering HTTP URLs, lookalike domains, embedded credentials, unexpected ports, and cross-origin redirects. ]]>
