T09 · Insecure Skill Coding Practices
- Location
scripts/volc_voice.py:37- Finding
Symlink Bypass Allows Unauthorized Local File Disclosure to an External ASR Service
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This voice skill is mostly purpose-aligned, but its ASR file handling and generated Feishu message commands create review-worthy risks before installation.
Review this before installing if the agent may process untrusted file paths or message IDs. It should restrict ASR input to the intended Feishu inbound media directory, resolve and reject symlinks, validate audio files, return structured message data instead of executable-looking command strings, and pin dependencies. Use a dedicated Volcengine token with minimal scope.
scripts/volc_voice.py:37Symlink Bypass Allows Unauthorized Local File Disclosure to an External ASR Service
scripts/feishu_voice.py:112Unescaped Values Are Embedded in Agent Tool-Call Instructions
requirements.txt:1Unpinned Runtime Dependencies Create Non-Reproducible Supply-Chain Exposure
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
query_headers["X-Tt-Logid"] = x_tt_logid
for i in range(120):
query_response = requests.post(ASR_QUERY_URL, data=json.dumps({}), headers=query_headers)
if 'X-Api-Status-Code' in query_response.headers:
code = query_response.headers["X-Api-Status-Code"]
The skill description presents a full Feishu voice interaction pipeline and a strict response policy, but the file only documents ASR/TTS helper scripts and relies on other components to receive and send messages. This mismatch can mislead operators and agents about what security boundaries, external data flows, and messaging actions are actually implemented, causing unsafe assumptions during deployment.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
## 前置准备
1. **注册火山引擎账号**: 访问 [火山引擎语音服务控制台](https://console.volcengine.com/speech/app)。
2. **创建应用**: 在控制台创建一个应用,获取 `AppID` 和 `Access Token`(**注意**:这是语音服务的凭证,不同于火山引擎 ARK API 的 Key)。
3. **开通服务**: 为应用开通「**大模型语音合成 TTS**」和「**大模型录音文件识别 ASR**」两个服务。
4. **安装依赖**: `pip install -r requirements.txt`
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
## 前置准备
1. **注册火山引擎账号**: 访问 [火山引擎语音服务控制台](https://console.volcengine.com/speech/app)。
2. **创建应用**: 在控制台创建一个应用,获取 `AppID` 和 `Access Token`(**注意**:这是语音服务的凭证,不同于火山引擎 ARK API 的 Key)。
3. **开通服务**: 为应用开通「**大模型语音合成 TTS**」和「**大模型录音文件识别 ASR**」两个服务。
4. **安装依赖**: `pip install -r requirements.txt`
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
logger = logging.getLogger(__name__)
script_dir = os.path.dirname(os.path.abspath(__file__))
skill_env_path = os.path.join(script_dir, '..', '.env')
# 加载 Skill 本地 .env 配置 / Load skill local .env config
# TTS/ASR 凭证(VOLC_APPID + VOLC_ACCESS_TOKEN)配置在 skills/.env 中
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
script_dir = os.path.dirname(os.path.abspath(__file__))
skill_env_path = os.path.join(script_dir, '..', '.env')
# 加载 Skill 本地 .env 配置 / Load skill local .env config
# TTS/ASR 凭证(VOLC_APPID + VOLC_ACCESS_TOKEN)配置在 skills/.env 中
load_dotenv(skill_env_path, override=True)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
script_dir = os.path.dirname(os.path.abspath(__file__))
skill_env_path = os.path.join(script_dir, '..', '.env')
# 加载 Skill 本地 .env 配置 / Load skill local .env config
# TTS/ASR 凭证(VOLC_APPID + VOLC_ACCESS_TOKEN)配置在 skills/.env 中
load_dotenv(skill_env_path, override=True)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
script_dir = os.path.dirname(os.path.abspath(__file__))
skill_env_path = os.path.join(script_dir, '..', '.env')
# 加载 Skill 本地 .env 配置 / Load skill local .env config
# TTS/ASR 凭证(VOLC_APPID + VOLC_ACCESS_TOKEN)配置在 skills/.env 中
load_dotenv(skill_env_path, override=True)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
script_dir = os.path.dirname(os.path.abspath(__file__))
skill_env_path = os.path.join(script_dir, '..', '.env')
# 加载 Skill 本地 .env 配置 / Load skill local .env config
# TTS/ASR 凭证(VOLC_APPID + VOLC_ACCESS_TOKEN)配置在 skills/.env 中
load_dotenv(skill_env_path, override=True)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
script_dir = os.path.dirname(os.path.abspath(__file__))
skill_env_path = os.path.join(script_dir, '..', '.env')
# 加载 Skill 本地 .env 配置 / Load skill local .env config
# TTS/ASR 凭证(VOLC_APPID + VOLC_ACCESS_TOKEN)配置在 skills/.env 中
load_dotenv(skill_env_path, override=True)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""检查必要的环境变量配置 / Check required environment variables"""
if not APPID or not ACCESS_TOKEN:
logger.error("Error: 请在 skills/feishu-voice-chat/.env 中配置 VOLC_APPID 和 VOLC_ACCESS_TOKEN")
logger.error("Error: Please configure VOLC_APPID and VOLC_ACCESS_TOKEN in skills/.env")
sys.exit(1)
The skill declares capabilities that involve shell execution, network access, environment-variable use, and file writes, but it does not define any explicit tool scope or allowed-tools boundary. In an agent environment, this increases the chance that the skill can invoke more powerful operations than intended, making misuse or prompt-driven tool abuse easier.
The skill description and behavior are specified entirely in Chinese and mandate a fixed response mode for voice interactions, without indicating that users can choose another language or locale. This can violate language/locale policy when the skill is used in broader contexts where user language preference is not guaranteed to be Chinese.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
print(f"🎙️ 正在识别语音: {audio_path}", flush=True)
try:
result = subprocess.run(
[sys.executable, str(SCRIPT_PATH), "asr", audio_path],
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
print(f"🔊 正在合成语音: {text[:50]}...", flush=True)
try:
result = subprocess.run(
[sys.executable, str(SCRIPT_PATH), "tts", text, output_path],
capture_output=True,
text=True,
The skill is presented as a voice ASR/TTS wrapper, but it emits executable-looking message tool command strings that can trigger outbound Feishu sends or replies. Mixing content generation with action-invocation strings increases the chance that another agent component treats this output as trusted instructions, enabling unintended message actions or confused-deputy behavior.
The manifest describes a voice-processing skill that performs ASR and TTS for Feishu voice messages, but it does not mention local command execution or dependence on external system binaries. This code calls ffmpeg via subprocess to transform audio, introducing process-execution capability beyond the stated purpose and trust model.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
'-f', 'ogg',
output_path
]
result = subprocess.run(cmd, capture_output=True, timeout=60)
if result.returncode == 0 and os.path.exists(output_path):
logger.info(f"转换成功: {output_path}")
return True
The TTS payload hard-codes "explicit_language":"zh", which imposes a specific language setting on generated speech. This is a natural-language policy concern because the skill does not offer the user a language choice or document this as a justified region-specific constraint.
The dependency list includes requests without a version pin, making builds non-reproducible and allowing different environments to resolve to different releases. This is risky here because static analysis already indicates multiple known advisories for this package, so the skill could unknowingly install a vulnerable version.
requests
python-dotenv
The manifest does not specify which requests version is installed, while the package has numerous known advisories, including credential leakage and TLS/verification-related issues. In a voice-chat skill that likely performs network requests to external APIs, a vulnerable requests release could expose secrets, mishandle transport security, or leak credentials during outbound communication.
python-dotenv is also unpinned, which means dependency resolution may vary over time and across deployments. Because the package has known advisories and no version is specified, there is no assurance that installation will avoid affected releases.
requests
python-dotenv
python-dotenv has known advisories, and because no version is pinned, the deployed version may be affected. The likely impact is lower than for active network libraries, but if the skill writes or manages .env files in tooling or deployment flows, a vulnerable release could contribute to configuration tampering or file overwrite issues.
The file’s user-facing descriptions and outputs are hardcoded in Chinese/English, indicating a fixed locale presentation rather than adapting to user preference. Under the policy rule, forcing a specific language or locale without explicit opt-in can be a natural-language policy concern even when multiple languages are included.
No suspicious patterns detected.