T09 · Insecure Skill Coding Practices
- Location
scripts/install.py:14- Finding
PowerShell Command Injection Through Unescaped Configuration and Path Values
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill openly controls a Windows desktop, but it needs Review because that powerful access is not tightly contained or cleaned up.
Install only if you intentionally want an agent to view and operate your Windows desktop. Run it only on a trusted local machine, close sensitive windows first, stop the server when finished, delete leftover screenshot temp files and .auth_token, and prefer a version that pins dependencies, protects the token file, enforces timeout, and avoids PowerShell string interpolation.
scripts/install.py:14PowerShell Command Injection Through Unescaped Configuration and Path Values
scripts/install.py:8Unpinned Runtime Dependency Installation Creates a Supply-Chain Risk
scripts/server.py:24Desktop-Control Bearer Token Is Stored Without Explicit Access Restrictions
config.json:7Configured Automatic Shutdown Is Not Enforced
Package name closely resembles a popular package, suggesting possible typosquatting. Attackers publish malicious packages with similar names to trick developers into installing them.
The shutdown method invokes a remote /shutdown endpoint, which is an irreversible or disruptive system action. In this file there is no confirmation prompt, cautionary comment, or user-visible warning indicating that calling this method can power off or terminate the controlled environment.
The endpoint handlers execute mouse and keyboard actions immediately with no user-facing consent, visibility, rate limiting, or allowlist of permitted operations. In the context of a remote desktop control skill, this means any party with the bearer token can silently take over the desktop, enter commands, approve prompts, or interact with sensitive applications.
The skill enables sensitive capabilities including shell execution, network communication, file access, and remote GUI control, but it does not declare any explicit tool scope or permission boundaries. In a desktop-control skill, the absence of scoped permissions increases the risk of overbroad execution and makes it harder for a host system or reviewer to enforce least privilege.
This skill is explicitly designed to capture screenshots and control a live Windows desktop, which can expose credentials, personal messages, documents, and other sensitive on-screen data. Although the description mentions intended use, it does not clearly warn about privacy risks, consent requirements, or the possibility of collecting unrelated sensitive information during screen capture.
The client sends JSON requests over HTTP and includes an Authorization bearer token for most endpoints, which constitutes network transmission of credentialed control data. While networking is core to this client, the file lacks any visible user-facing notice, logging, or warning about transmitting commands and authentication material to the service.
The screenshot method decodes sensitive desktop contents and writes them to a persistent temporary file using delete=False, which can leave confidential data on disk after use. In a remote desktop-control skill, screenshots may contain passwords, personal data, tokens, or business information, so residual files materially increase exposure to other local users, malware, or later forensic recovery.
The module docstring states the skill is for '一键安装' and all user-facing messages in the script are hard-coded in Chinese. This imposes a specific language/locale on users without opt-in or explanation, which matches the policy category for language or locale constraints.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def install():
cmd = f"& '{PY}' -m pip install {' '.join(DEPS)}"
result = subprocess.run([POWERSHELL, "-Command", cmd], capture_output=True, text=True, timeout=120)
print(result.stdout)
if result.returncode != 0:
print(f"错误: {result.stderr}")
Request target host is built from a dynamic or untrusted value. If the host is attacker-influenced, this enables SSRF to arbitrary internal or metadata endpoints.
def is_running() -> bool:
try:
resp = urllib.request.urlopen(f"http://{HOST}:{PORT}/status", timeout=3)
return resp.status == 200
except Exception:
return False
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 从WSL获取Windows路径
wsl_server = str(Path(__file__).parent / "server.py")
result = subprocess.run(["wslpath", "-w", wsl_server], capture_output=True, text=True)
win_server = result.stdout.strip()
cmd = (
The code builds a PowerShell -Command string using PY from config.json and win_server and then executes it. Because this is interpreted by PowerShell, a malicious or tampered configuration value containing quotes or PowerShell metacharacters could alter the command and execute arbitrary code on the Windows host.
f"-ArgumentList '{win_server}' "
f"-WindowStyle Hidden"
)
subprocess.run([POWERSHELL, "-Command", cmd], capture_output=True, timeout=15)
for _ in range(timeout // 2):
time.sleep(2)
The script reads a bearer token from disk and sends it over plain HTTP to HOST:PORT. If the service is reachable beyond a trusted local interface or the host value is changed, the token can be exposed to local network interception or misrouting, enabling unauthorized shutdown requests.
This code sends an authenticated shutdown request to a dynamic host/port from configuration using plain HTTP. While not a typical web-app SSRF case, it can become a confused-deputy issue if configuration is tampered with, causing the launcher to disclose its bearer token or send a privileged request to an unintended endpoint.
try:
token = (Path(__file__).parent.parent / ".auth_token").read_text().strip()
data = b"{}"
req = urllib.request.Request(
f"http://{HOST}:{PORT}/shutdown",
data=data,
headers={"Content-Type": "application/json", "Authorization": f"Bearer {token}"}
The stop logic escalates to unconditional force-killing without any confirmation or user-facing warning. In a remote desktop automation context, abrupt termination can interrupt user work, kill the wrong process if matching is imprecise, and cause loss of unsaved state.
This forcefully terminates any python process whose command line matches *server.py*, which is broad and can kill unrelated local processes if names collide. In a desktop-control skill, that behavior is more dangerous because it operates across the user's Windows environment and may cause data loss or denial of service for other tasks.
if not is_running():
return True
# 强制关闭
subprocess.run(
[POWERSHELL, "-Command",
"Get-Process python -ErrorAction SilentlyContinue | Where-Object {$_.CommandLine -like '*server.py*'} | Stop-Process -Force"],
capture_output=True, timeout=10
The server exposes a remotely callable /shutdown endpoint that allows any authenticated client to terminate the automation service. Although token-protected, this capability is unrelated to core desktop interaction and creates an unnecessary denial-of-service primitive if the token is leaked, mishandled, or abused by another local process.
The dependency 'fastapi' is unpinned, so installations may resolve to different versions over time, including vulnerable or breaking releases. In a skill that exposes remote desktop control capabilities and likely serves an API, this increases supply-chain and patch-verification risk because you cannot reliably determine or reproduce the security posture of deployed environments.
fastapi
uvicorn
mss
pyautogui
FastAPI has known advisories, and because no version is pinned, it is impossible to verify whether the installed release is affected. In a remote-control skill likely exposing HTTP endpoints, framework vulnerabilities can be more consequential because they may enable unauthorized interaction with a highly sensitive capability.
The dependency 'uvicorn' is unpinned, which means future installs may pull in unexpected versions with known flaws or incompatible behavior. Because this skill appears to provide remote-control functionality over a service boundary, lack of version pinning makes it harder to ensure the server component is not deployed with an affected release.
fastapi
uvicorn
mss
pyautogui
pillow
Uvicorn has known advisories, but the manifest does not specify a version, so the environment may be using an affected release without visibility. Because this service likely fronts desktop-control actions, even server-layer issues such as logging or response handling flaws can increase attack surface around a privileged automation interface.
The dependency 'mss' is unpinned, creating a reproducibility and supply-chain risk because the installed version may vary by environment or over time. In a desktop-control skill that handles screenshots, any vulnerable or maliciously substituted version could affect confidentiality or stability.
fastapi
uvicorn
mss
pyautogui
pillow
The dependency 'pyautogui' is unpinned, so installs are not deterministic and may introduce vulnerable or malicious changes unexpectedly. Given this package drives keyboard and mouse automation, compromise of this dependency could directly affect integrity of the controlled desktop session.
fastapi
uvicorn
mss
pyautogui
pillow
The dependency 'pillow' is unpinned, preventing verification that deployed versions are free from known image-parsing vulnerabilities. Since this skill processes screenshots, a vulnerable Pillow release could increase exposure to image-handling bugs and denial-of-service or worse depending on the affected version.
uvicorn
mss
pyautogui
pillow
Pillow has numerous published advisories, and without a pinned version there is no way to determine whether the installed build is vulnerable. This is especially relevant here because the skill handles screenshots and image data, so a vulnerable image library could expose denial-of-service, memory corruption, or code-execution paths depending on the version in use.
No suspicious patterns detected.