Back to skill

Security audit

Suno V5 Music

Security checks for vulnerabilities and agentic risk

Overview

This music-generation skill mostly matches its stated purpose, but it handles API credentials and a local web server in ways users should review carefully before installing.

Install only if you are comfortable running a local Flask server that stores your AceData API key in the browser, saves generated content and history to disk, and auto-installs dependencies. Prefer using a disposable or low-scope API key, a virtual environment, localhost-only access, and removing the shutdown/debug/localStorage patterns before regular use.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (6)

T09 · Insecure Skill Coding Practices

Error
Location
web/templates/index.html:1003
Finding

Persistent DOM-Based Cross-Site Scripting Through Untrusted Media URLs

Content
View full analysis
{ const card = document.createElement('div'); card.className = 'track-card'; const date = track.created_at ? new Date(track.created_at).toLocaleString() : 'Unknown'; const duration = track.duration ? `${Math.round(track.duration)}s` : ''; card.innerHTML = `

${escapeHtml(track.title)}

${escapeHtml(track.prompt || track.style || '')} • ${date} ${duration}

${track.audio_url ? `` : ''}
下载 MP3 ${track.lyric ? `歌词` : ''}
`; container.appendChild(card); }); ``` ### Technical Analysis The application obtains track records from `/history` and inserts them into the document using `innerHTML`. Although some textual properties are passed through `escapeHtml`, `track.image_url` and `track.audio_url` are directly interpolated into quoted HTML attributes. These URL values originate in the external music API response and are subsequently persisted in `generation_hi ...[truncated 1648 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
web/templates/index.html:908
Finding

AceData API Key Persisted in JavaScript-Accessible Local Storage

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
web/app.py:144
Finding

Directory Traversal Through User-Controlled Download Directory

Content
View full analysis
/') def download(date, filename): """Download generated file""" directory = os.path.join(BASE_MUSIC_DIR, date) return send_from_directory(directory, filename, as_attachment=True) ``` ### Technical Analysis The route treats the user-controlled `date` parameter as a trusted directory component. It joins this value to `BASE_MUSIC_DIR` before passing the result to `send_from_directory`. `send_from_directory` protects the requested filename relative to the directory supplied by the application, but it assumes that its `directory` argument is trusted. It does not establish that the separately constructed directory remains beneath `BASE_MUSIC_DIR`. A traversal value such as `..`, when accepted through an encoded URL segment, causes the effective serving directory to become the parent of the intended music directory. The attacker can then request a known filename from that parent directory. ### Attack Path 1. The Flask service is running and reachable by the attacker. 2. The attacker sends a request containing an encoded parent-directory segment in the `date` position, for example: `GET /download/%2e%2e/known-file.txt` 3. The application constructs a directory equivalent to: `~/Desktop/music/..` 4. This resolves to `~/Desktop`. 5. `send_from_directory` safely resolves `known-file.txt` relative to the wrong, attacker-selected serving root. 6. If that file exists and the process can read it, Flask returns it as a download. ### Impact Assessment The vulnerability can disclose files outside `~/Desktop/music`, initially within directories reachable through the manipulated serving root. Exploitation requires knowledge or guessing of filenames, and access remains constrained by the operating-system permissions of ...[truncated 222 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
web/app.py:157
Finding

Unauthenticated and CSRF-Prone Service Shutdown Endpoint

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
start_server.py:11
Finding

Automatic Installation of Unpinned Runtime Dependencies

Content
View full analysis
` without a pinned version or hash. 5. Pip resolves the package and transitive dependencies from its configured index at that moment. 6. A compromised or substituted package executes installation/build ...[truncated 637 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
web/app.py:164
Finding

Flask Development Debugger Enabled During Normal Startup

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The documentation makes strong claims about a full browser UI, playback, download, and complete web application behavior that static analysis indicates may not actually be present, while also omitting explicit permission disclosure for network and file-writing behavior. Security-relevant mismatches between documented and actual behavior can mislead users into running code with broader capabilities than they intended to trust.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

Storing an API key in browser localStorage is risky because any script running in the same origin, including injected or compromised frontend code, can read it. The documentation presents this as safe enough for convenience ('无文件溢出风险') without warning users that localStorage is not an appropriate place for long-lived secrets.

Content

No source excerpt is available for this finding.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
85% confidence
Finding

os.system() and os exec-family calls run shell commands with the process's full privileges, enabling arbitrary command execution.

Content

Scanner excerpt · start_server.py (reported line 46)May include surrounding context.

python
print()

    # Start the server
    os.execvp(sys.executable, [sys.executable, "app.py"])

if __name__ == "__main__":
    main()

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The /shutdown endpoint allows any caller to terminate the Flask process with no authentication, authorization, CSRF protection, or origin restriction. In a web app intended only for music generation, this creates an unnecessary remote denial-of-service capability that can be triggered trivially by any local user, webpage able to reach the service, or network peer if the app is exposed.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The endpoint performs immediate process termination via os._exit(0) without any disclosure, confirmation, or access control. Because this is destructive behavior unrelated to ordinary music playback/generation, it materially increases risk and can be abused for easy service disruption.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises and instructs use of capabilities that imply shell execution, network access, local file writes, and possible environment/API key handling, but it does not declare any tool scope or permissions. This creates a transparency and consent problem: users and the hosting platform cannot accurately assess what resources the skill may access before running it.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill states that generated files are automatically saved to the user's Desktop, but it does not prominently warn that local files will be created or describe what data will be written. Automatic writes to a user-visible directory can expose sensitive content, clutter the system, or overwrite expectations if filenames and paths are not carefully controlled.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/suno_client.py (reported line 10)May include surrounding context.

python
class AceSunoClient:
    """Python client for AceData Suno v5 music generation API"""
    
    def __init__(self, api_key: Optional[str] = None, base_url: str = "https://api.acedata.cloud/suno"):
        """
        Initialize the AceData Suno client

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The download helper fetches arbitrary URLs and writes their contents directly to local files with no user confirmation or trust validation. If the upstream API returns unexpected or attacker-controlled URLs, the skill can silently place untrusted files on disk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The client persists generated audio, images, and lyrics to a hard-coded desktop path, which introduces undeclared local data storage beyond simple API interaction. This can expose user content on disk without explicit consent, break least-surprise expectations, and create privacy or operational issues on shared systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The save routine automatically writes generated assets and lyrics to disk without user-facing notice or confirmation, creating silent local persistence of potentially sensitive or unwanted content. In the context of a music-generation skill, this is more dangerous because users may expect streamed or transient output rather than automatic desktop storage.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

A startup script for a music-generation web server should not need to silently modify the Python environment during normal execution. Runtime dependency installation increases supply-chain risk and can execute arbitrary package install hooks, making the skill more dangerous because users may run it expecting only a local server, not environment-changing behavior.

Content

No source excerpt is available for this finding.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · start_server.py (reported line 14)May include surrounding context.

python
def check_and_install(package):
    """Check if package is installed, install if not"""
    try:
        __import__(package)
        print("[OK] " + package + " already installed")
        return True
    except ImportError:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
83% confidence
Finding

This script automatically installs Python packages at runtime using pip, which changes the local environment and executes package installation logic without explicit user review. If package resolution is influenced by a compromised package index, dependency confusion, or a hostile Python/pip configuration, this can result in unintended code execution or environment compromise.

Content

Scanner excerpt · start_server.py (reported line 19)May include surrounding context.

python
return True
    except ImportError:
        print("Installing " + package + "...")
        subprocess.check_call([sys.executable, "-m", "pip", "install", package])
        return False

def main():

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The route accepts an api_key from the request and immediately constructs a client that will make an external generation call, but there is no user-facing warning, confirmation, or logging that sensitive credentials and prompt data are being sent to a remote service. Although the function has an internal docstring, it does not disclose this behavior to the user, so the network transmission and credential use are not visibly warned about in this code file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

Successful generation results are automatically saved under the user's Desktop music directory and appended to a local history JSON file containing prompts and URLs. The code performs these writes without any confirmation prompt or visible user-facing disclosure in this file that generated media and metadata will be persisted locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The API key is persisted in localStorage, which is accessible to any script running in the page origin, including malicious injected JavaScript if an XSS flaw exists anywhere in the app. Storing long-lived secrets this way increases exposure and gives users no warning that their credential remains on disk in the browser.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The generate flow sends the user's music prompt or lyrics together with the API key to the /generate backend endpoint via POST. Although the operation is functional, the interface does not disclose that entered content and credentials will be transmitted to the server, which is a safety-relevant omission for user data and privacy.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The UI exposes a direct shutdown action that sends a POST request to /shutdown, which is unrelated to the stated music-generation functionality and can be abused for denial of service if the backend does not strictly gate the endpoint. In a locally hosted app this may seem convenient, but embedding operational control into a general user interface increases the chance of accidental or unauthorized service termination.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The manifest describes a web application for generating and saving AI music, but this module also pulls secrets from the runtime environment via ACE_DATA_API_KEY. While common for developer tooling, credential harvesting from environment state is not part of the user-facing purpose as described.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency manifest specifies Flask without a version pin, which makes builds non-reproducible and can cause the application to install a vulnerable or incompatible release at deployment time. In a web application context, this is security-relevant because Flask has had past security advisories and the actual installed version cannot be verified from this file alone.

Content

Scanner excerpt · web/requirements.txt (reported line 1)May include surrounding context.

text
flask
requests

Unverifiable Dependency: flask has 10 known advisory(ies) (CVE-2025-47278 (Flask uses fallback key instead of current signing key); CVE-2018-1000656 (Flask is vulnerable to Denial of Service via incorrect encoding of JSON data); CVE-2019-1010083 (Pallets Project Flask is vulnerable to Denial of Service via Unexpected memory u) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding

Flask has known advisories, and because no version is pinned, it is impossible to verify whether the deployed package is affected or patched. For a browser-facing web app, uncertainty around the framework version increases exposure to web-layer issues such as denial of service, session handling weaknesses, or other framework-specific flaws.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency manifest specifies requests without a version pin, so installs may pull different versions over time, including releases with known security issues. Because this skill appears to call an external API, an unsafe or outdated requests version could expose the application to client-side HTTP-related vulnerabilities.

Content

Scanner excerpt · web/requirements.txt (reported line 2)May include surrounding context.

text
flask
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

Requests has multiple known advisories, and without a pinned version there is no assurance the installed library is free of those issues. Since this application integrates with a remote API, an affected requests version could increase the risk of credential leakage, TLS/verification mistakes, or other unsafe HTTP client behavior depending on usage.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The inline comment says the generation routine 'uses OpenClaw backend', but the implemented code posts collected AceData/Suno generation parameters to a local '/generate' endpoint. This documentation is actively misleading about what backend is actually being used.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.