T09 · Insecure Skill Coding Practices
- Location
scripts/azure_tts.py:240- Finding
Unvalidated Azure Region Enables Credential and Speech-Content Exfiltration
- Content
View full analysis
str: url = TOKEN_URL_TEMPLATE.format(region=region) req = request.Request( url, method="POST", headers={"Ocp-Apim-Subscription-Key": key}, ) try: with request.urlopen(req, timeout=timeout) as resp: return resp.read().decode("utf-8") except error.HTTPError as exc: body = exc.read().decode("utf-8", errors="replace") raise SystemExit(f"Token request failed: {exc.code} {exc.reason}: {body}") from exc def synthesize( region: str, token: str, ssml: str, audio_format: str, timeout: int, ) -> bytes: url = SYNTHESIS_URL_TEMPLATE.format(region=region) req = request.Request( url, data=ssml.encode("utf-8"), method="POST", headers={ "Authorization": f"Bearer {token}", "Content-Type": "application/ssml+xml", "X-Microsoft-OutputFormat": audio_format, "User-Agent": "openclaw-azure-speech-tts", }, ) try: with request.urlopen(req, timeout=timeout) as resp: return resp.read() except error.HTTPError as exc: body = exc.read().decode("utf-8", errors="replace") raise SystemExit(f"Synthesis failed: {exc.code} {exc.reason}: {body}") from exc ``` ```pyth ...[truncated 3059 chars]- Remediation
View remediation
str: normalized = region.strip().lower() if not REGION_PATTERN.fullmatch(normalized): raise SystemExit("Invalid Azure region.") return normalized ``` 2. **Prefer an explicit allowlist** of supported Azure Speech regions rather than relying only on a character pattern. Reject dots, slashes, backslashes, colons, `@`, whitespace, percent-encoding, and all other URL metacharacters. 3. **Verify the parsed destination before attaching credentials:** ```python from urllib.parse import urlsplit region = validate_region(region) url = TOKEN_URL_TEMPLATE.format(region=region) parsed = urlsplit(url) expected_host = f"{region}.api.cognitive.microsoft.com" if parsed.scheme != "https" or parsed.hostname != expected_host: raise SystemExit("Refusing to send credentials to an unexpected endpoint.") ``` Apply an equivalent exact-host check to: ```text {region}.tts.speech.microsoft.com ``` 4. **Do not attach the subscription key or bearer token until endpoint validation succeeds.** Redirect handling should also be restricted or disabled for credential-bearing requests so redirects cannot forward sensitive headers to another origin. 5. **Rotate any Azure key that may have been used with an untrusted region value.** Review Azure usage and billing logs for anomalous requests. 6. **Add regression tests** covering malicious values such as: ```text attacker.example/path eastus@example.com eastus:443 eastus/anything eastus%2Fanything ../eastus ``` Each value must be rejected before any network request occurs. ]]>
