T08 · Insecure Dependencies
- Location
scripts/generate_audio.py:218- Finding
Automatic Installation of Unpinned Third-Party Dependencies
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill appears to make book-summary videos as advertised, but it automatically installs unpinned Python packages and sends user content to external AI/TTS services, so it needs review before installation.
Install only after reviewing the provider choices. Prefer a dedicated virtual environment, preinstall pinned dependencies yourself, and avoid letting the scripts auto-install packages during a normal run. Do not submit confidential book data, unpublished manuscripts, private branding, or sensitive prompts unless the selected search, image, and TTS providers are approved for that data. Keep SD_WEBUI_URL pointed at a trusted local service if using the local backend.
scripts/generate_audio.py:218Automatic Installation of Unpinned Third-Party Dependencies
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 local Stable Diffusion endpoint is built from the SD_WEBUI_URL environment variable without validation, so a caller can redirect requests to an arbitrary host rather than a trusted localhost service. In agent environments, that can cause prompts and generated content requests to be sent to attacker-controlled infrastructure under the guise of a local backend.
}).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
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
| Engine | Credential | Timestamps | Notes |
|--------|-----------|-----------|-------|
| Volcano Engine TTS (default) | `VOLC_TTS_API_KEY` | Estimated from audio duration | Doubao Speech 2.0, best English naturalness, commercial use, get API Key from [Volcano console](https://console.volcengine.com/speech/new) |
| edge-tts (fallback) | none | Native WordBoundary | Microsoft free TTS, works out of the box, auto-fallback when no credential |
Set the Volcano credential:
Referenced artifact was not completely inspected
The original Coze workflow file is at `references/workflow-original.yaml`, a full chain of 30+ nodes:
Referenced artifact was not completely inspected
The original Coze workflow file is at `references/workflow-original.yaml`, a full chain of 30+ nodes:
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
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 guide suggests piping content fetched from an external website directly into Python via curl ... | python3 -c "...", which normalizes an unsafe pattern of executing data derived from the network. Even though the placeholder ... implies incompleteness, this example encourages command constructions where untrusted remote content can influence code execution, creating a clear path to arbitrary code execution if copied or adapted unsafely.
方案 A — Shell 命令搜索(免安装):
curl -s "https://www.google.com/search?q=book+title+author+summary" | python3 -c "..."
方案 B — 安装搜索 MCP 插件。
The script executes a shell command to install a missing dependency at runtime using os.system. Even though sys.executable is usually controlled by the local environment, invoking the shell for package installation creates an unnecessary command-execution path, can run unreviewed code from PyPI, and may behave dangerously in privileged or automated environments.
import edge_tts
except ImportError:
print("Installing 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 skill is presented as an 'English Version' and states that it produces the entire output 'entirely in English.' This is a natural-language locale constraint without any indication that users can choose another language or explicitly opt in, which matches the policy concern for forced language selection.
The markdown explicitly states that all script, narration, on-screen text, and prompts are fully in English. This is a natural-language locale policy constraint presented as mandatory behavior, and the file does not offer the user a language choice or document a justified region-specific requirement.
The workflow directs the agent to use third-party web search, image generation, and TTS providers, and elsewhere references API-based services and credentials, but it does not give a clear up-front privacy warning that user-supplied book titles, prompts, captions, and possibly derived content may be transmitted externally. This creates a real data-handling and consent risk, especially in enterprise or regulated environments where users may assume processing is local.
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.
# 1. Enable Skills (if not yet)
echo '[features]\nskills = true' >> ~/.codex/config.toml
# 2. Copy skill dir
cp -r ~/.workbuddy/skills/book-video-generator-en ~/.codex/skills/
# 3. Restart Codex CLI
The file repeatedly specifies that the skill is the English edition and, in this section, explicitly constrains TTS, subtitles, and fonts to English-only rendering. Because no user choice or opt-in is provided for language/locale behavior, this is a natural-language locale policy concern under the stated rule.
The file states that all output is in English, and later prompt fields also require English output for generated content. This imposes a language policy without offering the user a language choice or documenting a justified locale constraint.
The prompt explicitly instructs the model to use tools to search for real information about the book, but gives no user-facing notice that external/network retrieval may occur or what data will be sent. In an agent skill, this can expose user-supplied inputs such as book titles, authors, or surrounding context to third-party services without informed consent, creating privacy and compliance risk.
The top-level description states the workflow generates a Chinese-language video format, and multiple downstream prompts are written to require Chinese output. This imposes a specific language/locale behavior on all users without offering a choice or documenting a justified regional constraint.
The workflow sends generated and user-derived content, including text, audio, and images, to multiple external plugins and hosted asset URLs without any privacy or network-use disclosure. In this context, book inputs may seem low sensitivity, but account identifiers, generated media, and potentially user-provided names or branding still leave the local workflow boundary and may be retained or processed by third parties.
The workflow creates and saves an external video draft through plugins, changing external project state without any visible confirmation, warning, or consent gate. In an agent setting, silent state-changing actions can surprise users, create unauthorized artifacts under a linked account, and make abuse or accidental misuse harder to detect.
Detected: suspicious.exposed_secret_literal