T08 · Insecure Dependencies
- Location
scripts/generate_audio.py:210- Finding
Unpinned Runtime Installation of edge-tts
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its book-video purpose, but it performs automatic unpinned package installs and includes a reference workflow with a hard-coded third-party account ID that users should review before installing.
Install only if you are comfortable with the skill using external search, image, and TTS services and with scripts that may install Python packages during execution. Prefer a dedicated virtual environment with pinned dependencies, review or remove references/workflow-original.yaml before reusing it, and do not import the original workflow unless you replace the hard-coded user_id values with your own account or remove them.
scripts/generate_audio.py:210Unpinned Runtime Installation of edge-tts
scripts/generate_image.py:127Unpinned Runtime Installation of Image Provider SDKs
scripts/compose_video_moviepy.py:118Predictable MoviePy Temporary Audio File in the Working Directory
scripts/compose_video.py:400Unescaped Caption Text Permits ASS Subtitle Control Injection
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
req = urllib.request.Request(url, data=data, headers=headers, method="POST")
try:
with urllib.request.urlopen(req, timeout=300) as resp:
result = json.loads(resp.read())
except urllib.error.HTTPError as e:
err_body = e.read().decode()[:500]
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
req = urllib.request.Request(url, data=data, headers=headers, method="POST")
try:
with urllib.request.urlopen(req, timeout=300) as resp:
result = json.loads(resp.read())
except urllib.error.HTTPError as e:
err_body = e.read().decode()[:500]
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
}).encode()
req = urllib.request.Request(url, data=data, headers=headers, method="POST")
with urllib.request.urlopen(req) as resp:
result = json.loads(resp.read())
image_data = base64.b64decode(result["data"][0]["b64_json"])
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
}).encode()
req = urllib.request.Request(url, data=data, headers=headers, method="POST")
with urllib.request.urlopen(req) as resp:
result = json.loads(resp.read())
image_data = base64.b64decode(result["data"][0]["b64_json"])
The destination URL for the local Stable Diffusion request is taken directly from the SD_WEBUI_URL environment variable and then used for an HTTP request without validation. In an agent or automation environment, this enables SSRF-style access to arbitrary internal or external endpoints if that variable is influenced by an attacker or untrusted configuration.
}).encode()
req = urllib.request.Request(url, data=data, headers={"Content-Type": "application/json"}, method="POST")
with urllib.request.urlopen(req) as resp:
result = json.loads(resp.read())
image_data = base64.b64decode(result["images"][0])
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
*.skill
# Environment variables
.env
.env.local
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# Environment variables
.env
.env.local
声明描述的是一个端到端“读书视频生成器”,用户只需输入书名和作者即可自动完成文案、配图、TTS、字幕到MP4的全流程。而这段代码的实际职责明显更窄:它从stdin读取segments.json,要求上游已经提供image、audio、caption等素材,然后用ffmpeg/Pillow进行片段合成、字幕生成/烧录、关键词高亮、进度条叠加,以及BGM和转场音效混音。代码没有任何书籍信息检索、文案生成、AI绘图或TTS合成逻辑,也没有处理“书名+作者”输入。因此描述夸大了能力范围,实际更像“读书视频合成器”而不是完整“读书视频生成器”。
The declared description promises an end-to-end book video generator, including text generation, image generation, speech synthesis, subtitles, and final MP4 assembly. The provided code does not implement that pipeline. It only handles image generation from prompts or storyboard JSON and writes image files. While AI illustration is one possible sub-step of the declared workflow, this code chunk by itself materially underdelivers relative to the declared primary purpose and instead behaves as a generic image-generation utility. Therefore, the description does not accurately represent what this supplied code chunk actually does.
The documentation instructs modification of the agent's config directory and persistent configuration file (~/.codex/config.toml) using shell redirection. Access to agent config directories is sensitive because it can permanently alter tool behavior, enable features globally, or create persistence beyond the current task if executed by an agent without explicit user review.
# 1. 开启 Skills 功能(如未开启)
echo '[features]\nsskills = true' >> ~/.codex/config.toml
# 2. 复制技能目录
cp -r ~/.workbuddy/skills/book-video-generator ~/.codex/skills/
Referenced artifact was not completely inspected
原始扣子工作流文件位于 `references/workflow-original.yaml`,包含 30+ 节点的完整链路:
Referenced artifact was not completely inspected
原始扣子工作流文件位于 `references/workflow-original.yaml`,包含 30+ 节点的完整链路:
Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.
# 1. 开启 Skills 功能(config.toml)
cat >> ~/.codex/config.toml << 'EOF'
[features]
skills = true
EOF
Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.
# 1. 开启 Skills 功能(config.toml)
cat >> ~/.codex/config.toml << 'EOF'
[features]
skills = true
EOF
The example pipes content fetched from an external website directly into python, which is a classic unsafe execution pattern. Even though the inline command is abbreviated, this pattern normalizes executing network-derived content in a shell context and could lead users to adopt remote-code-execution behavior when adapting the example.
方案 A — Shell 命令搜索(免安装):
curl -s "https://www.google.com/search?q=书名+作者+简介" | python3 -c "..."
方案 B — 安装搜索 MCP 插件:
The workflow hard-codes a third-party user/account ID (10299) into draft creation and saving operations, and the save_draft description explicitly states that revenue can be attributed to that account. This causes user-generated outputs and potential monetization/ownership metadata to be silently linked to someone else, which is unrelated to core book-video generation and creates a clear abuse channel.
The code executes a shell command to install a package at runtime when edge_tts is missing. Although sys.executable is not attacker-controlled here, invoking pip through os.system downloads and installs code from an external source during normal execution, which expands the trust boundary and can lead to arbitrary code execution through dependency compromise, malicious package resolution, or unsafe environment behavior.
import edge_tts
except ImportError:
print("正在安装 edge-tts...")
os.system(f"{sys.executable} -m pip install edge-tts -q")
import edge_tts
os.makedirs(os.path.dirname(output_path) or ".", exist_ok=True)
The README states the workflow performs automatic web search and uses third-party APIs for image generation and TTS, but it does not clearly warn users that book titles, author names, prompts, and potentially generated content may be sent to external services. This can cause unintended data disclosure, especially if users provide sensitive or proprietary reading material requests under the assumption processing is local.
The README states the skill requires '任何支持中文的 LLM', which effectively constrains operation to Chinese without indicating this is optional or user-selected. This is a natural-language locale policy issue because the documentation forces a specific language context rather than offering a choice or clearly justifying a region-specific limitation.
The skill documents use of network access, shell commands, filesystem writes, and environment variables, but does not declare any explicit tool scope or permission boundaries. In agent platforms, missing scope declarations can cause overbroad execution authority and make it harder for users or hosts to understand what external effects the skill may have.
L006 中的触发词如“生成读书视频”“做读书视频”“精读一本书”表述较宽泛,和一般日常求助或内容创作请求高度重叠,但未说明仅在特定平台命令、上下文或参数满足时才应激活。缺少边界条件或反例,容易让代理在用户只是泛泛讨论读书视频时误调用该技能。
文档多处将中文作为默认且唯一明显支持的输出形态,例如 L017、L085-L086、L201-L203、L253、L306、L318 都强调中文 TTS、中文字体和中文读书解说,但未向用户提供语言/区域选择机制。对于通用技能,这种默认强制语言设定属于语言/locale 策略风险,除非明确声明该技能仅面向中文场景。
The skill instructs the agent to perform web searches and send prompts/content to third-party APIs for image generation and TTS, but does not clearly warn that user-provided book titles, prompts, and generated content will be transmitted externally. This creates a privacy and data-governance risk, especially in enterprise agent environments where users may assume local-only processing.
The search instructions explicitly send query data to Google via curl without warning the user that their search terms will be transmitted to a third party. Because the skill is intended for automated content generation, users may unknowingly send sensitive book/project context or internal prompts outside their environment.
The document instructs users to set API keys and use network-backed image generation services, but it does not clearly warn that prompts, metadata, and possibly generated content will be transmitted to third-party providers. In a skill that may process user-provided book titles, prompts, and local output paths across multiple platforms, this creates a real risk of accidental credential misuse or unintended data disclosure.