T09 · Insecure Skill Coding Practices
- Location
scripts/ensure_package.py:26- Finding
Host Python Environment Is Modified Before Virtual-Environment Isolation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This audio transcription skill mostly matches its purpose, but it quietly performs broad automatic installs and downloads despite presenting itself as local and offline.
Review before installing. Use this only in an environment where automatic pip installs, Hugging Face downloads, model caching, logs, and transcript/audio output files are acceptable. Prefer a sandbox or dedicated virtual environment, provide a local --model_path for offline use, and avoid untrusted --model repository names.
scripts/ensure_package.py:26Host Python Environment Is Modified Before Virtual-Environment Isolation
scripts/transcribe.py:27Unpinned Dependencies Are Automatically Downloaded and Executed
scripts/transcribe.py:51Arbitrary Remote Model Repositories Are Accepted Without Revision or Integrity Pinning
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
venv/
ENV/
env/
.env
# Logs
logs/*.log
The skill claims to be offline and restricted to audio transcription, but this finding indicates automatic model downloads, runtime dependency installation, audio export, and dataset metadata generation for TTS/training. Those are materially different capabilities that can exfiltrate trust to external services, create additional artifacts, and repurpose user audio into derived training-style datasets without clear consent.
The skill claims to be offline and restricted to audio transcription, but this finding indicates automatic model downloads, runtime dependency installation, audio export, and dataset metadata generation for TTS/training. Those are materially different capabilities that can exfiltrate trust to external services, create additional artifacts, and repurpose user audio into derived training-style datasets without clear consent.
The skill claims to be offline and restricted to audio transcription, but this finding indicates automatic model downloads, runtime dependency installation, audio export, and dataset metadata generation for TTS/training. Those are materially different capabilities that can exfiltrate trust to external services, create additional artifacts, and repurpose user audio into derived training-style datasets without clear consent.
The skill claims to be offline and restricted to audio transcription, but this finding indicates automatic model downloads, runtime dependency installation, audio export, and dataset metadata generation for TTS/training. Those are materially different capabilities that can exfiltrate trust to external services, create additional artifacts, and repurpose user audio into derived training-style datasets without clear consent.
The skill claims to be offline and restricted to audio transcription, but this finding indicates automatic model downloads, runtime dependency installation, audio export, and dataset metadata generation for TTS/training. Those are materially different capabilities that can exfiltrate trust to external services, create additional artifacts, and repurpose user audio into derived training-style datasets without clear consent.
The skill is described as a local audio-to-text tool, but this file implements a general-purpose package installer that can download and install code from package indexes and git repositories. That mismatch is security-relevant because users and reviewers may grant the skill more trust than warranted, while the hidden capability enables network access and code execution outside the declared purpose.
This section gives the skill subprocess execution and automatic pip-based environment modification during import, which is unnecessary for basic local transcription. In the context of a narrowly scoped offline STT skill, this overbroad capability is more dangerous because it permits silent system changes and potential execution of externally sourced installer code with minimal visibility.
This block explicitly supports installing from git+https, remote indexes, wheels, and zip files, directly contradicting the skill's 'completely offline, privacy-safe' positioning. In this context, the discrepancy increases severity because the skill can reach out to external sources and introduce arbitrary third-party code into a supposedly local-only workflow.
The code performs network-based package downloads while the skill description repeatedly presents the tool as fully offline, local, and privacy-safe. That discrepancy is security-significant because users may provide sensitive audio under the assumption that no network activity occurs, while the bootstrapper reaches external package repositories and executes downloaded code.
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.
sys.exit(1)
# 传递环境变量防止递归
env = os.environ.copy()
env["RUNNING_IN_VENV"] = "true"
logger.info(f" 当前Python: {sys.executable}")
The skill advertises itself as completely offline and privacy-safe, yet it will automatically download models from Hugging Face when a model is missing. That creates an undisclosed network egress path, undermines user expectations about locality/privacy, and introduces supply-chain exposure through remotely fetched model artifacts.
The README says the tool has built-in '中文优先优化', which indicates a language preference baked into the skill behavior. The document does not clearly offer users a language choice or opt-in for this locale-specific behavior.
The README makes absolute privacy/offline guarantees ('完全本地离线运行', '数据绝对安全') while elsewhere documenting automatic model downloads from Hugging Face. This can mislead users and agents into sending network requests or exposing metadata in environments where offline-only handling is required, creating a trust and disclosure risk even if no direct code execution is shown.
The skill invokes Python and the embedded command description indicates shell execution plus file writes, yet the manifest does not declare any tool scope or allowed-tools restrictions. This weakens containment and makes it easier for a supposedly simple transcription skill to execute broader system actions than users or the platform may expect.
The description states the tool is '中文优先', which imposes a locale/language preference by default. The policy allows language constraints only when users are given a choice or the locale limitation is clearly justified; here, the skill also supports other languages and auto-detection, so defaulting to Chinese preference without opt-in is a natural-language policy issue.
The trigger examples use broad everyday phrases like 'help me transcribe' that may activate the skill without enough assurance that the user actually provided an audio file or intended this specific tool. Over-broad activation can cause unintended shell execution, file writes, or environment changes in contexts where the user only asked a general question.
The main trigger documentation repeats insufficiently scoped colloquial phrases, increasing the chance of accidental invocation. In a skill capable of shelling out to Python and writing files, unintended activation is more dangerous than in a read-only assistant workflow.
The parameter documentation says language is optional and that the system will auto-detect but '默认自动检测但优先中文'. That language indicates a built-in preference for one locale even when the user has not requested it, which conflicts with the policy against forcing a language or locale without user opt-in.
The file header presents this module as part of the STT skill while the actual code is a reusable package-installation utility. Mislabeling functionality is dangerous because it obscures privileged behaviors from auditors and users, making risky capabilities easier to hide within an otherwise benign-seeming skill.
This import-time subprocess call invokes pip to modify the Python environment automatically, which can fetch and install code without explicit user approval. In a skill advertised as local/offline audio transcription, silently reinstalling packaging at runtime expands the attack surface and enables unreviewed dependency changes or supply-chain compromise.
"""专门为老项目(使用 pkg_resources 的 setup.py)修复 setuptools 版本"""
try:
# 先强制修复损坏的 packaging 包(关键!解决无RECORD文件报错)
subprocess.check_call([
sys.executable, "-m", "pip", "install",
"--verbose", "--ignore-installed", "--no-deps", "packaging==26.1"
])
This code force-reinstalls setuptools and wheel via pip during import, altering the host environment before the skill even runs. That behavior is dangerous because it can break other software, execute installer code from external package sources, and violates the stated local/offline scope of the skill.
"--verbose", "--ignore-installed", "--no-deps", "packaging==26.1"
])
# 再安装兼容的 setuptools + wheel
subprocess.check_call([
sys.executable, "-m", "pip", "install",
"--verbose", "--force-reinstall", "setuptools<=81.2.0", "wheel"
])
Calling fix_setuptools_for_legacy_packages() at import time means merely importing this module triggers package repair and reinstallation actions automatically. That is dangerous because it performs privileged environment changes without user warning or consent and can execute code from packaging operations unexpectedly.
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
# 第一步:尝试 import 检查(最快)
try:
parts = import_name.split('.')
mod = __import__(parts[0])
for part in parts[1:]:
mod = getattr(mod, part)
if sub_import:
This subprocess call executes pip install using a spec that supports ordinary packages, version specifiers, git+ URLs, and local archives. That gives the skill a generic code-download and code-install capability far beyond audio transcription, creating a serious supply-chain and arbitrary code execution risk if the spec is influenced by skill logic or compromised sources.
cmd.extend(["-i", "https://pypi.tuna.tsinghua.edu.cn/simple"])
try:
subprocess.check_call(cmd)
logger.info(f"✅ {spec} 安装/升级完成!")
except subprocess.CalledProcessError as e:
No suspicious patterns detected.