Back to skill

Security audit

acestep

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent music-generation API client, but it needs Review because its helper script can expose API keys and can write outside its output folder when given unsafe job IDs.

Install only if you are comfortable with a Bash skill that sends prompts and lyrics to a configured ACE-Step service and writes generated files locally. Prefer HTTPS endpoints for any remote service, avoid storing API keys in the skill directory when possible, do not run config commands that print raw config, and avoid untrusted job IDs or untrusted ACE-Step-compatible servers until the filename validation issue is fixed.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/acestep.sh:214
Finding

Unvalidated job identifiers permit writes outside the output directory

Content
View full analysis
"$output_file" echo -e "${GREEN}Result saved: $output_file${NC}" } ``` ```bash if [ -n "$audio_path" ]; then local output_file="${OUTPUT_DIR}/${job_id}_${count}.${audio_format}" local download_url="${api_url}${audio_path}" echo -e " ${CYAN}Downloading audio $count...${NC}" ``` ```bash if [ -n "$audio_url" ]; then local output_file="${OUTPUT_DIR}/${job_id}_$((i+1)).${audio_format}" echo -e " ${CYAN}Decoding audio $((i+1))...${NC}" if decode_base64_audio "$audio_url" "$output_file"; then ``` ```bash local job_id job_id=$(jq -r '.id // empty' "$resp_file" 2>/dev/null) [ -z "$job_id" ] && job_id="completion-$(date +%s)" ``` The `status` command also accepts a user-supplied job identifier and eventually passes it to the same output functions: ```bash cmd_status() { check_deps local job_id="$1" [ -z "$job_id" ] && { echo -e "${RED}Error: job_id required${NC}"; echo "Usage: $0 status "; exit 1; } ``` ### Technical Analysis The script uses `job_id` directly as part of output filenames without validating that it is a single safe filename component. In normal generation flows, this value originates from an API response. In the `status` flow, it originates directly from a command-line argument. A value containing path separators or traversal components, such as `../../target`, causes the constructed path to resolve outside `OUTPUT_DIR`. The script subsequently writes result JSON, downloaded response bodies, or decoded audio data to that path. Shell quoting p ...[truncated 1635 chars]
Remediation
View remediation
&2 return 1 } [[ "$job_id" != "." && "$job_id" != ".." ]] || return 1 } ``` 2. Reject forward slashes, backslashes, traversal components, control characters, absolute paths, and empty identifiers. 3. Prefer generating a local random filename independent of the remote task identifier. Store the untrusted remote identifier only as JSON metadata. 4. Canonicalize the destination and verify containment before every write: ```bash output_root=$(realpath -m "$OUTPUT_DIR") destination=$(realpath -m "$OUTPUT_DIR/$safe_name") case "$destination" in "$output_root"/*) ;; *) echo "Error: output path escapes output directory" >&2; return 1 ;; esac ``` 5. Open output files defensively and avoid following attacker-created symbolic links where the platform permits. 6. Apply the same validation to generation responses, completion IDs, native task IDs, and `status` command arguments. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/acestep.sh:270
Finding

Configuration commands can disclose API credentials in plaintext

Content
View full analysis
Get value" echo " config --set Set value" echo " config --reset Reset to defaults" ;; ``` The documented safety guidance acknowledges this exposure: ```markdown NEVER use `config --get api_key` or read `config.json` directly — these would expose the user's API key. ``` ### Technical Analysis Although `config --list` masks configured API keys, two other supported execution paths expose them: - `config --get api_key` returns the raw credential. - Invoking `config` without a recognized action executes `cat "$CONFIG_FILE"`, printing the complete configuration. Documentation asks the Agent not to use these paths, but documentation is not an effective security boundary. The executable should enforce secret redaction consistently. Because Skill commands can be captured in Agent transcripts, CI logs, terminal history, support logs, or remote execution records, printing the token can create a persistent disclosure even if it is visible only briefly. ### Attack Path 1. A user configures an API key using `config --set api_key`. 2. The user, Agent, automated diagnostic process, or copied troubleshooting instruction invokes either: - `scripts/acestep.sh config`, or - `scripts ...[truncated 820 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/acestep.sh:81
Finding

API keys are persisted without enforced owner-only file permissions

Content
View full analysis
${NC}" echo -e " ${CYAN}./scripts/acestep.sh config --set api_key ${NC}" else echo "$DEFAULT_CONFIG" > "$CONFIG_FILE" fi fi } ``` ```bash set_config() { local key="$1" local value="$2" ensure_config local tmp_file="${CONFIG_FILE}.tmp" local jq_path=".${key}" if [ "$value" = "true" ] || [ "$value" = "false" ]; then jq "$jq_path = $value" "$CONFIG_FILE" > "$tmp_file" elif [[ "$value" =~ ^-?[0-9]+$ ]] || [[ "$value" =~ ^-?[0-9]+\.[0-9]+$ ]]; then jq "$jq_path = $value" "$CONFIG_FILE" > "$tmp_file" else jq "$jq_path = \"$value\"" "$CONFIG_FILE" > "$tmp_file" fi mv "$tmp_file" "$CONFIG_FILE" echo "Set $key = $value" } ``` ### Technical Analysis The Skill stores the bearer token directly in `scripts/config.json`. Configuration creation and updates rely on the caller's current `umask`; the script never enforces owner-only permissions such as mode `0600`. The update path also uses a predictable temporary filename, `config.json.tmp`, rather than securely creating a private temporary file. After `mv`, the destination inherits the temporary file's permissions. On a system with a permissive `umask`, the resulting credential file may be readable by other local users. Storing active secrets inside the distributed Skill directory also increases t ...[truncated 1126 chars]
Remediation
View remediation
"$tmp_file" mv -f "$tmp_file" "$CONFIG_FILE" ``` 5. Install a cleanup trap so temporary files are removed after errors or interruptions. 6. Keep the active configuration outside the package directory and add it to applicable version-control and packaging exclusion rules. 7. Avoid echoing the configured key in the success message when setting `api_key`; report only that the key was updated. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/acestep.sh:653
Finding

Bearer tokens and user content can be transmitted over plaintext HTTP

Content
View full analysis
Remediation
View remediation
&2 exit 1 fi ``` 3. Normalize and parse the URL rather than relying only on string matching in production code. Validate the scheme and resolved destination. 4. If plaintext remote HTTP must be supported for exceptional development environments, require an explicit opt-in and prohibit bearer-token transmission in that mode. 5. Update `SKILL.md` to use an HTTPS custom endpoint and clearly warn that prompts, lyrics, and tokens are transmitted to the selected service. 6. For HTTPS services, retain certificate verification and avoid adding insecure curl flags such as `-k` or `--insecure`. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file's manifest-style description says to use the skill when users mention generating music, creating songs, music production, remix, or audio continuation. Phrases like 'creating songs' and especially 'music production' are broad and lack constraints or exclusion conditions, which could cause unintended invocation for general music discussions rather than ACE-Step-specific tasks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill documents that it writes MP3 and JSON artifacts to the project filesystem, including prompts, lyrics, metadata, and generated outputs, but does not present this as an upfront user warning or consent requirement. This can expose sensitive user-provided lyrics, prompts, or metadata to other tools, collaborators, backups, or source control, especially because the JSON may contain full synthesis inputs and generation details.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
If jq is not installed, the script will attempt to install it automatically. If automatic installation fails:
- **Windows**: `choco install jq` or download from https://jqlang.github.io/jq/download/
- **macOS**: `brew install jq`
- **Linux**: `sudo apt-get install jq` (Debian/Ubuntu) or `sudo dnf install jq` (Fedora)

### Before First Use

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill explicitly instructs the agent to solicit, receive, and persist the user's ACE-Step API key via a config-setting command. While API-key setup is relevant to using the service, collecting and storing credentials inside a general music-generation skill expands the skill's scope into secret handling and creates risk of credential exposure through logs, shell history, config files, or later tool access. The context makes this more dangerous because the skill also permits Bash and file operations, increasing the chance that stored secrets are later read or leaked.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script persists the API key in a local JSON config file and offers a CLI path to set it, but does not warn the user about plaintext local storage, file permissions, or safer alternatives. In an agent-skill context, this can expose credentials to other local users, logs, backups, or later accidental disclosure via the same script.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The config --reset path unconditionally writes default contents to config.json, replacing any existing settings including a previously configured API URL or key. This is a file write that discards prior configuration, and there is no confirmation prompt before the destructive overwrite occurs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The default config display path uses cat on the full config file, which includes the stored api_key in cleartext. This can leak credentials to terminal history capture, screen sharing, agent transcript logging, CI logs, or other observation channels, making it more dangerous in a tool/skill environment where outputs are often recorded.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/acestep.sh (reported line 313)May include surrounding context.

sh
echo "Available Models:"
    echo "----------------------------------------"
    if [ -n "$api_key" ]; then
        curl -s -H "Authorization: Bearer ${api_key}" "${api_url}/v1/models"
    else
        curl -s "${api_url}/v1/models"
    fi

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/acestep.sh (reported line 659)May include surrounding context.

sh
local http_code
    if [ -n "$api_key" ]; then
        http_code=$(curl -s -w "%{http_code}" --connect-timeout 10 --max-time 660 \
            -o "$resp_file" \
            -X POST "${api_url}/v1/chat/completions" \
            -H "Content-Type: application/json; charset=utf-8" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/acestep.sh (reported line 933)May include surrounding context.

sh
local api_key=$(load_api_key)
        local response
        if [ -n "$api_key" ]; then
            response=$(curl -s -X POST "${api_url}/release_task" \
                -H "Content-Type: application/json; charset=utf-8" \
                -H "Authorization: Bearer ${api_key}" \
                --data-binary "@${temp_payload}")

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/acestep.sh (reported line 1022)May include surrounding context.

sh
local api_key=$(load_api_key)
        local response
        if [ -n "$api_key" ]; then
            response=$(curl -s -X POST "${api_url}/release_task" \
                -H "Content-Type: application/json; charset=utf-8" \
                -H "Authorization: Bearer ${api_key}" \
                --data-binary "@${temp_payload}")

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The configuration sets "vocal_language" to "en", which hard-codes a specific language choice. For a policy check that applies to all file types, this is a natural-language locale constraint with no indication of user choice or documented region-specific justification in the file.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This manifest file hard-codes vocal_language to en, but there is no indication in the file that users can choose another language or that the English-only setting is justified by a narrow regional or compliance context. For manifest/config files, this can also make activation or behavior scope less explicit because the language constraint is implicit rather than clearly bounded.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The vocal_language field is set to en, which enforces a specific language/locale in the skill configuration. Under the policy, language restrictions should either offer user choice or be clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file states that audio is auto-decoded and saved to acestep_output/, which is a file-writing behavior affecting the user's filesystem. The description does not include a caution, confirmation note, or user-facing warning about where files are written or that disk contents will be modified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script sets LANG and LC_ALL to en_US.UTF-8 whenever they are unset, imposing a specific locale choice. This is a natural-language and locale policy concern because the script selects a language/locale default without offering the user an explicit choice or documenting a justified regional requirement.

Content

No source excerpt is available for this finding.