T09 · Insecure Skill Coding Practices
- Location
scripts/common.py:16- Finding
API Key Disclosure Through an Unrestricted Base URL Override
- Content
View full analysis
str: key = os.environ.get(API_KEY_ENV) if not key: raise MiniMaxError(f"Missing {API_KEY_ENV} in environment") return key def headers(extra: Optional[Dict[str, str]] = None) -> Dict[str, str]: h = {"Authorization": f"Bearer {get_api_key()}"} if extra: h.update(extra) return h def request_json(method: str, path: str, *, params=None, json_body=None, timeout: int = 180) -> Dict[str, Any]: resp = requests.request( method, BASE_URL + path, headers=headers({"Content-Type": "application/json"}), params=params, json=json_body, timeout=timeout, ) ``` The same issue also affects multipart requests in `scripts/common.py:64-73`: ```python def request_multipart(path: str, *, data=None, files=None, timeout: int = 180) -> Dict[str, Any]: resp = requests.post( BASE_URL + path, headers={"Authorization": f"Bearer {get_api_key()}"}, data=data, files=files, timeout=timeout, ) ``` ### Technical Analysis The Skill legitimately requires `MINIMAX_API_KEY` and must transmit it to the MiniMax API for authentication. However, `MINIMAX_BASE_URL` is accepted directly from the environment without validating its scheme, hostname, port, or other URL components. Every authenticated API call attaches the bearer credential to the configured destination. Consequently, a value such as `http://attacker.example` causes the API key to be transmitted to an attacker-controlled server. An HTTP destination also exposes the credential to passive network interception and active man-in-the-middle attacks. The netw ...[truncated 1629 chars]- Remediation
View remediation
str: parsed = urlparse(value) if parsed.scheme != "https": raise MiniMaxError("MINIMAX_BASE_URL must use HTTPS") if parsed.username or parsed.password: raise MiniMaxError("Credentials are not allowed in MINIMAX_BASE_URL") return value.rstrip("/") ``` 2. Allowlist the official hostname by default: ```python ALLOWED_API_HOSTS = {"api.minimaxi.com"} if parsed.hostname not in ALLOWED_API_HOSTS: raise MiniMaxError("Untrusted MiniMax API host") ``` 3. If custom enterprise or proxy endpoints are a required feature, require an additional explicit opt-in such as `MINIMAX_ALLOW_CUSTOM_HOST=1` and clearly warn that the API key will be shared with that host. 4. Reject unexpected ports, fragments, query strings, and URL user-information unless they are explicitly required. 5. Construct endpoint URLs with a safe URL-joining mechanism rather than direct string concatenation. 6. Add tests confirming that plaintext HTTP, embedded credentials, malformed URLs, and untrusted hosts are rejected before the API key is read or transmitted. 7. Document the trust implications of custom endpoints and recommend narrowly scoped, revocable API keys where supported. ]]>
