Back to skill

Security audit

Doubao ASR Flash

Security checks for vulnerabilities and agentic risk

Overview

This is a legitimate Doubao transcription skill, but it needs review because it uploads recordings to Volcengine and unnecessarily copies the API key into the request body.

Install only if you are comfortable sending selected recordings or audio URLs to Volcengine/ByteDance for processing and with the associated billing. Protect the API key with restrictive file permissions or an environment secret, avoid passing it on the command line, and prefer a patched version that does not place the API key in user.uid.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/asr.py:156
Finding

API Key Duplicated into the Request Body as a User Identifier

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
SKILL.md:37
Finding

Agent-Facing Setup Instructions Store the API Key Without Enforcing Restrictive Permissions

Content
View full analysis
~/.config/doubao-asr/config.json <<'EOF' {"api_key": "[REDACTED API KEY]"} EOF ``` ### Technical Analysis The Agent-facing setup procedure writes a persistent plaintext API key but does not set a restrictive umask or explicitly apply permissions to either the directory or configuration file. The resulting permissions therefore depend on the user's current umask. On a system with a permissive umask, another local account may be able to traverse the configuration directory or read the credential file. This is inconsistent with the safer procedure in `README.md`, which applies `chmod 600` to the resulting file. Persisting a credential is compatible with the declared functionality, but allowing its confidentiality to depend entirely on ambient permission defaults is not a least-privilege configuration. ### Attack Path 1. An agent or user follows the setup commands in `SKILL.md`. 2. The API key is written in plaintext to `~/.config/doubao-asr/config.json`. 3. The current umask permits group or other users to read the resulting file, or the directory permissions permit unintended access. 4. Another local account reads the configuration file. 5. The local attacker extracts the API key and uses it to make unauthorized requests against the services permitted by that credential. This path requires local filesystem access and permissive resulting permissions; it is not remotely exploitable by the Skill alone. ### Impact Assessment An attacker who obtains the key may consume authorized ASR services, incur charges, exhaust quotas, or disrupt availability associated with the user's account. The vulnerability does not itself provide elevated local ...[truncated 136 chars]
Remediation
View remediation
"$HOME/.config/doubao-asr/config.json" <<'EOF' {"api_key": "[YOUR API KEY]"} EOF chmod 600 "$HOME/.config/doubao-asr/config.json" ``` Additional hardening should include: - Keep `SKILL.md` and `README.md` consistent about required permissions. - Validate at runtime that the configuration file is owned by the current user and is not readable by group or other users. - Emit a clear warning or refuse to load credentials when permissions are unsafe. - Prefer an operating-system credential manager or secret store where available. - Avoid passing the key through `--api-key` when possible because command-line arguments may be visible to other local processes or retained in shell history. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (14)

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

把 Key 存到配置文件(推荐,持久化):

bash
mkdir -p ~/.config/doubao-asr
printf '{"api_key": "你的API Key"}\n' > ~/.config/doubao-asr/config.json
chmod 600 ~/.config/doubao-asr/config.json

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

把 Key 存到配置文件(推荐,持久化):

bash
mkdir -p ~/.config/doubao-asr
printf '{"api_key": "你的API Key"}\n' > ~/.config/doubao-asr/config.json
chmod 600 ~/.config/doubao-asr/config.json

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · README.md (reported line 56)May include surrounding context.

bash
mkdir -p ~/.config/doubao-asr
printf '{"api_key": "你的API Key"}\n' > ~/.config/doubao-asr/config.json
chmod 600 ~/.config/doubao-asr/config.json

或使用环境变量:export DOUBAO_ASR_API_KEY="你的API Key",或每次调用 --api-key。

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documentation instructs use of shell, filesystem, environment variables, and outbound network access, but the manifest declares no explicit tool scope or permissions boundaries. That creates an over-privileged integration surface where an agent may invoke the skill without clear least-privilege constraints, increasing the chance of unintended file access, secret handling, or network exfiltration.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest says to use the skill whenever the user wants to transcribe or generate text from audio/video, which is a broad trigger phrase that can cause over-invocation. In an agentic system, overly broad routing increases the chance that unrelated user content, sensitive local files, or private URLs get sent to an external ASR provider without sufficiently specific user intent.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

This is a duplicate persistence issue on the same line: long-lived storage of an API credential in a predictable path increases secret exposure risk. In context, the skill uploads user audio to a third-party service, so compromise of the key could enable unauthorized API usage and billing abuse.

Content

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

bash
# 方式 A(推荐,持久):写入配置文件
mkdir -p ~/.config/doubao-asr
cat > ~/.config/doubao-asr/config.json <<'EOF'
{"api_key": "你的API Key"}
EOF

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

This is a duplicate persistence issue on the same line: long-lived storage of an API credential in a predictable path increases secret exposure risk. In context, the skill uploads user audio to a third-party service, so compromise of the key could enable unauthorized API usage and billing abuse.

Content

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

bash
# 方式 A(推荐,持久):写入配置文件
mkdir -p ~/.config/doubao-asr
cat > ~/.config/doubao-asr/config.json <<'EOF'
{"api_key": "你的API Key"}
EOF

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

脚本位于 scripts/asr.py(相对 skill 目录),用绝对路径调用:

bash
# 假设 skill 已安装到 <你的 skills 目录>/doubao-asr/(如 ~/.pi/agent/skills/doubao-asr 或 ~/.claude/skills/doubao-asr)
ASR="<你的 skills 目录>/doubao-asr/scripts/asr.py"
PYTHONIOENCODING=utf-8 python3 "$ASR" /path/to/录音.m4a            # 转文字
PYTHONIOENCODING=utf-8 python3 "$ASR" /path/to/会议.mp4            # 视频自动提取音频

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

脚本位于 scripts/asr.py(相对 skill 目录),用绝对路径调用:

bash
# 假设 skill 已安装到 <你的 skills 目录>/doubao-asr/(如 ~/.pi/agent/skills/doubao-asr 或 ~/.claude/skills/doubao-asr)
ASR="<你的 skills 目录>/doubao-asr/scripts/asr.py"
PYTHONIOENCODING=utf-8 python3 "$ASR" /path/to/录音.m4a            # 转文字
PYTHONIOENCODING=utf-8 python3 "$ASR" /path/to/会议.mp4            # 视频自动提取音频

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The module docstring, CLI descriptions, status messages, and setup instructions are all presented exclusively in Chinese, with no indication that language selection is optional or that the skill is intentionally limited to a Chinese-speaking context. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/asr.py (reported line 87)May include surrounding context.

python
def check_ffmpeg() -> bool:
    try:
        subprocess.run(["ffmpeg", "-version"], capture_output=True, timeout=10)
        return True
    except Exception:
        return False

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/asr.py (reported line 96)May include surrounding context.

python
def probe_duration(path: str) -> Optional[float]:
    """用 ffprobe 获取音频时长(秒),失败返回 None。"""
    try:
        r = subprocess.run(
            ["ffprobe", "-v", "error", "-show_entries", "format=duration",
             "-of", "json", path],
            capture_output=True, text=True, timeout=60,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/asr.py (reported line 113)May include surrounding context.

python
"-vn", "-ar", "16000", "-ac", "1", "-b:a", "64k",
        dst,
    ]
    r = subprocess.run(cmd, capture_output=True, text=True, timeout=1800)
    if r.returncode != 0:
        print(f"ffmpeg 转码失败:\n{r.stderr[-2000:]}", file=sys.stderr)
        sys.exit(2)

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The script transmits audio content, or a user-supplied public URL to audio content, to a third-party external API. In this skill context that behavior is expected, but it still creates a real data-exposure risk because potentially sensitive recordings, transcripts, and a user identifier are sent off-host without any explicit consent check, redaction step, or allowlist enforcement.

Content

Scanner excerpt · scripts/asr.py (reported line 169)May include surrounding context.

python
"request": {"model_name": "bigmodel"},
    }
    # 大文件 base64 上传可能较慢;2h 音频 flash 处理一般 1~3 分钟
    r = requests.post(FLASH_URL, json=payload, headers=headers, timeout=900)
    status_code = r.headers.get("X-Api-Status-Code", "")
    message = r.headers.get("X-Api-Message", "")
    logid = r.headers.get("X-Tt-Logid", "")

Static analysis

No suspicious patterns detected.