T09 · Insecure Skill Coding Practices
- Location
scripts/check_env.py:20- Finding
Shell Command Injection Through User-Controlled Installation and Startup Arguments
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is mostly a Fooocus local image-generation helper, but its installer and runtime guidance create real host-safety and privacy risks that should be reviewed before installation.
Install only if you are comfortable with a skill that can install software, clone remote code, modify files under your home directory, start a local Fooocus service, and send prompts or selected images to a configured API endpoint. Review and preferably patch the installer before use, avoid --force except on a verified Fooocus directory, keep the service bound to localhost, and do not use cloud or remote endpoints with sensitive prompts or personal images unless you explicitly accept that data transfer.
scripts/check_env.py:20Shell Command Injection Through User-Controlled Installation and Startup Arguments
scripts/install_fooocus.py:35Shell Command Injection in the Standalone Fooocus Installer
scripts/install_fooocus.py:220Arbitrary Recursive Directory Deletion Through the Force-Reinstall Option
scripts/install_fooocus.py:14Moving Remote Repository and Unpinned Dependencies Are Installed Without Integrity Verification
scripts/generate_image.py:91Private Prompts and Images Can Be Sent to Arbitrary Plaintext API Endpoints
SKILL.md:1855Documentation Encourages Unauthenticated Binding of Fooocus to All Network Interfaces
The skill includes guidance for network connectivity checks to third-party hosts and diagnostics unrelated to the narrow end-user expectation of image generation. While not overtly malicious, combining environment diagnostics, external connectivity tests, and local inspection without precise scoping broadens the operational footprint and may leak metadata or trigger unnecessary outbound traffic.
The skill includes guidance for network connectivity checks to third-party hosts and diagnostics unrelated to the narrow end-user expectation of image generation. While not overtly malicious, combining environment diagnostics, external connectivity tests, and local inspection without precise scoping broadens the operational footprint and may leak metadata or trigger unnecessary outbound traffic.
The skill includes guidance for network connectivity checks to third-party hosts and diagnostics unrelated to the narrow end-user expectation of image generation. While not overtly malicious, combining environment diagnostics, external connectivity tests, and local inspection without precise scoping broadens the operational footprint and may leak metadata or trigger unnecessary outbound traffic.
The skill includes guidance for network connectivity checks to third-party hosts and diagnostics unrelated to the narrow end-user expectation of image generation. While not overtly malicious, combining environment diagnostics, external connectivity tests, and local inspection without precise scoping broadens the operational footprint and may leak metadata or trigger unnecessary outbound traffic.
The skill includes guidance for network connectivity checks to third-party hosts and diagnostics unrelated to the narrow end-user expectation of image generation. While not overtly malicious, combining environment diagnostics, external connectivity tests, and local inspection without precise scoping broadens the operational footprint and may leak metadata or trigger unnecessary outbound traffic.
This is a true tool-parameter-abuse issue because shell=True turns command text into a shell-interpreted program, and this helper is used to run install and clone operations. Any attacker-controlled content reaching cmd can inject additional shell commands, which is especially dangerous in a skill designed to modify the local environment.
"""Run a shell command and return output"""
try:
if capture:
result = subprocess.run(
cmd, shell=True, cwd=cwd, capture_output=True, text=True, timeout=timeout
)
return result.returncode == 0, result.stdout, result.stderr
The non-capturing execution path has the same shell injection sink and exposes the same abuse primitive. Because this utility performs installation-related tasks, successful exploitation can result in arbitrary package installation, file modification, or command execution as the local user.
)
return result.returncode == 0, result.stdout, result.stderr
else:
result = subprocess.run(cmd, shell=True, cwd=cwd, timeout=timeout)
return result.returncode == 0, "", ""
except subprocess.TimeoutExpired:
return False, "", "Command timed out"
This duplicate Popen finding is a true vulnerability for the same reason: shell=True on a concatenated command string containing external input enables arbitrary command execution. The skill's purpose of installing and launching local AI tooling increases exposure because it already expects filesystem and process-level access.
# Start in background
if sys.platform == "win32":
subprocess.Popen(
cmd, cwd=path, shell=True,
creationflags=subprocess.CREATE_NEW_CONSOLE
)
This duplicate Popen finding is a true vulnerability for the same reason: shell=True on a concatenated command string containing external input enables arbitrary command execution. The skill's purpose of installing and launching local AI tooling increases exposure because it already expects filesystem and process-level access.
# Start in background
if sys.platform == "win32":
subprocess.Popen(
cmd, cwd=path, shell=True,
creationflags=subprocess.CREATE_NEW_CONSOLE
)
This duplicate non-Windows Popen finding is also a true vulnerability; shell metacharacters in interpolated values can alter command behavior or append attacker commands. In this environment-management script, exploitation could compromise the host running the agent skill.
creationflags=subprocess.CREATE_NEW_CONSOLE
)
else:
subprocess.Popen(
cmd, cwd=path, shell=True,
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
)
This duplicate non-Windows Popen finding is also a true vulnerability; shell metacharacters in interpolated values can alter command behavior or append attacker commands. In this environment-management script, exploitation could compromise the host running the agent skill.
creationflags=subprocess.CREATE_NEW_CONSOLE
)
else:
subprocess.Popen(
cmd, cwd=path, shell=True,
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
)
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("--output-dir", default=DEFAULT_OUTPUT_DIR, help="Output directory")
# Behavior
parser.add_argument("--skip-check", action="store_true", help="Skip environment check")
parser.add_argument("--cpu-optimize", action="store_true", help="Optimize for CPU mode")
parser.add_argument("--verbose", "-v", action="store_true", help="Verbose output")
parser.add_argument("--timeout", type=int, default=300, help="Request timeout")
Using subprocess.run with shell=True in a generic wrapper creates a tool-abuse primitive: any tainted input that reaches cmd can escape intended boundaries and execute arbitrary shell commands. In the context of an installer that handles filesystem paths and package operations, this can lead to local code execution under the user's account.
"""Run a shell command"""
try:
if capture:
result = subprocess.run(
cmd, shell=True, cwd=cwd, capture_output=True, text=True, timeout=timeout
)
return result.returncode == 0, result.stdout, result.stderr
The non-capturing subprocess path repeats the same unsafe shell=True behavior, so the wrapper remains dangerous regardless of output mode. This broadens the attack surface because future commands may be added to this helper under the assumption it is safe.
)
return result.returncode == 0, result.stdout, result.stderr
else:
result = subprocess.run(cmd, shell=True, cwd=cwd, timeout=timeout)
return result.returncode == 0, "", ""
except subprocess.TimeoutExpired:
return False, "", "Command timed out"
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
# Create launcher
create_launcher_scripts(args.path)
# Print instructions
print_post_install(args.path)
The quick reference tells the agent to steer users to Google Colab and Hugging Face when no GPU is present, even though the skill is described as local Fooocus image generation. This creates scope drift: a user invoking a local-only skill could be redirected to third-party services, causing unintended data disclosure of prompts or images and violating user expectations about where content is processed.
The instructions tell the agent to run dependency installation automatically ('Let me install it for you') without first obtaining explicit consent or clearly warning that packages will be installed and the system modified. Automatic installs change the host environment, consume bandwidth and disk, and increase risk when performed by an autonomous agent on behalf of a user.
The setup guidance initiates Fooocus installation and a multi-gigabyte model download without an explicit confirmation step before the action. This is risky because it can trigger substantial network, storage, and environment changes that the user did not knowingly authorize, especially in an agent-driven workflow.
The fallback section instructs the agent to suggest external cloud services if local setup fails, which is behavior outside the stated local-generation scope. In practice, this can cause sensitive prompts, reference images, or inpainting inputs to be sent to third-party providers without the user anticipating that change in trust boundary.
The documentation explicitly recommends Google Colab and Hugging Face, which are cloud-hosted services, even though the skill is described as local-only Fooocus image generation. This can misroute users from a local privacy-preserving workflow to third-party platforms, creating data exposure and policy-boundary violations if users upload sensitive prompts or images.
The skill declares requirements and operational steps that imply shell execution, network access, and filesystem modification, but it does not declare any explicit tool scope or permission boundaries. In an agent environment, this can cause the skill to obtain or appear to justify broad capabilities without user-visible restrictions, increasing the chance of unintended installs, downloads, and local changes.
The trigger language is very broad and may activate the skill for generic image-related requests whenever Fooocus is merely mentioned. Overbroad invocation increases the chance that an agent will enter a setup/install/service-management flow unexpectedly, performing privileged actions in contexts where the user only intended a normal conversation or a different tool.
The skill supports face swap, style transfer, image prompt, and user image upload workflows but does not prominently warn about privacy, consent, biometric sensitivity, or copyright concerns. This omission can lead to misuse of personal or third-party images and accidental processing of sensitive content without informed user consent.
The documentation markets the workflow as local/offline, but repeatedly instructs package installation, GitHub/community lookups, and model downloads from external services. This can mislead users into exposing system/network metadata or initiating unreviewed downloads when they believed the tool would remain offline.
Large portions of the skill are written in Chinese and line L0011 explicitly presents a Chinese-only maintenance statement, while the document does not offer users a language option or explain that the skill is intended only for a Chinese-speaking environment. This can violate language or locale policy when a skill implicitly forces one language without opt-in.
No suspicious patterns detected.