Back to skill

Security audit

IMA AI Music Generator — Suno, DouBao

Security checks for vulnerabilities and agentic risk

Overview

This skill needs an API key and can send it to an arbitrary API base URL despite claiming it only goes to IMA, and its voice-versus-music descriptions are inconsistent.

Install only if you understand this is a music-generation skill, not a voiceover/TTS skill. Do not allow untrusted instructions to set --base-url, and prefer a fixed or allowlisted api.imastudio.com endpoint before providing IMA_API_KEY. Pin dependencies before production use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ima_voice_create.py:894
Finding
API Credential and Prompt Disclosure Through an Arbitrary Base URL<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ima_voice_create.py`, lines 52–58, 72–79, 611–617, and 894–910 **Vulnerability Type**: Unrestricted credential-bearing network destination **Risk Level**: Medium ### Vulnerable Code ```python def make_headers(api_key: str, language: str = "en") -> dict: return { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", "User-Agent": "IMA-OpenAPI-Client/Skill-1.2.2", "x-app-source": "ima_skills", "x_app_language": language, } ``` ```python url = f"{base_url}/open/v1/product/list" params = {"app": app, "platform": platform, "category": TASK_TYPE} headers = make_headers(api_key, language) resp = requests.get(url, params=params, headers=headers, timeout=30) ``` ```python url = f"{base_url}/open/v1/tasks/create" headers = make_headers(api_key) resp = requests.post(url, json=payload, headers=headers, timeout=30) ``` ```python p.add_argument("--base-url", default=DEFAULT_BASE_URL, help="API base URL") ``` ```python def main(): args = build_parser().parse_args() base = args.base_url # API key is accepted only from environment variable apikey = os.getenv("IMA_API_KEY") if not apikey: logger.error("API key is required. Set IMA_API_KEY environment variable") sys.exit(1) ``` ### Technical Analysis The script obtains the sensitive `IMA_API_KEY` credential from the environment and places it in an HTTP `Authorization: Bearer` header. However, the destination receiving that header is derived directly from the unrestricted `--base-url` command-line argument. There is no validation of: - The destination hostname. - The URL scheme. - The destination port. - URL user-information components. - Whether the destination belongs to an approved IMA domain. Consequently, the credential is not technically restricted to `api.imastudio.com`. A caller can provide an attacker-controlled ...[truncated 2017 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--base-url` from production-facing command-line options and use the fixed constant: ```python base = DEFAULT_BASE_URL ``` 2. If endpoint configurability is required for controlled testing, enforce an exact allowlist before reading or using the API key: ```python from urllib.parse import urlparse ALLOWED_API_HOSTS = {"api.imastudio.com"} def validate_base_url(value: str) -> str: parsed = urlparse(value) if parsed.scheme != "https": raise ValueError("The API base URL must use HTTPS") if parsed.hostname not in ALLOWED_API_HOSTS: raise ValueError("Unapproved API hostname") if parsed.username or parsed.password: raise ValueError("URL user information is not permitted") if parsed.port not in (None, 443): raise ValueError("Unapproved API port") return f"https://{parsed.hostname}" ``` 3. Validate the destination before constructing any authorization header or sending any request. 4. Disable redirects for credential-bearing requests unless redirects are strictly required: ```python requests.get(..., allow_redirects=False) requests.post(..., allow_redirects=False) ``` 5. If redirects must be supported, validate every redirect destination against the same HTTPS hostname allowlist before resending credentials. 6. Separate authenticated and unauthenticated request helpers so credentials cannot accidentally be attached to arbitrary URLs. 7. Add automated tests confirming that HTTP URLs, alternate hosts, subdomain lookalikes, user-information URLs, and unexpected ports are rejected. 8. Update the documentation only after code-level enforcement matches the claim that credentials are sent exclusively to `api.imastudio.com`. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:4
Finding
Unbounded and Unhashed Third-Party Dependency<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt`, line 4 **Vulnerability Type**: Insufficient dependency version and integrity controls **Risk Level**: Low ### Vulnerable Code ```text requests>=2.25.0 ``` ### Technical Analysis The dependency declaration establishes only a minimum version and permits installation of any later `requests` release. It also provides no package hashes or lock file to verify the integrity of the resolved package and its transitive dependencies. This does not establish that the current `requests` package is malicious. However, it makes installations non-reproducible and allows future, unreviewed versions to enter the Skill environment automatically. Because this dependency handles every credential-bearing request, unexpected changes or a future supply-chain compromise could affect authentication headers, TLS behavior, proxy handling, redirects, or response processing. ### Attack Path 1. The Skill is installed in a fresh environment using: ```bash pip install -r requirements.txt ``` 2. The package resolver selects any available release satisfying `requests>=2.25.0`, including releases published after the Skill was audited. 3. The selected release and its transitive dependencies are installed without comparison against audit-approved hashes. 4. If a resolved release or dependency is compromised, malicious installation or import-time behavior could execute in the installer or Skill process. 5. The compromised component could access network requests and potentially expose the IMA API key, prompts, or API responses. This is a conditional supply-chain path rather than evidence that the currently available dependency is compromised. ### Impact Assessment Potential impact depends on the privileges of the environment performing installation or running the Skill. A compromised dependency could potentially: - Execute code with the privileges of the installing or running account. - Read environment varia ...[truncated 421 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `requests` to a release that has been reviewed and tested with the Skill: ```text requests==<reviewed-version> ``` 2. Pin all transitive dependencies through a generated lock file rather than relying only on a top-level requirement. 3. Generate and verify cryptographic hashes, for example with `pip-compile --generate-hashes`, and install with: ```bash pip install --require-hashes -r requirements.lock ``` 4. Periodically update the pinned versions through a controlled dependency-review process that includes vulnerability scanning and regression testing. 5. Use a trusted Python package index and prevent untrusted index configuration from being supplied during automated installation. 6. Run installation and execution in a minimally privileged virtual environment or container to limit the impact of a compromised dependency. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (26)

Tainted flow: 'task_id' from os.getenv (line 983, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
"Check the IMA dashboard for status."
            )

        resp = requests.post(url, json={"task_id": task_id},
                             headers=headers, timeout=30)
        resp.raise_for_status()
        data = resp.json()
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill metadata and description say the skill generates voiceovers and narration, but the file actually documents text-to-music generation APIs. This mismatch can mislead users and downstream agents into sending prompts or data to a different capability than expected, undermining informed consent and safe routing.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The manifest says the skill generates voiceovers, narration, and spoken audio, but the body documents music and song generation workflows instead. This kind of description-behavior mismatch is dangerous because users and reviewers may grant trust, credentials, or approval based on one purpose while the skill actually performs a different remote action, undermining informed consent and security review.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The manifest description explicitly promises voiceovers and spoken audio, while the remainder of the file describes text-to-music and song generation. Security-relevant documentation inconsistencies can mislead users, operators, and automated governance systems about what data is processed and what external actions are taken.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The manifest tagline and description claim the skill generates voiceovers and narration, while the rest of the metadata clearly describes music and song generation. This discrepancy can mislead users, reviewers, and downstream automation about what content is processed and what external services may be invoked, undermining informed consent and trust.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The keyword file markets broad AI music generation, songwriting, BGM, jingles, and beat-making capabilities, while the manifest description says the skill is for voiceovers, narration, and spoken audio. This mismatch is dangerous because it can cause the platform or users to invoke the skill for materially different functionality than declared, weakening trust, review accuracy, and policy enforcement around what the skill actually does.

Intent-Code Divergence

Medium
Confidence
99% confidence
Finding
The final lines explicitly state that the skill is a music-generation capability and even distinguish it from TTS, directly contradicting the manifest's voiceover/narration-focused description. This is especially risky because it looks like an attempt to route users into an undeclared capability area, which can bypass user expectations and any review controls tied to the declared skill type.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The phrase indicating that a user can describe desired music in one sentence is broad enough to overlap with many ordinary requests for media creation, increasing the chance of accidental or overly aggressive triggering. In the context of a skill whose declared purpose already conflicts with its actual documented behavior, broad triggering becomes more dangerous because it can silently activate undeclared music-generation functionality.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The title claims 'IMA Voice AI' while the content is clearly about music generation. Although not directly code-execution related, deceptive or inaccurate labeling increases the risk of operator confusion, misuse, and accidental transmission of user requests to an unintended service flow.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The UX flow specifies fixed Chinese user messages for pre-generation and progress updates, rather than offering a language choice. This creates a locale/language policy issue because the skill appears to require Chinese output regardless of user preference.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
The error translation section instructs the skill to use Chinese phrasing ('Say Instead (Chinese)') and presents that as a default behavior, while also prohibiting technical messages. Without an explicit user language selection mechanism, this imposes a language choice on users.

External Transmission

Medium
Category
Data Exfiltration
Content
}
        }]
    }
    r = requests.post(f"{BASE_URL}/open/v1/tasks/create", headers=HEADERS, json=body)
    r.raise_for_status()
    return r.json()["data"]["id"]
Confidence
89% confidence
Finding
The skill sends user-supplied prompts and model parameters to an external domain, which is an external data transmission event. In this skill context that behavior is expected, but it is still security-relevant because users may provide sensitive text and the skill does not document consent, minimization, or safeguards around what is transmitted.

External Transmission

Medium
Category
Data Exfiltration
Content
def poll(task_id, interval=5, timeout=480):
    deadline = time.time() + timeout
    while time.time() < deadline:
        r = requests.post(f"{BASE_URL}/open/v1/tasks/detail",
                          headers=HEADERS, json={"task_id": task_id})
        r.raise_for_status()
        task = r.json()["data"]
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill declares capabilities requiring environment variable access and outbound network access, but it does not explicitly scope or disclose tool permissions. This weakens least-privilege controls and makes it harder for reviewers or runtime policy engines to understand what the skill is allowed to do, especially since it transmits an API credential to a remote service.

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
Labeling the skill as 'IMA Voice AI' while documenting music generation creates an identity and purpose mismatch that can confuse users and reviewers. In a credentialed, networked skill, this ambiguity increases the risk of inappropriate deployment or trust because the branding suggests a different class of processing than what actually occurs.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The documentation hard-codes `x_app_language: en`, which indicates the skill will send an English locale setting regardless of the user's language preference. This is a natural-language locale policy concern because the file does not offer user choice or explain why English is required for a region-specific or compliance reason.

Intent-Code Divergence

Medium
Confidence
84% confidence
Finding
The manifest asserts that the API key is sent only to api.imastudio.com, but the listed models and branding suggest possible brokering to third-party music providers such as Suno or DouBao. If requests or user content are actually relayed beyond the declared endpoint, the manifest creates inaccurate security and data-handling expectations, which can expose credentials or user prompts to undisclosed processors.

External Transmission

Medium
Category
Data Exfiltration
Content
f"credit={model_params['credit']}, attribute_id={model_params['attribute_id']}")

    try:
        resp = requests.post(url, json=payload, headers=headers, timeout=30)
        resp.raise_for_status()
        data = resp.json()
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
f"credit={model_params['credit']}, attribute_id={model_params['attribute_id']}")

    try:
        resp = requests.post(url, json=payload, headers=headers, timeout=30)
        resp.raise_for_status()
        data = resp.json()
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
logger.info(f"Attempt {attempt_num}: attribute_id={attribute_id}, credit={credit}, params={list(candidate_params.keys())}")
        
        try:
            resp = requests.post(url, json=payload, headers=headers, timeout=30)
            resp.raise_for_status()
            data = resp.json()
Confidence
81% confidence
Finding
The script allows a user-supplied --base-url to fully control the destination of authenticated POST requests, including the Authorization bearer token in headers. In the reflection path, it repeatedly sends task-creation payloads and credentials to that destination, so an attacker who can influence invocation arguments could redirect requests to a malicious server and capture the API key and submitted content.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This Python file contains hard-coded natural-language strings in Chinese for success/failure reflections and user-visible status messages, such as '✅ 成功(尝试 ...)', '移除不支持的参数', and later CLI output like '🧠 反省日志'. The policy requires flagging language/locale violations when a skill forces a specific language without offering user choice, and these strings are emitted regardless of the user's language preference for product labels.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The manifest describes a skill for generating voiceovers, narration, and spoken audio, which implies text-to-speech or spoken-voice output. In contrast, the script explicitly identifies itself as a music creation tool and uses a fixed task type of "text_to_music", with examples and model selection centered on music, BGM, and songs rather than narration or voiceover generation.

Natural-Language Policy Violations

Low
Confidence
72% confidence
Finding
The file introduces a substantial Chinese-language keyword and description block after extensive English-language content, but it does not state how language selection is determined or offer user opt-in for locale/language behavior. This can create ambiguity about language handling and may conflict with organizational expectations to avoid forcing a language or locale without user choice.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# Python dependencies for ima-voice-ai skill
# Install with: pip install -r requirements.txt

requests>=2.25.0
Confidence
97% confidence
Finding
The dependency is specified with a lower bound only (`requests>=2.25.0`), which makes builds non-reproducible and allows installation of different versions over time. That increases supply-chain risk and can unintentionally pull in vulnerable or breaking releases, especially for a network-facing library like `requests`.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding
The manifest references `requests` without an exact version, so it is impossible to verify whether the installed package includes fixes for known CVEs affecting some releases. Because `requests` handles outbound HTTP and potentially credentials, leaving its version unspecified creates avoidable exposure to known dependency vulnerabilities.

Static analysis

No suspicious patterns detected.