T09 · Insecure Skill Coding Practices
- Location
scripts/gui_agent.py:44- Finding
Shell Command Injection Through GUI Task Parameters
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This GUI automation skill is mostly purpose-aligned, but it has review-worthy risks around insecure remote control, command-injection paths, broad screenshot retention, and OpenClaw session metadata access.
Install only if you are comfortable giving this skill broad desktop-control and screenshot access. Avoid using it on password managers, private chats, financial/account screens, or sensitive documents unless you first disable or regularly delete visual memory. Use remote mode only against trusted isolated VMs, not arbitrary HTTP endpoints, and prefer reviewing/fixing the shell=True and remote python3 -c command paths before using it with untrusted task parameters. Treat the setup as mutable because it installs latest packages and model artifacts without hashes.
scripts/gui_agent.py:44Shell Command Injection Through GUI Task Parameters
scripts/backends/http_remote.py:8Remote Python Injection and Unauthenticated Plaintext VM Control
scripts/app_memory.py:2068Unconditional Persistent Storage of Full-Screen and Full-Page Screenshots
skills/gui-report/scripts/tracker.py:20Performance Tracker Enumerates Global OpenClaw Session Metadata
requirements.txt:4Unpinned and Unverified Third-Party Dependency Installation
The finding indicates reads of session/token-related local files and writes of tracker/task history logs despite the skill presenting itself as GUI automation. Access to session artifacts and local memory stores can expose authentication data or sensitive operational history, and the mismatch means users may not realize the skill touches those files at all.
The finding indicates reads of session/token-related local files and writes of tracker/task history logs despite the skill presenting itself as GUI automation. Access to session artifacts and local memory stores can expose authentication data or sensitive operational history, and the mismatch means users may not realize the skill touches those files at all.
The finding indicates reads of session/token-related local files and writes of tracker/task history logs despite the skill presenting itself as GUI automation. Access to session artifacts and local memory stores can expose authentication data or sensitive operational history, and the mismatch means users may not realize the skill touches those files at all.
The finding indicates reads of session/token-related local files and writes of tracker/task history logs despite the skill presenting itself as GUI automation. Access to session artifacts and local memory stores can expose authentication data or sensitive operational history, and the mismatch means users may not realize the skill touches those files at all.
The finding indicates reads of session/token-related local files and writes of tracker/task history logs despite the skill presenting itself as GUI automation. Access to session artifacts and local memory stores can expose authentication data or sensitive operational history, and the mismatch means users may not realize the skill touches those files at all.
The finding indicates reads of session/token-related local files and writes of tracker/task history logs despite the skill presenting itself as GUI automation. Access to session artifacts and local memory stores can expose authentication data or sensitive operational history, and the mismatch means users may not realize the skill touches those files at all.
The finding indicates reads of session/token-related local files and writes of tracker/task history logs despite the skill presenting itself as GUI automation. Access to session artifacts and local memory stores can expose authentication data or sensitive operational history, and the mismatch means users may not realize the skill touches those files at all.
The finding indicates reads of session/token-related local files and writes of tracker/task history logs despite the skill presenting itself as GUI automation. Access to session artifacts and local memory stores can expose authentication data or sensitive operational history, and the mismatch means users may not realize the skill touches those files at all.
The finding indicates reads of session/token-related local files and writes of tracker/task history logs despite the skill presenting itself as GUI automation. Access to session artifacts and local memory stores can expose authentication data or sensitive operational history, and the mismatch means users may not realize the skill touches those files at all.
The finding indicates reads of session/token-related local files and writes of tracker/task history logs despite the skill presenting itself as GUI automation. Access to session artifacts and local memory stores can expose authentication data or sensitive operational history, and the mismatch means users may not realize the skill touches those files at all.
The skill metadata claims support for both macOS and Linux, but the action implementations rely heavily on macOS-specific tools such as osascript, System Events, screencapture, open -a, and /opt/homebrew/bin/cliclick. This mismatch can cause operators to run the skill in unsupported environments, leading to unsafe fallbacks, broken automation, or incorrect assumptions about what system capabilities are being invoked.
The quit_app action forcibly requests an application quit with no warning about unsaved work, no save-state check, and no confirmation step. In GUI automation, this creates a significant integrity and availability risk because it can cause immediate user data loss or interrupt critical tasks in the targeted application.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- These were only: VM reset → config download → mark score=0
**Blocked tasks** (cannot run):
- Google Drive: #5, #6, #10, #11, #13, #14, #29, #33, #77, #99 (missing client_secrets.json)
- Network: #28 (GitHub 403), #30 (anaconda timeout), #34-36 (web scraping), #47, #48, #53, #57, #66, #85, #95, #100, #101
## Key Observations
The code explicitly forwards the full inherited environment to child scripts. In an automation-agent setting, environment variables commonly hold secrets like API tokens, cloud credentials, SSH settings, and proxy authentication, so every called helper script and imported dependency gains access to those secrets, increasing the blast radius if any helper is compromised or logs/debugs its environment.
cmd = [VENV, str(SCRIPT_DIR / script_name)] + args_list
try:
r = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout,
env={**os.environ, "LANG": "en_US.UTF-8", "LC_ALL": "en_US.UTF-8"})
return r.stdout.strip(), r.returncode
except subprocess.TimeoutExpired:
return "Timeout", 1
The script enables remote GUI control over HTTP based only on a user-supplied URL, which expands the skill from local automation into network-delivered command execution against another host. In skill context, this is more dangerous because GUI actions can type secrets, click privileged dialogs, capture screenshots, and manipulate remote sessions without any visible authentication, transport-security, or scope restrictions in this interface.
The helper is a generic shell execution primitive with shell=True and is used to build commands from dynamic data. In this skill, which already has broad desktop control, successful parameter injection would escalate from GUI automation into unrestricted command execution on the host.
return r.stdout.strip()
def shell(cmd, timeout=15):
r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout,
env={**os.environ, "LANG": "en_US.UTF-8", "LC_ALL": "en_US.UTF-8"})
return r.stdout.strip()
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.
def shell(cmd, timeout=15):
r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout,
env={**os.environ, "LANG": "en_US.UTF-8", "LC_ALL": "en_US.UTF-8"})
return r.stdout.strip()
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.
def shell(cmd, timeout=15):
r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout,
env={**os.environ, "LANG": "en_US.UTF-8", "LC_ALL": "en_US.UTF-8"})
return r.stdout.strip()
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
�═════════════════════════════════
# Keyboard operations (pynput)
# ═══════════════════════════════════════════
# Map common key names to pynput Key objects
def _resolve_key(name):
"""Resolve a key name string to pynput Key or KeyCode."""
from pynput.keyboard import Key, KeyCode
key_map = {
"return": Key.enter, "enter": Key.enter,
"tab": Key.tab,
"esc": Key.esc, "escape": Key.esc,
"space": Key.space,
"delete": Key.backspace, "backspace": Key.backspace,
"fwd-delete": Key.delete,
"up": Key.up, "arrow-up": Key.up,
"down": Key.down, "arrow-down": Key.down,
"left": Key.left, "arrow-left": Key.left,
"right": Key.right, "arrow-right": Key.right,
"home": Key.home, "end": Key.end,
"page-up": Key.page_up, "page-down": Key.page_down,
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
e keyboard shortcut instead:
# In Excel Mac: click Name Box = Cmd+F5 doesn't work reliably
# Best approach: just press Ctrl+G or F5 for Go To dialog
if app == "Microsoft Excel":
# Excel Mac: use Ctrl+G to open Go To dialog, then type in Reference field
key_press("escape")
time.sleep(0.1)
# Open Go To dialog with Ctrl+G (not Cmd+G!)
from pynput.keyboard import Key, Controller as KBController
kb = KBController()
kb.press(Key.ctrl)
kb.press('g')
time.sleep(0.05)
kb.release('g')
kb.release(Key.ctrl)
time.sleep(0.8)
# Tab to the Reference field (it may not be focused by default)
# Actually in Excel Mac Go To, the Reference field IS focused
# But paste doesn't work there. Use type_text instead.
# Clear any existing text first
key_combo("command", "a")
time.sleep(0.05)
type_text(cell_ref)
time.sleep(0
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.
r = subprocess.run(
["swift", swift_file, img_path],
capture_output=True, text=True,
env={**os.environ, "LANG": "en_US.UTF-8"}
)
os.unlink(swift_file)
The statement 'no privacy filtering needed' dismisses privacy safeguards in a workflow that processes screenshots and stores cropped interface elements. This increases the likelihood that sensitive or regulated data present in the UI will be retained without review, especially because the same document contemplates dynamic content removal only after capture has already occurred.
The documentation describes remote screenshots, text input, and GUI control but does not warn users that screen contents and keystrokes may be transmitted to another machine or service. This omission undermines informed consent and increases the chance that sensitive data such as credentials, personal information, or proprietary content will be exposed during normal use.
The design expands a local GUI automation skill into remote device control over HTTP and SSH, which materially changes the trust and attack boundaries. That enables the agent to send clicks, keystrokes, window actions, and screenshots to external endpoints, creating a real risk of unauthorized remote control and data exposure beyond the stated local-only scope.
Remote HTTP control allows this skill to operate external GUI environments and retrieve screenshots over the network, which is a significant capability expansion from local automation. Without explicit scope declaration and security controls, this can lead to remote manipulation of systems and transmission of sensitive screen contents or typed data to untrusted services.