T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/generate_avatar.py:25
- Finding
- Unrestricted Custom Provider Endpoints Can Receive API Credentials and User Images<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_avatar.py`, lines 25–29, 229–238, 251–265, and 292–322 **Vulnerability Type**: Unvalidated, environment-controlled network destinations for sensitive requests **Risk Level**: High ### Vulnerable Code ```python OPENAI_BASE_URL = os.environ.get("OPENAI_BASE_URL", "https://api.openai.com/v1") ARK_BASE_URL = os.environ.get("ARK_BASE_URL", "https://ark.cn-beijing.volces.com/api/v3") NANO_BASE_URL = os.environ.get("NANO_BASE_URL", "https://generativelanguage.googleapis.com/v1beta") NANO_MODEL = os.environ.get("NANO_MODEL", "gemini-3.1-flash-image-preview") ARK_MODEL = os.environ.get("ARK_MODEL", "doubao-seedream-5-0-260128") ``` ```python def openai_direct_generate(mother_path: Path, prompt: str) -> bytes: api_key = os.environ["OPENAI_API_KEY"] url = OPENAI_BASE_URL.rstrip("/") + "/images/edits" out = subprocess.check_output([ "curl", "-sS", "-X", "POST", url, "-H", f"Authorization: Bearer {api_key}", "-F", "model=gpt-image-1", "-F", f"prompt={prompt}", "-F", f"image=@{mother_path}", "-F", "size=1024x1024", "-F", "quality=high", "-F", "response_format=b64_json", ], text=True) ``` ```python def nano_direct_generate(mother_path: Path, prompt: str) -> bytes: api_key = os.environ.get("GEMINI_API_KEY") or os.environ.get("NANO_API_KEY") if not api_key: raise RuntimeError("Missing GEMINI_API_KEY or NANO_API_KEY") url = NANO_BASE_URL.rstrip("/") + f"/models/{NANO_MODEL}:generateContent?key={api_key}" payload = { "contents": [{ "parts": [ {"text": prompt}, { "inline_data": { "mime_type": guess_mime(mother_path), "data": load_image_b64(mother_path), } }, ] }], "generationConfig": { "responseModalities": ["I ...[truncated 3976 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Allow only documented provider hosts by default: - `api.openai.com` - `generativelanguage.googleapis.com` - The documented Ark provider hostname 2. Parse custom endpoints with a URL parser and reject: - Non-HTTPS schemes - Embedded credentials - Unexpected ports - Loopback, link-local, and private-network destinations unless explicitly authorized 3. Require an explicit command-line option and clear user confirmation before using a custom provider endpoint. 4. Keep custom endpoint support disabled in normal operation or maintain a configurable hostname allowlist. 5. Avoid putting API credentials in query strings. Use a provider-supported authorization header where possible. 6. Avoid placing bearer tokens in `curl` command-line arguments. Prefer an in-process HTTP client or a protected header/configuration input that is not exposed in the process argument list. 7. Document exactly which destination receives each image and credential before generation begins. 8. Use narrowly scoped, revocable API keys with provider-side spending limits and monitor them for unexpected use. ]]>
