T09 · Insecure Skill Coding Practices
- Location
helper.py:393- Finding
Default Plaintext Debug Logging Exposes User Content and Complete API Responses
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This voiceover skill is mostly coherent, but it automatically saves detailed plaintext debug files containing user text and responses.
Review before installing if you will process confidential scripts, personal data, or proprietary content. The skill sends text to SenseAudio and, more importantly, helper.py automatically leaves a detailed .debug.json beside generated audio; delete those logs or modify the helper before using sensitive material. Keep the API key in the environment rather than source files.
helper.py:393Default Plaintext Debug Logging Exposes User Content and Complete API Responses
声明描述强调的是短视频配音助手,核心卖点包括多角色音色映射、自动语速调节和 BGM 建议。但代码实际只提供两个子命令:synthesize 和 concat。synthesize 读取文本文件并调用 SenseAudio TTS 接口生成音频,支持可选的 voice、speed、pitch、vol 和音频格式参数;concat 仅通过 ffmpeg 进行音频拼接。代码中虽然有文本清洗、去角色前缀、重试、回退 voice_id、调试日志等辅助逻辑,但没有任何基于角色到音色的映射机制、没有自动计算语速的算法,也没有与 BGM 推荐相关的处理、模型调用或输出。因此声明与实际行为存在明显功能性不一致,且实际主用途更接近“通用 TTS 请求/拼接助手”而非所宣称的专业级短视频配音助手。
Referenced artifact was not completely inspected
先检查环境变量 `SENSEAUDIO_API_KEY`。如果已经存在,直接使用;如果不存在,再提示用户提供 API Key 或先在终端设置环境变量。不要把密钥写进 `SKILL.md`、脚本源码或提交记录。
The skill declares powerful capabilities via required binaries, environment secret access, local file operations, network calls, and shell command examples, but it does not define an explicit tool scope or allowed-tools boundary. That makes the effective privilege surface broader and less auditable, increasing the chance an agent executes unintended shell/network actions with access to sensitive files or secrets.
The manifest description and the full user-facing guidance force a specific language/locale for interaction. Under the policy, language constraints should either be optional for the user or clearly justified as region-specific; this file provides neither an opt-in nor a justification.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
API 地址固定为:
https://api.senseaudio.cn/v1/t2a_v2
优先使用 jq 构造 JSON,避免转义错误。默认走非流式模式,便于直接拿到 hex 音频并落盘。
The skill sends user-provided text and an authorization bearer token to an external third-party API. This is expected for a cloud TTS workflow, but it is still a real data-exfiltration boundary: potentially sensitive scripts, prompts, or personal content leave the local environment, and misuse or logging by the third party could expose them.
voice_id: $voice_id
}
}' |
curl -sS "https://api.senseaudio.cn/v1/t2a_v2" \
-H "Authorization: Bearer $SENSEAUDIO_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @-
The skill sends user-provided text and an authorization bearer token to an external third-party API. This is expected for a cloud TTS workflow, but it is still a real data-exfiltration boundary: potentially sensitive scripts, prompts, or personal content leave the local environment, and misuse or logging by the third party could expose them.
voice_id: $voice_id
}
}' |
curl -sS "https://api.senseaudio.cn/v1/t2a_v2" \
-H "Authorization: Bearer $SENSEAUDIO_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @-
The code performs external transmission of user text and authorization credentials to a remote API endpoint, which is a real data-exposure boundary. In the context of a dubbing assistant, this may be functionally necessary, but it still creates privacy, compliance, and third-party trust risk if users are not clearly informed or if sensitive material is processed.
from pathlib import Path
API_URL = "https://api.senseaudio.cn/v1/t2a_v2"
MODEL_NAME = "SenseAudio-TTS-1.0"
FALLBACK_VOICE_IDS = ["child_0001_b", "male_0004_a", "male_0018_a"]
RETRYABLE_HTTP_STATUS_CODES = {500, 502, 503, 504}
The helper transmits user-supplied text to a remote third-party TTS service without any explicit disclosure, consent flow, or local-only alternative. In this skill context, users may reasonably assume they are just generating audio, not exporting potentially sensitive script contents to an external provider, which raises privacy and data-governance concerns.
The code writes detailed debug logs containing full text variants, request payloads, and response bodies to disk automatically, including on failure. For a voiceover tool, input text may contain sensitive scripts, personal data, or proprietary content, so persistent local logging creates an unnecessary confidentiality risk and expands exposure if the host is shared or compromised.
The manifest describes a short-video dubbing assistant focused on voice mapping, speech-rate adjustment, and BGM suggestions. In this file, the skill also executes a local system binary via subprocess to concatenate arbitrary audio files, which is a broader host-execution capability than the manifest suggests and is not clearly justified by the stated scope.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
ffmpeg = "ffmpeg"
try:
subprocess.run(
[ffmpeg, "-version"],
check=True,
stdout=subprocess.DEVNULL,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"copy",
str(output),
]
result = subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8", errors="replace")
if result.returncode != 0:
raise SystemExit(result.stderr.strip() or "ffmpeg concat failed.")
The code fixes service use to a single provider endpoint under api.senseaudio.cn, which can impose a locale or regional routing choice on all users without opt-in. The policy calls for flagging language or locale constraints when they are forced rather than user-selectable or explicitly justified.