T09 · Insecure Skill Coding Practices
- Location
SKILL.md:18- Finding
API Key Disclosed in Terminal Output
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent cloud TTS drama generator, but it needs Review because its own instructions can expose the SenseAudio API key in terminal output or command-line history.
Install only if you are comfortable sending generated dialogue to SenseAudio. Do not let the agent print your API key, do not pass it with --senseaudio-api-key, and prefer a protected environment variable or secret manager. Avoid using sensitive or proprietary story content unless you accept both the cloud TTS processing and the local saved JSON copy.
SKILL.md:18API Key Disclosed in Terminal Output
scripts/generate_drama.py:198API Key Accepted Through Command-Line Arguments
USAGE.md:8Unpinned Third-Party Dependency Installation
The natural-language description and example invocation are entirely in Chinese, and the file does not indicate that other languages are supported or that Chinese is a required, justified locale constraint. This can violate language/locale policy when a specific language is implicitly mandated without user opt-in.
The README describes automatic script generation and TTS synthesis but does not clearly warn users that their provided theme, generated dialogue, and character text will be transmitted to an external SenseAudio API. This creates a real transparency and privacy issue because users may unknowingly send sensitive or proprietary content to a third-party service with different retention or logging practices.
The skill instructs the agent to read an environment variable, write a temporary JSON file, invoke a Python script, and call an external TTS API, but it does not declare any tool scope or permission boundaries. That mismatch increases the chance of overbroad execution and secret exposure because the runtime may allow capabilities that are not explicitly constrained or auditable.
The trigger phrases are broad, natural-language requests like '帮我生成一个短剧' and '做一个有声剧', with no confirmation step or tighter scope constraints. Broad triggers can cause accidental invocation in unrelated conversations, leading the agent to generate files, access secrets, or make networked API calls when the user did not clearly intend to run this skill.
The guide explicitly recommends passing the SenseAudio API key on the command line, which can expose the secret through shell history, process listings, terminal logging, or CI/job telemetry. Even though this is documentation rather than executable code, it encourages an insecure operational practice that can lead to credential theft and unauthorized API usage.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# ============== API 配置 ==============
SENSEAUDIO_API_KEY = os.environ.get("SENSEAUDIO_API_KEY", "")
SENSEAUDIO_API_URL = "https://api.senseaudio.cn/v1/t2a_v2"
# 可用音色列表(voice_id → 描述)
VOICE_CATALOG = {
This code performs intentional external transmission of user-provided dialogue text and an API credential to a remote service. Although necessary for cloud TTS functionality, it still represents a genuine data exposure boundary and is more sensitive because the skill processes arbitrary user-authored content.
}
for retry in range(3):
try:
resp = requests.post(SENSEAUDIO_API_URL, json=payload, headers=headers, timeout=60)
result = resp.json()
if result.get("data") and result["data"].get("audio"):
return bytes.fromhex(result["data"]["audio"])
The script sends the full dialogue text to a third-party TTS service, which may include sensitive or proprietary user content, but it does not clearly warn the user at the point of use. In a skill context, users may assume processing is local, so silent external transmission creates a real privacy and data-handling risk.
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
final_wav = concat_wavs(wav_list, gap_sec=gap_sec)
os.makedirs(os.path.dirname(os.path.abspath(output_path)) or ".", exist_ok=True)
with open(output_path, 'wb') as f:
f.write(final_wav)
# 保存剧本 JSON
Natural-language policy violations include forcing a specific language without user opt-in. This skill presents its description, usage instructions, and examples only in Chinese, and it does not state that the skill is region-specific or offer an alternative language option.
The file title, instructions, examples, and expected prompts are all presented in Chinese, including the example invocation text at L024-L032. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale restriction is explicitly documented and justified, which is not present here.
The script persists both the generated audio and a full copy of the script JSON to disk without an explicit warning, which can unintentionally store sensitive content locally. This is a privacy issue rather than code execution, but it can expose user data to other local users, backups, or later accidental disclosure.
Detected: suspicious.exposed_secret_literal