Back to skill

Security audit

acestep-lyrics-transcription

Security checks for vulnerabilities and agentic risk

Overview

This transcription skill is mostly purpose-aligned, but it has serious implementation weaknesses that could expose API keys or run unintended local code with crafted inputs.

Review this skill before installing. It does what it says at a high level, but only use it with non-sensitive audio and disposable or tightly scoped API keys until the output-path, jq, and credential-handling issues are fixed. Avoid custom output paths containing special characters, do not rely on config --get for secrets, and ensure any stored config file is protected.

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-lyrics-transcription.sh:147
Finding

Arbitrary Python Code Execution Through Crafted Output Path

Content
View full analysis
{fmt(e)}\n') f.write(f'{text}\n') f.write('\n') " } ``` The value originates from the user-controlled `--output` argument: ```bash --output|-o) output="$2"; shift 2 ;; ``` It is subsequently passed to the vulnerable conversion function: ```bash case "$format" in lrc) words_to_lrc "$words_file" "$output" ;; srt) words_to_srt "$words_file" "$output" ;; json) cp "$words_file" "$output" ;; esac ``` ### Technical Analysis Shell quoting protects the output path while it is handled by Bash, but it does not make the value safe when it is inserted into dynamically constructed Python source code. A path containin ...[truncated 1831 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/acestep-lyrics-transcription.sh:118
Finding

API Keys Are Exposed Through Command Arguments and Unmasked Output

Content
View full analysis
"$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" } ``` The generic getter also returns API keys without masking: ```bash "get") [ -z "$key" ] && { echo -e "${RED}Error: --get requires KEY${NC}"; exit 1; } local result=$(get_config "$key") [ -n "$result" ] && echo "$key = $result" || echo "Key not found: $key" ;; ``` The documentation instructs users or Agents to place keys directly in command arguments: ```bash bash ./scripts/acestep-lyrics-transcription.sh config --set .api_key ``` ```bash ./scripts/acestep-lyrics-transcription.sh config --set openai.api_key sk-... ./scripts/acestep-lyrics-transcription.sh config --set elevenlabs.api_key ... ``` This conflicts with the documentation's security requirement: ```markdown **NEVER read or display the user's API key content.** Do not use `config --get` on key fields or read `config.json` directly. ``` ### Technical Analysis Passing an API key as a command-line argument can expose it through shell history, command auditing, process inspection, terminal recording, o ...[truncated 1750 chars]
Remediation
View remediation
&2 exit 1 fi ``` 3. Replace command-line key arguments with one of the following: - A silent interactive prompt using `read -r -s`. - Standard input with clear controls preventing logging. - Provider-specific environment variables. - An operating-system credential store or secret manager. 4. If environment variables are supported, avoid printing them and clear temporary shell variables after use where practical. 5. Update `SKILL.md` so the documented setup flow does not place credentials in command arguments. 6. Rotate any keys that may already have appeared in shell history, process logs, Agent transcripts, or CI output. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/acestep-lyrics-transcription.sh:87
Finding

Plaintext API-Key Configuration Is Created Without Restrictive Permissions

Content
View full analysis
${NC}" echo -e " ${CYAN}./scripts/acestep-lyrics-transcription.sh config --set .api_key ${NC}" else echo "$DEFAULT_CONFIG" > "$CONFIG_FILE" fi fi } ``` Configuration changes use a predictable temporary filename and replace the original file without enforcing its mode: ```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 script persists OpenAI and ElevenLabs API keys as plaintext JSON. It does not set a restrictive `umask`, create the file with mode `0600`, ver ...[truncated 1484 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/acestep-lyrics-transcription.sh:102
Finding

Configuration Key and Value Injection Into jq Programs

Content
View full analysis
/dev/null) if [ "$value" = "null" ]; then echo "" else echo "$value" | tr -d '\r\n' fi } ``` Both the key and string value are interpolated into an executable jq program: ```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" } ``` The arguments are accepted without an allowlist: ```bash --get) action="get"; key="$2"; shift 2 ;; --set) action="set"; key="$2"; value="$3"; shift 3 ;; ``` ### Technical Analysis `jq` treats its filter argument as program source. Concatenating untrusted data into that source permits a crafted key or quoted value to terminate the intended path or string expression and append additional jq filters. This is not shell-command injection: jq does not inherently execute arbitrary operating-system commands. However, it permits unintended reads and transformations of configuration data and can overwrite fields outside the nominal key selected by the caller. The configuration includes `api_url`, `api_key`, `provid ...[truncated 1522 chars]
Remediation
View remediation
&2 exit 1 ;; esac ``` 2. Pass values with `--arg` or `--argjson` instead of concatenating them into jq source: ```bash jq --arg key "$key" --arg value "$value" \ 'setpath($key | split("."); $value)' \ "$CONFIG_FILE" > "$tmp_file" ``` 3. Use `getpath` for reads: ```bash jq -r --arg key "$key" 'getpath($key | split(".")) // empty' "$CONFIG_FILE" ``` 4. Apply explicit type validation after identifying the field. Validate `provider` and `output_format` against fixed enumerations. 5. Validate API URLs before storing or using them: - Require HTTPS. - Restrict hosts to approved provider domains unless custom endpoints are an explicit trusted feature. - Do not attach credentials when the destination is outside an approved origin. 6. Validate the resulting JSON against a fixed schema before replacing the active configuration. 7. Write updates to a securely created temporary file and perform an atomic replacement only after all validation succeeds. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (15)

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/acestep-lyrics-transcription.sh (reported line 442)May include surrounding context.

sh
case "$provider" in
        openai)   transcribe_openai "$audio" "$language" "$words_file" ;;
        elevenlabs) transcribe_elevenlabs "$audio" "$language" "$words_file" ;;
        *) echo -e "${RED}Error: unknown provider: $provider${NC}"; echo "Supported: openai, elevenlabs"; rm -f "$words_file"; exit 1 ;;
    esac

    # Check if we got words

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

text
6. After configuring, re-run `config --check-key` to verify the key is set before proceeding.

**If the API key is already configured**, proceed directly to transcription without asking.

## Quick Start

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest presents the capability as transcription, but the workflow goes further by performing semantic correction using external lyric references and rewriting the output file. This mismatch can cause an agent or user to trust the skill as a simple transform of the audio when it is actually incorporating additional data sources and making substantive content edits.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill is described as audio transcription, but it instructs the agent to read an ACE-Step output JSON file containing original lyrics and use that external content to modify the transcription. This expands access beyond the user-provided audio input and can pull in unrelated or copyrighted source material, violating least-privilege expectations for a transcription skill.

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 · SKILL.md (reported line 142)May include surrounding context.

md
"output_format": "lrc",
  "openai": {
    "api_key": "",
    "api_url": "https://api.openai.com/v1",
    "model": "whisper-1"
  },
  "elevenlabs": {

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/acestep-lyrics-transcription.sh (reported line 75)May include surrounding context.

sh
"output_format": "lrc",
  "openai": {
    "api_key": "",
    "api_url": "https://api.openai.com/v1",
    "model": "whisper-1"
  },
  "elevenlabs": {

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/acestep-lyrics-transcription.sh (reported line 294)May include surrounding context.

sh
"output_format": "lrc",
  "openai": {
    "api_key": "",
    "api_url": "https://api.openai.com/v1",
    "model": "whisper-1"
  },
  "elevenlabs": {

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/config.example.json (reported line 6)May include surrounding context.

json
"output_format": "lrc",
  "openai": {
    "api_key": "",
    "api_url": "https://api.openai.com/v1",
    "model": "whisper-1"
  },
  "elevenlabs": {

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 · SKILL.md (reported line 145)May include surrounding context.

md
},
  "elevenlabs": {
    "api_key": "",
    "api_url": "https://api.elevenlabs.io/v1",
    "model": "scribe_v2"
  }
}'

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/acestep-lyrics-transcription.sh (reported line 80)May include surrounding context.

sh
},
  "elevenlabs": {
    "api_key": "",
    "api_url": "https://api.elevenlabs.io/v1",
    "model": "scribe_v2"
  }
}'

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/acestep-lyrics-transcription.sh (reported line 352)May include surrounding context.

sh
},
  "elevenlabs": {
    "api_key": "",
    "api_url": "https://api.elevenlabs.io/v1",
    "model": "scribe_v2"
  }
}'

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/config.example.json (reported line 11)May include surrounding context.

json
},
  "elevenlabs": {
    "api_key": "",
    "api_url": "https://api.elevenlabs.io/v1",
    "model": "scribe_v2"
  }
}'

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script uploads user-supplied audio to the OpenAI transcription API, but it does not provide an explicit warning or confirmation at the point of transmission. In a skill context, this can cause unintended disclosure of sensitive audio content because users may assume processing is local unless clearly told otherwise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The ElevenLabs path sends the provided audio file to a third-party speech-to-text service without an explicit warning immediately before transmission. This creates a privacy risk because song files, recordings, or embedded personal audio may be exfiltrated off-host without sufficiently informed user consent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script unconditionally sets LANG and LC_ALL to en_US.UTF-8 when they are unset, which imposes a specific locale choice in natural-language-related processing. This can violate language/locale policy when users are not offered a choice or informed of the override.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.