T08 · Insecure Dependencies
- Location
SKILL.md:172- Finding
Unpinned Package Execution Through npx
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
Review recommended: the skill’s video workflow is coherent, but it runs an unpinned external CLI and has weak asset path validation that could expose files outside the project.
Install only if you are comfortable running video-generation tooling in a contained project workspace. Pin or preinstall HyperFrames instead of allowing ad hoc `npx` downloads, and avoid using untrusted storyboard files until asset paths are constrained to the project directory.
SKILL.md:172Unpinned Package Execution Through npx
scripts/validate_storyboard.py:161Storyboard Asset Validation Allows Paths Outside the Project Root
The declared description describes an end-to-end article/image-to-video generation skill for WeChat Channels. The supplied code chunk only implements a contact-sheet generator for an already existing video, using ffprobe/ffmpeg and PIL to sample frames and compose a labeled image grid. This is materially different from the declared primary purpose and omits nearly all advertised capabilities. While such a tool could support QA in a broader video workflow, on its own it does not match the claimed skill behavior.
The skill instructs file reads, file writes, and shell execution but does not declare any explicit tool scope or allowed-tools boundary. In an agent runtime, that increases the chance of over-broad tool access, making unintended filesystem or command execution possible if article content, filenames, or surrounding context are adversarial.
Using npx hyperframes without a pinned version allows whatever package version is current at execution time to be fetched and run. This creates a supply-chain risk where a compromised, malicious, or simply breaking upstream release could execute arbitrary code in the agent environment.
The default prompt is written as an English instruction ('Use $wechat-article-video to turn this WeChat article...') with no indication that the user can choose language or locale. Because this skill targets WeChat content and the surrounding metadata is Chinese, hard-coding an English interaction pattern may violate a language/locale policy requiring user choice or explicit justification.
Line L125 states 'Use spoken Chinese' as a blanket instruction. This is a natural-language locale constraint, and the file does not provide user opt-in, alternative language handling, or a clear documented justification that the skill is region- or language-specific.
Line L120 explicitly instructs handling of long Chinese names, and the example asset metadata at L129 uses Chinese text, indicating a Chinese-language assumption. Because this markdown file does not document that the skill is region-specific or offer a language/locale choice, it appears to impose a locale-specific content policy by default.
The example hard-codes zh-CN-XiaoxiaoNeural, which specifies a Chinese locale and voice. This appears to impose a specific language/locale in the skill guidance without stating that users can choose another locale or that the schema is region-specific.
The script defaults to zh-CN-XiaoxiaoNeural, which hard-codes a Chinese locale/voice selection in user-facing behavior. This is a natural-language locale policy concern because the file does not indicate that the user is choosing this language or that the tool is intentionally region-specific.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def probe_duration(video: Path) -> float:
result = subprocess.run(
[
"ffprobe",
"-v",
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def extract_frame(video: Path, timestamp: float, destination: Path) -> None:
subprocess.run(
[
"ffmpeg",
"-y",
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def probe(video: Path) -> dict:
result = subprocess.run(
[
"ffprobe",
"-v",
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def extract_first_frame(video: Path, destination: Path) -> dict:
destination.parent.mkdir(parents=True, exist_ok=True)
subprocess.run(
[
"ffmpeg",
"-y",
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.
permit persons to whom the Software is furnished to do so.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
The instruction "Default to Chinese" imposes a specific language behavior in the skill’s natural-language policy surface. The file does not offer a user language choice or explain that the skill is restricted to a China-only or Chinese-only compliance context.
The ffmpeg invocation uses the -y flag, which forces overwrite of the destination cover file if it already exists. Although the script later prints overall results, there is no prior confirmation prompt or explicit user-facing warning near the destructive write behavior itself.
The script creates parent directories and writes the report file unconditionally, which can overwrite an existing report path. There is no confirmation prompt or inline warning around this file write, and the top-level docstring does not disclose the write behavior.
No suspicious patterns detected.