T08 · Insecure Dependencies
- 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 punctuation skill appears intended to process text, but it also automatically changes Python environments, downloads unpinned packages, installs unrelated audio tools, and stores logs, so it needs review before installation.
Install only if you are comfortable with the skill downloading and installing Python packages at runtime and creating persistent local artifacts. Prefer running it in an isolated environment with no sensitive credentials, avoid submitting confidential text until logging is fixed, and review or remove the unrelated audio dependencies and import-time package repair logic before normal use.
scripts/ensure_package.py:26Host Python Environment Is Modified Before Virtual-Environment Isolation
scripts/punctuation_restore.py:30Unpinned Runtime Dependencies and Excessive Third-Party Packages
scripts/config.py:27Mutable Virtual Environment Is Shared Outside the Skill Root
scripts/punctuation_restore.py:195User Text and Filesystem Paths Are Persisted in Plaintext Logs
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 only restore punctuation, yet it reportedly creates virtual environments, probes GPU/CUDA state, installs large ML stacks, includes audio-related libraries, and re-executes other scripts. In the context of a simple text-processing skill, these extra behaviors materially expand attack surface and enable execution paths unrelated to the user's request.
The skill claims to only restore punctuation, yet it reportedly creates virtual environments, probes GPU/CUDA state, installs large ML stacks, includes audio-related libraries, and re-executes other scripts. In the context of a simple text-processing skill, these extra behaviors materially expand attack surface and enable execution paths unrelated to the user's request.
The skill claims to only restore punctuation, yet it reportedly creates virtual environments, probes GPU/CUDA state, installs large ML stacks, includes audio-related libraries, and re-executes other scripts. In the context of a simple text-processing skill, these extra behaviors materially expand attack surface and enable execution paths unrelated to the user's request.
The file implements a general-purpose package installer rather than functionality narrowly related to punctuation restoration. This mismatch is dangerous because capability overreach often hides unnecessary environment-modifying behavior that expands attack surface beyond the skill's stated purpose.
The module mutates the package environment immediately on import by reinstalling packaging, setuptools, and wheel. Import-time side effects are especially hazardous because merely loading the skill triggers network/package operations and changes the host environment without any explicit action from the user.
This module can install arbitrary packages from network sources, git repositories, and local archives based on function input, which is a broad code-execution primitive. In the context of a punctuation tool, the capability is unjustified and substantially more dangerous because it could be repurposed to fetch and run malicious packages unrelated to the skill.
The bootstrapper performs broad dependency installation, including audio tooling, despite the skill being declared as punctuation-only text processing. This scope mismatch creates unjustified code execution and package-trust expansion, making the skill materially riskier than users would reasonably expect.
Audio-processing capability is introduced into a skill whose metadata explicitly forbids audio transcription or other non-punctuation NLP tasks. Unnecessary capability expansion increases attack surface, dependency complexity, and the chance of hidden or future misuse without user awareness.
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 script installs Python packages at runtime via pip, which grants it the ability to execute package installation side effects and pull arbitrary code from package repositories during normal use. This is dangerous because package installation is a powerful supply-chain boundary crossing that is not necessary to perform punctuation restoration at execution time and can lead to unauthorized code execution or environment modification.
The README mentions directory mirroring and persistent local model caching, but these side effects are presented as features rather than prominent operational warnings. Users may not realize that invoking the skill on a directory creates a sibling output tree and stores models on disk, which can expose sensitive filenames/content footprints, consume storage, and create unexpected artifacts in monitored or shared environments.
The trigger phrases are broad natural-language requests such as '帮我给这段文本加标点' and '这段话没有标点,帮我整理一下', which can easily overlap with ordinary conversation. In an agent environment with automatic skill routing, this can cause unintended invocation on sensitive pasted text, local file paths, or folder paths, leading to unplanned processing of user data.
The skill invokes Python and performs file and shell operations, but it declares no explicit tool scope or permissions boundaries. That makes the effective capabilities broader than what a reviewer or runtime policy can easily validate, increasing the risk of unintended command execution, filesystem modification, and environment access.
The natural-language description is written entirely in Chinese and states the skill restores Chinese/English punctuation, but it does not offer a language or locale choice for interaction. Under the policy, forcing a specific language without user opt-in can be a language/locale policy violation unless the restriction is clearly documented and justified.
The manifest lists phrases like “帮我给这段文本加标点”, “这段话没有标点,帮我整理一下”, and “把这个无标点文本变正常”, which are natural everyday requests and not tightly scoped to a specific invocation context. Although the skill states it only handles punctuation restoration, it does not provide exclusion examples or clearer boundaries to reduce unintended activation collisions.
The documentation explicitly describes a smart package installation utility, which conflicts with the declared skill purpose of punctuation restoration. This inconsistency increases risk because it indicates hidden or unnecessary capabilities that can surprise operators and bypass least-privilege expectations.
The natural-language description and operational messaging are written entirely in Chinese, with no indication that users may choose another language 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 locale-policy concern.
Automatic environment modification at import time occurs without explicit confirmation, warning, or isolation. This is dangerous because users invoking a benign text-processing skill would not reasonably expect it to silently reinstall packaging infrastructure and alter dependency state.
This subprocess call invokes pip to modify the Python environment at runtime, and it happens inside a helper that is executed automatically on module import. Even though the arguments are hardcoded, automatic package mutation creates supply-chain and stability risk by silently downloading/installing code and changing dependency state without user consent.
"""专门为老项目(使用 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 call force-reinstalls setuptools and wheel, which are core packaging components, and can destabilize the host environment or override security expectations. Because it is part of import-time execution, simply loading this module can mutate the runtime environment in a way unrelated to punctuation restoration.
"--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"
])
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 installs an arbitrary package spec supplied to the function, including normal packages, URLs, git repositories, wheels, and zip archives. In the context of a punctuation-restoration skill, this is especially dangerous because it enables execution of untrusted third-party code and supply-chain compromise with no clear business justification.
cmd.extend(["-i", "https://pypi.tuna.tsinghua.edu.cn/simple"])
try:
subprocess.check_call(cmd)
logger.info(f"✅ {spec} 安装/升级完成!")
except subprocess.CalledProcessError as e:
This fallback subprocess installs a local zip archive when git installation fails, allowing arbitrary code from an archive path to be installed and executed. Supporting local archives as a generic fallback increases the attack surface further, especially because the skill context does not justify arbitrary package installation at all.
sys.executable, "-m", "pip", "install",
"--upgrade", fallback_zip, "--verbose"
]
subprocess.check_call(cmd_fallback)
logger.info(f"✅ 使用本地包 {fallback_zip} 安装成功!")
return
except subprocess.CalledProcessError as e2:
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
# ==================== 1. 检查是否已安装 + 版本是否满足 ====================
try:
__import__(import_name)
# 尝试获取当前版本
try: