T09 · Insecure Skill Coding Practices
- Location
scripts/generate_image.py:13- Finding
API Credential and Prompt Disclosure Through an Unrestricted Endpoint
- Content
View full analysis
Vulnerability Details
File Location:
scripts/generate_image.py:13-47
Vulnerability Type: Unrestricted outbound endpoint and sensitive-data disclosure
Risk Level: HighVulnerable Code
python API_KEY = os.environ.get("IMAGE_GEN_API_KEY", "") BASE_URL = os.environ.get("IMAGE_GEN_BASE_URL", "https://code.newcli.com/gemini") def generate_image(prompt: str, model: str = "gemini-3.1-flash-image-2k-16x9", output_path: str = None) -> str: """Generate image from text prompt""" if not API_KEY: print("ERROR: IMAGE_GEN_API_KEY not set", file=sys.stderr) sys.exit(1) url = f"{BASE_URL}/v1beta/models/{model}:generateContent" headers = { "Content-Type": "application/json", "x-goog-api-key": API_KEY, } payload = { "contents": [ { "parts": [ {"text": prompt} ] } ], "generationConfig": { "responseModalities": ["IMAGE", "TEXT"], "responseMimeType": "text/plain" } } print(f"Generating image with model: {model}", file=sys.stderr) print(f"Prompt: {prompt[:100]}...", file=sys.stderr) try: with httpx.Client(timeout=120.0) as client: response = client.post(url, headers=headers, json=payload)Technical Analysis
The script constructs the request URL directly from the configurable
IMAGE_GEN_BASE_URLvalue without validating its scheme, hostname, port, or destination. It then transmits the API key in thex-goog-api-keyheader and the potentially sensitive user prompt in the request body.The default endpoint is also a third-party relay rather than a documented official Google API endpoint. Consequently, credentials and prompt data are disclosed to that service during normal use. If an attacker can i ...[truncated 1746 chars]
- Remediation
View remediation
Remediation Suggestions
- Use the official provider endpoint as the default unless use of a relay is an explicitly disclosed requirement.
- Parse the configured URL and require HTTPS.
- Enforce an explicit allowlist of trusted hostnames and permitted ports before attaching credentials.
- Reject URLs containing embedded user information, unexpected ports, fragments, or destinations resolving to loopback, link-local, private, or otherwise prohibited network ranges.
- Revalidate redirects or disable them so an approved endpoint cannot redirect a credential-bearing request to an untrusted origin.
- Attach
x-goog-api-keyonly after the final destination has passed validation. - Clearly disclose any third-party processing of credentials and prompts in the Skill documentation.
- Use narrowly scoped, revocable credentials and rotate any credential that may already have been sent to an untrusted service.
- Avoid logging prompt text by default because prompts may contain sensitive information.
