T09 · Insecure Skill Coding Practices
- Location
scripts/video_remix.py:490- Finding
Environment-Controlled Temporary Directory Can Cause Arbitrary Recursive Deletion
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is a real video-remix workflow, but it uses powerful setup, browser, network sharing, external AI, and cleanup behavior that needs human review before installation.
Install only if you are comfortable with a skill that can install system packages, use a logged-in browser profile for Gemini, download videos, send transcript-derived text to AI/TTS services, and serve generated files on your local network. Run it in an isolated workspace, avoid sudo-driven setup from the skill itself, keep VR_TEMP_DIR pointed at a dedicated disposable folder, disable or restrict LAN HTTP sharing, and do not process private or copyrighted material unless you accept the external-service disclosures.
scripts/video_remix.py:490Environment-Controlled Temporary Directory Can Cause Arbitrary Recursive Deletion
scripts/gemini_first_remix.py:361Unauthenticated HTTP Server Exposes the Entire Output Directory on All Network Interfaces
modules/script_gen.py:248Custom LLM Endpoint Can Receive Video Content and the OpenAI API Credential
requirements.txt:4Unbounded and Unverified Runtime Dependencies Create Supply-Chain Risk
The declared description promises a broader end-to-end YouTube processing assistant, including Gemini-based analysis, clipping, hard subtitle synthesis, and LAN HTTP sharing. The actual code chunk is only an init.py that re-exports modules for download, transcription, analysis, script generation, TTS, and merging. Some declared functions are partially aligned with these exports, but several notable promised capabilities are not evidenced in the supplied code, especially LAN HTTP sharing and explicit hard subtitle composition. Because the visible code represents a narrower and somewhat different set of capabilities than the description, this is a mismatch.
The code matches only the downloading portion of the description. It fetches video metadata, downloads a video file, optionally downloads audio separately, supports format/quality selection, uses an HTTP/HTTPS proxy if present, and cleans up local downloaded files. There is no evidence of Gemini-based analysis, clipping, dubbing, subtitle burning, or local HTTP sharing in this code chunk. Because the declared description presents a much broader multifunction video-processing assistant than what this code actually does, the description is not an accurate representation of the supplied code chunk.
The declared description presents a broad YouTube-processing assistant with AI analysis, downloading, clipping, dubbing, hard subtitle embedding, and LAN HTTP sharing. The supplied code only covers one narrow media-processing component: using FFmpeg/ffprobe to merge video with new audio, cut timed segments, concatenate clips, replace/add audio, and extract audio. While this partially aligns with dubbing and some clipping-related processing, the primary declared capabilities around YouTube, Gemini analysis, subtitle hardcoding, and HTTP sharing are absent from this code chunk. Therefore the description does not accurately represent what this specific code actually does.
The declared description and the code overlap substantially on video download, transcription/analysis, script generation, dubbing, and final video merging. However, there are material discrepancies. First, the description specifically claims 'Gemini intelligent analysis', but the code configures ScriptGenerator with provider='openai' and an OPENAI_API_KEY, so the implemented LLM integration does not match that declared provider. Second, the description claims hard subtitle composition and LAN HTTP sharing, but this code chunk contains no subtitle burn-in/subtitle rendering logic and no local network HTTP serving/sharing functionality. Third, the code also supports local file input, which is broader than a pure YouTube assistant. These are meaningful behavior-description mismatches, so the description does not accurately represent this code chunk.
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
请只输出配音文案,不要其他说明:"""
return prompt
def _call_llm(self, prompt: str) -> str:
"""Call LLM API to generate script"""
When no LLM provider is configured, the fallback returns a slice of the prompt segment after the '原始内容' marker, which can echo user-supplied source text and portions of prompt scaffolding into output unexpectedly. This can disclose raw transcription/content that may have been expected to be transformed rather than reproduced, increasing privacy and copyright exposure in this video-processing context.
else:
# Fallback: return simplified original text
print("⚠️ No LLM configured, using original text")
return prompt.split("【原始内容】")[-1].strip()[:100]
def _call_openai(self, prompt: str) -> str:
"""Call OpenAI or compatible API"""
The skill instructs use of shell, network, environment variables, and file read/write, but does not declare any tool scope or allowed-tools restrictions. That means a host agent may grant broader capabilities than users expect, increasing the chance of unintended command execution, filesystem modification, network access, and data exposure.
The skill explicitly instructs downloading content and exposing outputs over a LAN HTTP server, but does not require clear user confirmation or provide meaningful privacy warnings. This can expose copyrighted or sensitive media to anyone on the local network and may unintentionally leak generated files or directory listings.
The trigger list is broad enough to activate on many generic video-related requests, which can cause the agent to invoke a highly privileged workflow unexpectedly. In this skill, unexpected activation is more dangerous because the workflow includes browser automation, package installation, downloads, file writes, and HTTP serving.
The instructions explicitly require the generated script to be written in Chinese, and the skill also defaults to Chinese TTS voices, but there is no opt-in or user choice for language. Under the stated policy, forcing a specific language/locale without user selection is a natural-language policy violation.
The skill directs execution of sudo apt update/install as part of normal operation. Embedding privileged package-management commands in a skill materially increases risk of host modification, unreviewed dependency installation, and abuse if the skill is triggered unexpectedly or if package sources/dependencies are compromised.
# 0.3 平台依赖(Ubuntu/Debian)
if command -v apt >/dev/null 2>&1; then
sudo apt update -y
sudo apt install -y ffmpeg yt-dlp libass-dev
fi
The second sudo invocation continues the same privileged installation flow and compounds the risk by performing package installation with elevated rights. In the context of a skill that also automates network and shell actions, this creates a broad host-compromise surface if misused or triggered without careful review.
# 0.3 平台依赖(Ubuntu/Debian)
if command -v apt >/dev/null 2>&1; then
sudo apt update -y
sudo apt install -y ffmpeg yt-dlp libass-dev
fi
# 0.4 Python 依赖(幂等安装)
The analyzer hard-codes keyword lists and scoring terms specifically for Chinese and English content, which creates a built-in locale preference in the skill behavior. Because the file does not provide any user opt-in, configuration, or documented restriction to those languages, this can violate language/locale policy expectations.
The downloader implicitly reads HTTP_PROXY/HTTPS_PROXY from the process environment, causing network traffic and requested video URLs to be routed through infrastructure the user may not expect. In an agent or hosted environment, this can leak sensitive request metadata, enable traffic inspection, or change network reachability in ways not disclosed by the skill interface.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
cmd.append(url)
print(f"📥 Downloading video: {title}")
result = subprocess.run(
cmd,
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
cmd.extend(["--proxy", self.proxy])
cmd.append(url)
result = subprocess.run(
cmd,
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
cmd.extend(["--proxy", self.proxy])
cmd.append(url)
result = subprocess.run(
cmd,
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
cmd.extend(["--proxy", self.proxy])
cmd.append(url)
result = subprocess.run(
cmd,
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
cmd.extend(["--proxy", self.proxy])
cmd.append(url)
result = subprocess.run(
cmd,
capture_output=True,
text=True,
The cleanup method unlinks all .mp4, .m4a, and .info.json files in the output directory, which is a destructive file-deletion operation. There is no confirmation prompt, print/log message, or warning in nearby documentation/comments that this method will delete user-downloaded content.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
str(output_path)
])
result = subprocess.run(
cmd,
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
str(output_path)
])
result = subprocess.run(
cmd,
capture_output=True,
text=True,
The code sends segment text, summaries, keywords, and optionally full transcription context to external LLM providers without any visible consent gate, redaction, or disclosure control. If the input contains private, copyrighted, or sensitive content, this can leak user data to third-party services and may violate user expectations or policy requirements.
Natural-language instructions hardcode Chinese output ("语言:中文"), while the class exposes a language parameter that is not honored in prompt construction. This creates a language policy issue because the skill imposes a specific language without offering user choice at generation time.
The local-model path performs an HTTP POST to a configurable base_url, which can transmit prompt contents off-host if the URL is changed from localhost to a remote service. Because the payload includes user-derived text and there is no allowlist, TLS enforcement, or warning, this creates a data exfiltration/privacy risk similar to other remote LLM calls.
"stream": False
}
response = requests.post(url, json=payload, timeout=60)
response.raise_for_status()
data = response.json()
No suspicious patterns detected.