Back to skill

Security audit

Alibaba Cloud AI Audio ASR

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent Alibaba Cloud transcription skill, but it sends audio to a cloud service and its helper script can fetch an unvalidated provider-returned URL, so it should be reviewed before installation.

Install only if you are comfortable sending selected audio files and the DashScope API key to Alibaba Cloud. Prefer non-sensitive test audio first, avoid uploading private recordings without consent, and review or patch the async result URL fetching so it only follows expected Alibaba Cloud HTTPS result locations.

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/transcribe_audio.py:222
Finding

Unvalidated Server-Provided Transcription URL Enables SSRF

Content
View full analysis

Vulnerability Details

File Location: scripts/transcribe_audio.py:222-224, 335-339
Vulnerability Type: Server-Side Request Forgery (SSRF) through an unvalidated API response URL
Risk Level: Medium

Vulnerable Code

python
def _fetch_json_url(url: str) -> dict[str, Any]:
    try:
        with urllib.request.urlopen(url, timeout=180) as resp:
            raw = resp.read().decode("utf-8")
python
if async_mode and status.upper() == "SUCCEEDED":
    transcription_url = (((final_resp.get("output") or {}).get("result") or {}).get("transcription_url") or "")
    if isinstance(transcription_url, str) and transcription_url:
        transcription_json = _fetch_json_url(transcription_url)
        final_resp["transcription_result"] = transcription_json

Technical Analysis

After a successful asynchronous transcription, the script extracts transcription_url from the remote API response and passes it directly to urllib.request.urlopen.

The destination is not subject to:

  • Scheme validation, such as requiring HTTPS.
  • An Alibaba Cloud hostname allowlist.
  • DNS resolution and rejection of loopback, private, link-local, multicast, or reserved addresses.
  • Redirect-target validation.
  • A maximum response-size limit.

Because urllib follows HTTP redirects by default, validating only the initial URL would also be insufficient. An allowed-looking URL could redirect the client to an internal address.

Exploitation requires an attacker to influence the response returned by the configured DashScope endpoint, such as through compromise of the provider or another trusted response path. The primary API endpoints themselves are hard-coded HTTPS URLs, which reduces exposure but does not eliminate the unsafe trust boundary.

Attack Path

  1. A user invokes asynchronous transcription with --wait.
  2. The script submits the request to the hard-coded DashScope API and polls until the task reports SUCCEEDED.
  3. An attacker capable of influenci ...[truncated 1590 chars]
Remediation
View remediation

Remediation Suggestions

  1. Accept only https transcription-result URLs.
  2. Allowlist the exact Alibaba Cloud storage hostnames documented for transcription results. Compare normalized hostnames exactly rather than using suffix-only substring checks.
  3. Resolve the hostname and reject every resolved loopback, private, link-local, multicast, unspecified, or reserved IP address for both IPv4 and IPv6.
  4. Disable automatic redirects or implement a redirect handler that revalidates the scheme, hostname, port, and resolved addresses at every hop.
  5. Restrict destination ports to 443.
  6. Apply a bounded response-size limit rather than reading the entire response into memory.
  7. Validate the response content type and expected transcription-result schema before storing it.
  8. Fail closed if the destination cannot be validated.
  9. Add tests covering direct private addresses, encoded IP representations, IPv6 loopback and link-local addresses, DNS rebinding scenarios, and redirects to internal destinations.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (10)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/transcribe_audio.py (reported line 53)May include surrounding context.

python
def _load_env() -> None:
    _load_dotenv(Path.cwd() / ".env")
    repo_root = _find_repo_root(Path(__file__).resolve())
    if repo_root:
        _load_dotenv(repo_root / ".env")

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/transcribe_audio.py (reported line 56)May include surrounding context.

python
def _load_env() -> None:
    _load_dotenv(Path.cwd() / ".env")
    repo_root = _find_repo_root(Path(__file__).resolve())
    if repo_root:
        _load_dotenv(repo_root / ".env")

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/transcribe_audio.py (reported line 306)May include surrounding context.

python
api_key = os.getenv("DASHSCOPE_API_KEY")
    if not api_key:
        print(
            "Error: DASHSCOPE_API_KEY is not set. Configure it via env/.env or ~/.alibabacloud/credentials.",
            file=sys.stderr,
        )
        sys.exit(1)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill uses environment variables, local file read/write, and network access but does not declare any explicit tool scope or permission boundaries. That makes the skill harder to sandbox safely and increases the risk of overbroad execution, especially because it handles local files and transmits audio content to a remote API.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 14)May include surrounding context.

Validation

bash
mkdir -p output/alicloud-ai-audio-asr
python -m py_compile skills/ai/audio/alicloud-ai-audio-asr/scripts/transcribe_audio.py && echo "py_compile_ok" > output/alicloud-ai-audio-asr/validate.txt

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

The skill explicitly sends user-provided audio data and authentication credentials to an external cloud endpoint. External transmission is expected for a cloud ASR skill, but it is still security-relevant because local audio may contain sensitive information and the examples encourage uploading either public URLs or local-file content converted to data URIs.

Content

Scanner excerpt · SKILL.md (reported line 72)May include surrounding context.

Sync transcription (OpenAI-compatible protocol):

bash
curl -sS --location 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions' \
  --header "Authorization: Bearer $DASHSCOPE_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file instructs users to base64-encode local audio and submit it to a remote ASR API, but it does not warn that local file contents will be sent off-device to an external service. For markdown files, user-facing documentation should disclose behaviors that could affect privacy or user data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This script uploads audio content, including local files converted to data URIs, to Alibaba Cloud's remote ASR endpoints without an explicit runtime warning or consent prompt. In a skill intended for transcription this network transfer is expected, but users may unintentionally send sensitive recordings, making this a real privacy/security issue in context.

Content

No source excerpt is available for this finding.

Tainted flow: 'output_path' from os.getenv (line 346, credential/environment) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/transcribe_audio.py (reported line 356)May include surrounding context.

python
)
    )
    output_path.parent.mkdir(parents=True, exist_ok=True)
    output_path.write_text(json.dumps(normalized, ensure_ascii=False, indent=2), encoding="utf-8")

    if args.print_response:
        print(json.dumps(normalized, ensure_ascii=True))

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The manifest and the rest of the file consistently describe a narrowly scoped non-realtime speech-to-text skill. The workflow text at L155-L157 introduces generic guidance about 'mutating' operations and executing a 'target operation,' which contradicts the skill's documented read-only transcription purpose and could mislead an agent about the skill's intent.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.