T08 · Insecure Dependencies
- Location
scripts/audio_tools.py:197- Finding
Automatic Installation of Unpinned Runtime Dependencies
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This media tool largely matches its stated purpose, but routine use can automatically install or upgrade Python packages and includes an unsafe metadata parser, so it needs review before installation.
Install only if you are comfortable with a media skill that may modify the active Python environment by installing or upgrading packages. Prefer preinstalling reviewed, pinned dependencies in an isolated virtual environment, avoid running it with elevated privileges, and confirm before using playback or transcription on untrusted or sensitive media.
scripts/audio_tools.py:197Automatic Installation of Unpinned Runtime Dependencies
scripts/audio_tools.py:582Unsafe Evaluation of ffprobe Frame-Rate Metadata
The documented behavior understates several sensitive capabilities: automatic pip installation, launching external programs/system handlers, and an eval-based parsing risk in metadata handling. Hidden or weakly disclosed execution paths are dangerous because they can introduce arbitrary code execution, unreviewed dependency installation, or unexpected application launches beyond the user's apparent consent.
Using eval() on r_frame_rate from ffprobe output is dangerous because it executes arbitrary Python expressions if that value is maliciously crafted or the ffprobe output is spoofed/tampered with. Even though ffprobe normally emits simple fractions like 30/1, agent tools should never turn external process output into executable code.
"codec": stream.get("codec_name"),
"width": int(stream.get("width", 0)),
"height": int(stream.get("height", 0)),
"fps": eval(stream.get("r_frame_rate", "0/1")), # 如 "30/1" -> 30.0
"pixel_format": stream.get("pix_fmt")
}
break
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
)
parser.add_argument("--check", action="store_true", help="检查环境依赖并退出")
parser.add_argument("--no-check", action="store_true", help="跳过环境检查(静默模式)")
subparsers = parser.add_subparsers(dest="command", required=False)
The skill declares shell and file-writing behavior but does not define any explicit tool scope or permissions boundary. That makes it easier for an orchestrator or user to invoke filesystem writes and command execution without a clearly documented restriction set, increasing the risk of overbroad execution or unsafe integration assumptions.
Overly broad trigger phrases such as generic playback or file-info terms can cause unintended activation of a skill that executes shell commands, writes files, and opens local media. In this context, accidental invocation is more dangerous because the skill can launch external applications and process user files without a narrowly scoped intent signal.
Speech-to-text on user media can expose sensitive personal, business, or regulated content, yet the skill provides no privacy notice or consent guidance. Even if transcription is local, the capability materially increases data sensitivity because it extracts and persists readable text and JSON metadata from media that users may not realize contains private information.
The documentation describes speech-to-text output behavior but does not clearly warn that recognized speech will be persisted to disk in JSON and TXT files. This can cause users to unintentionally store sensitive spoken content such as credentials, personal data, or confidential meeting audio in locations that may be backed up, shared, or accessible to other local users.
The top-level natural-language documentation is written entirely in Chinese and does not indicate that users may choose another language. Under the stated policy, language constraints should either be optional, user-selectable, or clearly justified as region-specific.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def check_pip_available():
"""检查 pip 是否可用"""
try:
result = subprocess.run(
[sys.executable, "-m", "pip", "--version"],
capture_output=True, text=True
)
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
print("\n Option 2 - System ffmpeg:")
print(" Windows: winget install ffmpeg")
print(" macOS: brew install ffmpeg")
print(" Linux: sudo apt install ffmpeg")
print("\n Option 3 - MoviePy (Python fallback):")
print(" pip install moviepy")
print("\n[NOTE] ffmpeg is recommended for better performance and format support.")
This code path performs undeclared package installation during standard feature execution rather than a separate setup phase. In a skill environment, that is a meaningful security issue because it grants the tool hidden networked code-acquisition behavior and mutates the host runtime unexpectedly.
The tool warns after entering the code path but does not obtain explicit user confirmation before performing a networked pip install. In agent usage, lack of consent around package installation is a real security concern because users may not expect environment mutation from a media command.
The skill automatically installs moviepy at runtime without explicit user confirmation, causing undeclared network/package-management side effects during normal operation. This expands the trust boundary to PyPI and the local Python environment, which is risky in agent/tooling contexts because a simple media request can trigger code download and installation.
return True
except ImportError:
print("⚙️ moviepy 未安装,正在自动安装...")
result = subprocess.run(
[sys.executable, "-m", "pip", "install", "moviepy"],
capture_output=True, text=True
)
Automatically invoking pip install moviepy is not necessary to safely fulfill the declared interface and introduces network/package-management behavior beyond expected audio processing. That mismatch increases risk because users may permit file operations without realizing they also permit software installation.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"-ac", "2", # 双声道
str(output_path)
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"❌ ffmpeg 执行失败:\n{result.stderr}")
sys.exit(1)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"-ac", "2", # 双声道
str(output_path)
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"❌ ffmpeg 执行失败:\n{result.stderr}")
sys.exit(1)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"-ac", "2", # 双声道
str(output_path)
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"❌ ffmpeg 执行失败:\n{result.stderr}")
sys.exit(1)
Launching ffplay on a user-specified file can trigger parsing of untrusted media by a native external program. In a skill context, this is more dangerous than a local desktop script because a remote prompt can cause opening/processing of attacker-controlled files, potentially abusing vulnerable media parsers or unexpectedly interacting with the user environment.
cmd = [ffplay_path, "-autoexit", str(input_path)]
try:
subprocess.Popen(cmd)
print(f"✅ 已启动 ffplay 播放:{input_path}")
return
except Exception as e:
Opening a file with the system default handler delegates execution to whatever application is associated with that file type. In an agent skill, this can unexpectedly launch local applications on attacker-influenced paths, creating a risky bridge from data handling into OS-level application execution.
if sys.platform == "win32":
os.startfile(str(input_path))
elif sys.platform == "darwin":
subprocess.Popen(["open", str(input_path)])
else:
subprocess.Popen(["xdg-open", str(input_path)])
print(f"✅ 已调用系统默认播放器打开:{input_path}")
Using xdg-open on a user-selected path hands control to the desktop environment and associated application handlers. That behavior is risky for an agent skill because it can launch arbitrary local applications or trigger unsafe file handling without an explicit user action at execution time.
elif sys.platform == "darwin":
subprocess.Popen(["open", str(input_path)])
else:
subprocess.Popen(["xdg-open", str(input_path)])
print(f"✅ 已调用系统默认播放器打开:{input_path}")
The transcription feature similarly includes hidden runtime installation behavior for Whisper. That creates unexpected side effects and increases supply-chain exposure, which is especially problematic for an agent skill that may be executed on behalf of a user without clear awareness of environment changes.
The same undisclosed install-on-use behavior exists for Whisper. Because this is triggered by ordinary transcription requests, it silently expands capability and trust to external package repositories without a clearly separate authorization step.
The skill automatically installs openai-whisper at runtime, again introducing undeclared package installation and network access during a routine transcription request. This is dangerous because it implicitly downloads and executes third-party package code in the host environment, which exceeds the stated expectations of a media-processing skill unless clearly disclosed and approved.
return True
except ImportError:
print("[INFO] openai-whisper not installed, installing...")
result = subprocess.run(
[sys.executable, "-m", "pip", "install", "-U", "openai-whisper"],
capture_output=True, text=True
)
The Whisper install path likewise adds package installation as an implicit side effect unrelated to the core expectation of local file transformation. In the context of an automation skill, hidden dependency installation is more dangerous because it may occur in privileged environments or CI/agent hosts.
The manifest header description includes five operations, including Whisper transcription and metadata extraction, but the body overview says the skill supports only three core functions: audio extraction, clipping, and playback. This creates a semantic mismatch in the skill documentation about what the skill actually provides.