Back to skill

Security audit

windows-automation

Security checks for vulnerabilities and agentic risk

Overview

This Windows automation skill matches its stated purpose, but it can control the desktop and has unsafe PowerShell command construction that needs review before installation.

Review this skill carefully before installing. It is not backed by evidence of exfiltration or persistence, but it can manipulate the live Windows desktop, capture visible information, terminate processes, and execute PowerShell built from user-provided values. It should be used only in a controlled environment after adding strict input validation, allowlists, explicit confirmations, and safer APIs that do not interpolate user input into PowerShell source.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/app_launcher.py:28
Finding
PowerShell Command Injection in Application Launch Parameters<![CDATA[ ## Vulnerability Details **File Location**: `scripts/app_launcher.py`, lines 28-46 **Vulnerability Type**: PowerShell command injection **Risk Level**: High ### Vulnerable Code ```python # Build the PowerShell command ps_cmd = f"Start-Process -FilePath '{app_path}'" if arguments: ps_cmd += f" -ArgumentList '{arguments}'" if working_dir: ps_cmd += f" -WorkingDirectory '{working_dir}'" if wait: ps_cmd += f" -Wait -Timeout {timeout}" # Execute the PowerShell command result = subprocess.run( ["powershell", "-Command", ps_cmd], capture_output=True, text=True, timeout=timeout + 10 ) ``` ### Technical Analysis The `app_path`, `arguments`, and `working_dir` values are interpolated directly into PowerShell source code enclosed by single quotes. No escaping, validation, or parameter separation is applied. An attacker-controlled value containing a single quote can terminate the intended PowerShell string. PowerShell statement delimiters can then introduce additional commands. Supplying the generated script as an element of a Python argument array does not prevent this vulnerability because `powershell -Command` deliberately parses that element as executable PowerShell source. The `url` command is also affected because `open_url()` passes the URL to the vulnerable `start_app()` function: ```python def open_url(url): return start_app(url, arguments="") ``` ### Attack Path 1. An attacker supplies a crafted application path or URL through an automation request. 2. The Agent invokes `app_launcher.py start <value>` or `app_launcher.py url <value>`. 3. The script inserts the value into `Start-Process -FilePath '<value>'`. 4. A quote in the value closes the intended string, after which injected PowerShell statements are parsed. 5. PowerShell executes the appended commands with the privileges of the Python/Agent process. ### Impact Assessment Successful exploitation provides arbitrary command execution under the current Age ...[truncated 319 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not generate PowerShell source code by interpolating untrusted values. - Launch executables directly with `subprocess.Popen()` or `subprocess.run()` using a structured argument list. - Use `webbrowser.open()` or an equivalent native API for URLs after validating the allowed URL schemes. - Pass application arguments as separate list elements rather than as one command string. - Canonicalize and validate application and working-directory paths. - Consider an allowlist of approved executables and URL schemes. - If PowerShell is unavoidable, pass values through separately bound parameters and treat them strictly as data rather than script fragments. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/app_launcher.py:104
Finding
PowerShell Command Injection in Process Termination<![CDATA[ ## Vulnerability Details **File Location**: `scripts/app_launcher.py`, lines 104-112 **Vulnerability Type**: PowerShell command injection **Risk Level**: High ### Vulnerable Code ```python try: ps_cmd = f"Stop-Process -Name '{process_name}' -Force" result = subprocess.run( ["powershell", "-Command", ps_cmd], capture_output=True, text=True ) ``` ### Technical Analysis The process name is inserted directly into a single-quoted PowerShell expression. Although the intended operation is process termination, the parameter is not constrained to a valid process-name format and is not escaped before PowerShell parses it. A crafted process name can close the quoted `-Name` argument and append additional PowerShell statements. The process-name value therefore crosses a data-to-code boundary. ### Attack Path 1. An attacker submits a crafted process name through a request to close or terminate an application. 2. The Agent invokes `app_launcher.py kill <process_name>`. 3. The script embeds the process name in the `Stop-Process` command. 4. PowerShell parses injected syntax following a prematurely closed string. 5. The injected statements execute as the current Agent account. ### Impact Assessment The attacker can execute arbitrary PowerShell commands with the permissions of the automation process. This could enable unauthorized file access, process execution, system modification, or persistence where the current account has sufficient rights. Even without command injection, unrestricted use of `Stop-Process -Force` can cause availability loss if the Skill is allowed to terminate arbitrary user processes. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Replace generated PowerShell with a native process-management API. - Resolve processes by a strictly validated name or numeric process identifier. - Restrict process names to an expected character set and preferably an explicit allowlist. - Require confirmation before terminating sensitive or unrelated processes. - If PowerShell must be retained, bind the process name as data instead of incorporating it into the command source. - Avoid forced termination unless it is explicitly necessary and authorized. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/keyboard_control.py:57
Finding
PowerShell Command Injection Through Keyboard Text Input<![CDATA[ ## Vulnerability Details **File Location**: `scripts/keyboard_control.py`, lines 57-73 **Vulnerability Type**: PowerShell command injection **Risk Level**: High ### Vulnerable Code ```python # Use the SendKeys method ps_script = f''' Add-Type -AssemblyName System.Windows.Forms $wshell = New-Object -ComObject WScript.Shell # Send text $wshell.SendKeys("{text}") ''' result = subprocess.run( ["powershell", "-Command", ps_script], capture_output=True, text=True, timeout=60 ) ``` ### Technical Analysis Text intended to be simulated as keyboard input is embedded directly inside a double-quoted PowerShell expression. No PowerShell escaping or parameter binding is applied. A text value containing quotation marks or other PowerShell syntax can break out of the `SendKeys()` argument and introduce executable statements. PowerShell also performs interpolation inside double-quoted strings, creating additional ambiguity between literal text and executable expressions. SendKeys has its own metacharacter syntax as well. Consequently, even non-malicious text containing reserved characters may be interpreted as special keystrokes rather than typed literally. ### Attack Path 1. An attacker supplies crafted text in a request to type into an application or form. 2. The Agent passes the text to `keyboard_control.py type`. 3. `type_text()` inserts the value into `$wshell.SendKeys("<text>")`. 4. Crafted syntax escapes the intended string or invokes PowerShell interpolation. 5. PowerShell executes attacker-controlled commands under the Agent's account. ### Impact Assessment Successful exploitation yields arbitrary command execution with the privileges of the Python/Agent process. Accessible files, applications, user data, and system settings could be affected. The vulnerability is especially exposed because arbitrary free-form text is an expected input for the Skill's normal form-filling workflows. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Use a native Python keyboard automation API rather than dynamically generated PowerShell. - If PowerShell is required, provide the text through a separately bound parameter, environment variable, or safely encoded data channel. - Apply correct SendKeys literal escaping independently from PowerShell escaping. - Check the PowerShell subprocess return code before reporting success. - Avoid returning sensitive typed text in status messages or logs. - Add tests covering quotation marks, dollar signs, braces, semicolons, backticks, and SendKeys metacharacters. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/screenshot.py:31
Finding
PowerShell Command Injection Through Full-Screen Screenshot Output Path<![CDATA[ ## Vulnerability Details **File Location**: `scripts/screenshot.py`, lines 31-58 **Vulnerability Type**: PowerShell command injection **Risk Level**: High ### Vulnerable Code ```python # Use PowerShell Add-Type to call the .NET screenshot API ps_script = f''' Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing $screen = [System.Windows.Forms.Screen]::AllScreens[{monitor}] $bitmap = New-Object System.Drawing.Bitmap $screen.Bounds.Width, $screen.Bounds.Height $graphics = [System.Drawing.Graphics]::FromImage($bitmap) $graphics.CopyFromScreen($screen.Bounds.X, $screen.Bounds.Y, 0, 0, $screen.Bounds.Size) $bitmap.Save("{output_path}", [System.Drawing.Imaging.ImageFormat]::Png) $graphics.Dispose() $bitmap.Dispose() Write-Output "{output_path}" ''' result = subprocess.run( ["powershell", "-Command", ps_script], capture_output=True, text=True, timeout=30 ) ``` ### Technical Analysis The caller-controlled screenshot output path is inserted twice into double-quoted PowerShell expressions without escaping or parameter binding. A path containing PowerShell syntax can terminate or alter those expressions and append executable statements. The command-line entry point accepts the path directly from `sys.argv`, so the sink is reachable through the documented `screen` operation. Numeric conversion of the monitor index limits injection through `monitor`, but it does not protect `output_path`. ### Attack Path 1. An attacker supplies a crafted output path in a screenshot request. 2. The Agent invokes `screenshot.py screen <output_path>`. 3. The path is interpolated into `$bitmap.Save()` and `Write-Output`. 4. PowerShell parses injected syntax from the crafted path. 5. The injected command executes with the Agent process's privileges. ### Impact Assessment An attacker can potentially execute arbitrary commands as the current Agent account. In addition, unrestricted output paths allow screenshot files to be writt ...[truncated 157 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Capture screenshots through native Python or .NET bindings without generating PowerShell source. - Bind the output path as data if PowerShell must be used. - Canonicalize the destination with `Path.resolve()` and restrict writes to an approved screenshot directory. - Generate server-side filenames rather than accepting arbitrary paths where possible. - Reject control characters and paths that escape the approved directory. - Prevent unintended overwrites by using exclusive file creation or explicit overwrite confirmation. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/screenshot.py:94
Finding
PowerShell Command Injection Through Window Screenshot Parameters<![CDATA[ ## Vulnerability Details **File Location**: `scripts/screenshot.py`, lines 94-139 **Vulnerability Type**: PowerShell command injection **Risk Level**: High ### Vulnerable Code ```python ps_script = f''' Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing $window = Get-Process | Where-Object {{$_.MainWindowTitle -like "*{window_title}*"}} | Select-Object -First 1 if ($window) {{ $rect = New-Object System.Drawing.Rectangle $rect = $window.MainWindowHandle | ForEach-Object {{ $p = New-Object System.Drawing.Point $s = New-Object System.Drawing.Size [System.Windows.Forms.NativeMethods]::GetWindowRect($_, [ref]$rect) }} $bitmap = New-Object System.Drawing.Bitmap $rect.Width, $rect.Height $graphics = [System.Drawing.Graphics]::FromImage($bitmap) $graphics.CopyFromScreen($rect.X, $rect.Y, 0, 0, $rect.Size) $bitmap.Save("{output_path}", [System.Drawing.Imaging.ImageFormat]::Png) $graphics.Dispose() $bitmap.Dispose() Write-Output "{output_path}" }} else {{ Write-Error "Window not found" }} ''' result = subprocess.run( ["powershell", "-Command", ps_script], capture_output=True, text=True, timeout=30 ) ``` ### Technical Analysis Both `window_title` and `output_path` are embedded directly into executable PowerShell. The title is placed inside a wildcard expression in a double-quoted string, while the output path is used inside `$bitmap.Save()` and `Write-Output`. A crafted title or path can alter PowerShell parsing and introduce new statements. Wildcard matching also means the selected target may differ from the exact window expected by the caller, potentially capturing a different visible window with a partially matching title. ### Attack Path 1. An attacker supplies a crafted window title or screenshot path. 2. The Agent invokes `screenshot.py window <title> <path>`. 3. `capture_window()` inserts both values into a PowerShell script. 4 ...[truncated 526 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Enumerate and capture windows through native APIs without dynamically generated PowerShell. - Pass window titles and paths as isolated data parameters if PowerShell remains necessary. - Prefer selecting windows by a verified process identifier or window handle rather than ambiguous partial-title matching. - Require confirmation when multiple windows match. - Canonicalize and restrict screenshot output paths to an approved directory. - Validate subprocess results and confirm that the selected window is the expected target before capture. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (45)

Missing User Warnings

High
Confidence
97% confidence
Finding
The skill describes capabilities for screenshots, keyboard simulation, mouse control, application launching, URL opening, and process termination without prominent warnings about privacy, security, and system impact. In this context, those actions can expose sensitive on-screen data, inject input into the wrong window, terminate important processes, or drive the machine in ways the user does not fully understand.

Missing User Warnings

High
Confidence
94% confidence
Finding
The documentation advertises high-impact capabilities including screenshots, keyboard/mouse control, URL opening, and process termination, but it does not clearly warn about privacy exposure, unintended system changes, or risks to active user sessions. In an automation skill, omission of these warnings makes unsafe use more likely and reduces informed consent for sensitive operations.

Vague Triggers

High
Confidence
95% confidence
Finding
The trigger list for application control uses broad everyday phrases such as opening or closing apps/websites without requiring a constrained invocation pattern, which increases the chance of accidental activation. In a Windows automation skill, accidental triggering can launch programs or URLs and cause unintended system actions with security and privacy consequences.

Vague Triggers

High
Confidence
97% confidence
Finding
Mouse and keyboard triggers include very generic verbs like click, type, and shortcut, making activation conditions unclear for actions that directly control the user's desktop. In this context, misfires can send input to the wrong window, approve prompts, alter documents, or trigger destructive shortcuts.

Vague Triggers

High
Confidence
97% confidence
Finding
The 'other' trigger category contains extremely broad terms like automation, RPA, and control app, which effectively widen activation to many unrelated user requests. For a skill capable of screenshots, process killing, and simulated input, this lack of boundary makes unintended invocation significantly more dangerous.

Missing User Warnings

High
Confidence
96% confidence
Finding
The skill description advertises capabilities including application control, screenshots, mouse control, and keyboard simulation but does not warn users that these are high-risk actions capable of manipulating the desktop, capturing sensitive information, or interfering with active sessions. Because this skill operates at the UI layer and can automate powerful actions, missing safety warnings increases the likelihood of unsafe use and insufficient user consent.

Vague Triggers

High
Confidence
95% confidence
Finding
The trigger list includes broad everyday phrases such as “点击”, “截图”, “自动化”, and “关闭应用”, which can match many benign user requests and unintentionally invoke powerful desktop-control actions. In the context of a Windows automation skill that can launch apps, kill processes, simulate keyboard input, and capture screens, accidental triggering could cause unauthorized UI actions, data exposure, or disruption.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger list is broad enough to activate on common requests like opening apps, taking screenshots, clicking, or typing without strong constraints that the user explicitly wants desktop automation. In an agent setting, this can cause the skill to be selected for sensitive actions that affect the host system, increasing the chance of unintended execution, privacy violations, or disruptive UI control.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The primary trigger section includes ambiguous standalone activators such as '点击', '截图', and '打开 [应用名称]' that may match routine conversational requests rather than deliberate consent to device automation. Because this skill can simulate input and control applications, ambiguous activation materially raises the risk of the agent performing real system actions when the user may have intended only informational assistance.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The module presents itself as an application launcher but also provides process enumeration and force-kill capabilities. This mismatch expands operational scope in a way users or higher-level agents may not expect, increasing the risk of misuse for host reconnaissance and service disruption.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
ps_cmd += f" -Wait -Timeout {timeout}"

        # 执行PowerShell命令
        result = subprocess.run(
            ["powershell", "-Command", ps_cmd],
            capture_output=True,
            text=True,
Confidence
98% confidence
Finding
`start_app` builds a PowerShell command string by interpolating untrusted `app_path`, `arguments`, and `working_dir` directly into `ps_cmd` and then executes it with `powershell -Command`. Because single quotes in attacker-controlled input can break out of the quoted context, this creates a command injection path that can execute arbitrary PowerShell commands under the current user's privileges.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""
    try:
        ps_cmd = "Get-Process | Select-Object Name, Id, Path | ConvertTo-Json"
        result = subprocess.run(
            ["powershell", "-Command", ps_cmd],
            capture_output=True,
            text=True
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The force-kill functionality uses `Stop-Process -Force` with no confirmation, policy check, or safeguard. In an agent skill context, this makes accidental or malicious disruption easier by allowing arbitrary process termination without friction, potentially killing security tools, productivity apps, or critical user processes.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""
    try:
        ps_cmd = f"Stop-Process -Name '{process_name}' -Force"
        result = subprocess.run(
            ["powershell", "-Command", ps_cmd],
            capture_output=True,
            text=True
Confidence
97% confidence
Finding
`kill_app` interpolates untrusted `process_name` into a PowerShell `Stop-Process` command string and executes it via `powershell -Command`. An attacker can inject quotes or additional PowerShell syntax to run arbitrary commands, and even without injection the function enables forceful termination of arbitrary processes, which can be abused for denial of service.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This skill can send arbitrary keystrokes and hotkeys to whatever application has focus, which can trigger destructive actions, data exfiltration, or unintended confirmations without any warning, consent boundary, or safety gating. In an agent skill context, UI automation is more dangerous because it can affect external applications and sensitive user sessions outside the skill's own scope.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
$wshell.SendKeys("{text}")
        '''

        result = subprocess.run(
            ["powershell", "-Command", ps_script],
            capture_output=True,
            text=True,
Confidence
94% confidence
Finding
This PowerShell subprocess executes a dynamically constructed script that embeds untrusted text directly into a SendKeys call. If the input contains quotes or PowerShell metacharacters, it can break out of the intended string context and alter the script being run, turning keyboard automation into command/script injection with the privileges of the current user.

Context-Inappropriate Capability

Medium
Confidence
86% confidence
Finding
With no manifest available, the documented purpose is limited to keyboard input simulation. Implementing that by invoking external PowerShell processes adds a command-execution capability beyond the apparent need of a keyboard-control utility, since the same behavior could be implemented directly without spawning a shell.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
[Keyboard]::keybd_event({key_code}, 0, [Keyboard]::KEYEVENTF_KEYUP, 0)
        '''

        subprocess.run(
            ["powershell", "-Command", ps_script],
            capture_output=True,
            text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
[Keyboard]::keybd_event({key_code}, 0, [Keyboard]::KEYEVENTF_KEYUP, 0)
        '''

        subprocess.run(
            ["powershell", "-Command", ps_script],
            capture_output=True,
            text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill exposes mouse movement and clicking primitives that act on the live system without user confirmation, disclosure, or environmental safeguards. In an agent skill context, this is dangerous because UI automation can be chained to dismiss warnings, authorize actions, manipulate applications, or interfere with a user's desktop unexpectedly.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The docstring says the `relative` parameter controls whether movement is relative, implying movement offset from the current cursor position. However, both the `relative=True` and `relative=False` branches call `SetCursorPos(x, y)`, which sets an absolute screen position in either case.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
        # 获取当前屏幕尺寸
        ps_cmd = "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.Screen]::PrimaryScreen.Bounds | Select-Object Width, Height | ConvertTo-Json"
        result = subprocess.run(
            ["powershell", "-Command", ps_cmd],
            capture_output=True,
            text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
[Mouse]::SetCursorPos({x}, {y})
            '''

        result = subprocess.run(
            ["powershell", "-Command", ps_script],
            capture_output=True,
            text=True,
Confidence
90% confidence
Finding
This code builds a PowerShell script with Python f-string interpolation of x and y, then executes it via PowerShell. Although the CLI path casts arguments to integers, the function itself accepts untrusted parameters and, if imported or reused elsewhere, could permit script injection or unintended UI control on the host system.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
}}
        '''

        subprocess.run(
            ["powershell", "-Command", ps_script],
            capture_output=True,
            text=True,
Confidence
86% confidence
Finding
This subprocess call executes PowerShell-generated mouse click automation against the live desktop without any privilege separation or execution guard. In an agent skill context, such UI-driving capability can be abused to perform unintended clicks, approve prompts, or interfere with the user session.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
Drag-and-drop is a higher-risk UI automation primitive because it can move files, reorder data, change settings, or trigger unintended destructive state changes in arbitrary applications. The lack of confirmation or context restrictions makes the skill materially more dangerous in an agent environment.

Static analysis

No suspicious patterns detected.