T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/generate.py:43
- Finding
- Azure API Key Disclosure Through an Unrestricted Configurable Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate.py`, lines 43–63 **Vulnerability Type**: Credential disclosure through insufficient endpoint validation **Risk Level**: High ### Vulnerable Code ```python url = f"{endpoint}/openai/deployments/{deployment}/images/generations?api-version={api_version}" payload = { "prompt": prompt, "size": size, "quality": quality, "style": style, "n": 1, "response_format": "b64_json" } headers = { "Content-Type": "application/json", "api-key": api_key } data = json.dumps(payload).encode("utf-8") req = urllib.request.Request(url, data=data, headers=headers, method="POST") try: with urllib.request.urlopen(req, timeout=120) as response: ``` ### Technical Analysis The `AZURE_OPENAI_ENDPOINT` value is incorporated directly into the destination URL without validating its scheme, hostname, port, embedded credentials, or ownership. The Azure API key is then attached to the request as the `api-key` header. Although network access and authentication are necessary for the declared Azure image-generation functionality, sending credentials to an arbitrary environment-controlled endpoint exceeds the minimum privileges required. The implementation permits both attacker-controlled hosts and plaintext HTTP destinations. The endpoint is loaded from either the process environment or the project-local `.env` file. Anyone able to influence either source can redirect the authenticated request. This is not evidence that the project intentionally exfiltrates credentials, but it creates a concrete credential-disclosure vulnerability. ### Attack Path 1. An attacker gains the ability to modify the project `.env` file, influence the launch environment, or persuade the user to use a malicious endpoint configuration. 2. The attacker sets `AZURE_OPENAI_ENDPOINT` to an attacker-controlled URL, such as `https://attacker.example`, or to a plaintext HTTP endpoint. 3. The user invokes the image-g ...[truncated 993 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the endpoint with `urllib.parse.urlsplit` before constructing the request. 2. Require the `https` scheme and reject plaintext HTTP. 3. Reject endpoints containing embedded usernames, passwords, fragments, unexpected query parameters, or unsupported ports. 4. Enforce an explicit hostname allowlist. If appropriate for supported Azure environments, validate against documented Azure OpenAI hostname suffixes while preventing suffix-confusion attacks. 5. Prefer pinning an expected hostname through trusted configuration rather than accepting arbitrary URLs. 6. Resolve configuration from a protected source and ensure `.env` permissions restrict unauthorized modification. 7. Avoid following cross-origin redirects for authenticated requests, or explicitly verify every redirect destination before retaining the credential header. 8. Consider Azure identity-based authentication and narrowly scoped credentials where supported. 9. Add tests confirming rejection of HTTP endpoints, deceptive subdomains, embedded credentials, attacker domains, malformed URLs, and credential-bearing redirects. ]]>
