T03 · Remote Payload Retrieval and Execution
- Location
README.md:14- Finding
Unverified Remote Installer Scripts Are Executed Directly
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This appears to be a legitimate GUI automation skill, but it grants powerful host-control capabilities and documents high-risk installation, persistence, recording, browser-profile, and approval-bypass modes that need manual review.
Install only if you intentionally want an agent to control real desktop apps. Prefer isolated browser profiles, avoid existing authenticated profiles unless necessary, do not enable recording around secrets, review or replace the remote installer flow with a verified package, and disable autostart or unrestricted embedded mode unless you have a specific need and understand the exposure.
README.md:14Unverified Remote Installer Scripts Are Executed Directly
WINDOWS.md:458GUI Automation Daemon Persists Across Windows Logons Through a Scheduled Task
EMBEDDING.md:101Embedded Mode Can Disable Runtime Approval Boundaries
RECORDING.md:67Trajectory Recording Stores Full Text-Input Arguments in Plaintext Artifacts
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
-o ExampleAgentHarness.app/Contents/MacOS/ExampleAgentHarness \
-framework ApplicationServices
printf '%s\n' '<?xml version="1.0" encoding="UTF-8"?>' \
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' \
'<plist version="1.0"><dict>' \
'<key>CFBundleExecutable</key><string>ExampleAgentHarness</string>' \
'<key>CFBundleIdentifier</key><string>com.trycua.example-agent-harness</string>' \
The skill documents capabilities for background input injection, screenshots, app launching, and session recording without a prominent safety notice, consent boundary, or privacy warning. In a GUI-driving skill, these features can enable covert interaction with user applications and capture sensitive on-screen data, so omission of upfront risk guidance materially increases misuse risk even if the document is otherwise technical.
The file repeatedly states that every form of open activates the target and must never be used for app launch, framing this as a strict no-foreground rule. Later, the prerequisites recommend exactly such an open invocation to start CuaDriver, which directly contradicts the earlier documented rule and creates intent-level inconsistency for operators following the guide.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
**Never use `open` for any app launch.** This includes launching
a just-built .app from a local build dir (e.g. `open
build/Build/Products/Debug/MyApp.app`) — resolve the
`CFBundleIdentifier` from `Info.plist` and use `launch_app`
with that id. See "The narrow carve-out" below for why
`launch_app` is safe even when the app internally calls
`NSApp.activate`.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
**Never use `open` for any app launch.** This includes launching
a just-built .app from a local build dir (e.g. `open
build/Build/Products/Debug/MyApp.app`) — resolve the
`CFBundleIdentifier` from `Info.plist` and use `launch_app`
with that id. See "The narrow carve-out" below for why
`launch_app` is safe even when the app internally calls
`NSApp.activate`.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
**Never use `open` for any app launch.** This includes launching
a just-built .app from a local build dir (e.g. `open
build/Build/Products/Debug/MyApp.app`) — resolve the
`CFBundleIdentifier` from `Info.plist` and use `launch_app`
with that id. See "The narrow carve-out" below for why
`launch_app` is safe even when the app internally calls
`NSApp.activate`.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
**Never use `open` for any app launch.** This includes launching
a just-built .app from a local build dir (e.g. `open
build/Build/Products/Debug/MyApp.app`) — resolve the
`CFBundleIdentifier` from `Info.plist` and use `launch_app`
with that id. See "The narrow carve-out" below for why
`launch_app` is safe even when the app internally calls
`NSApp.activate`.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
**Never use `open` for any app launch.** This includes launching
a just-built .app from a local build dir (e.g. `open
build/Build/Products/Debug/MyApp.app`) — resolve the
`CFBundleIdentifier` from `Info.plist` and use `launch_app`
with that id. See "The narrow carve-out" below for why
`launch_app` is safe even when the app internally calls
`NSApp.activate`.
The instruction to always name the focus steal in a fixed English phrase is natural-language guidance that assumes English output. The file does not offer a language/locale choice or state that the wording should match the user's language, which can violate language-choice policy.
The self-check presents an unconditional decision rule: if a command foregrounds an app, moves the real cursor, or bypasses cua-driver, it says to stop. Later sections on canvases/viewports and frontmost-gated menu commands explicitly approve osascript activate and CGEvent.post(...cghidEventTap) with visible cursor movement in narrow cases, which contradicts the earlier operational guidance rather than merely extending it.
This section instructs the agent to use a specific English disclosure such as 'Briefly activating Preview to enable Tools → Rotate Right.' Because the guidance does not permit or require adapting to the user's language, it risks forcing English-language interaction.
The document describes session recording, per-turn screenshots, before/after accessibility state, full input arguments, and video capture by default, but it does not prominently warn that these artifacts can contain sensitive screen contents, typed secrets, personal data, or application state. In a GUI automation skill operating on real host applications, this omission materially increases the chance that users or downstream agents enable recording in unsafe contexts and store sensitive data in output directories or training datasets.
The skill advertises itself for broadly phrased requests to 'operate, drive, automate, or perform a GUI task in a real application on the host,' which can cause it to trigger on loosely related requests and grant an agent powerful host-GUI control too readily. In the context of a GUI-driving skill, overbroad invocation materially increases the chance of unintended execution against sensitive local applications, files, or user sessions.
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| state | `get_window_state` | element-index click (AX/UIA) | `press_key` commit | pixel click |
| -------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------- | ----------------------------------------------------- | ------------------------------ |
| frontmost | ✅ | ✅ | ✅ | ✅ |
| backgrounded / visible | ✅ | ✅ | ✅ | ✅ |
| **minimized** | ✅ | ✅ (actions fire in place) | ❌ silent no-op — use `set_value` or click equivalent | ❌ no on-screen bounds |
| hidden | ✅ | ✅ | depends | ❌ |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| state | `get_window_state` | element-index click (AX/UIA) | `press_key` commit | pixel click |
| -------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------- | ----------------------------------------------------- | ------------------------------ |
| frontmost | ✅ | ✅ | ✅ | ✅ |
| backgrounded / visible | ✅ | ✅ | ✅ | ✅ |
| **minimized** | ✅ | ✅ (actions fire in place) | ❌ silent no-op — use `set_value` or click equivalent | ❌ no on-screen bounds |
| hidden | ✅ | ✅ | depends | ❌ |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| state | `get_window_state` | element-index click (AX/UIA) | `press_key` commit | pixel click |
| -------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------- | ----------------------------------------------------- | ------------------------------ |
| frontmost | ✅ | ✅ | ✅ | ✅ |
| backgrounded / visible | ✅ | ✅ | ✅ | ✅ |
| **minimized** | ✅ | ✅ (actions fire in place) | ❌ silent no-op — use `set_value` or click equivalent | ❌ no on-screen bounds |
| hidden | ✅ | ✅ | depends | ❌ |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| state | `get_window_state` | element-index click (AX/UIA) | `press_key` commit | pixel click |
| -------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------- | ----------------------------------------------------- | ------------------------------ |
| frontmost | ✅ | ✅ | ✅ | ✅ |
| backgrounded / visible | ✅ | ✅ | ✅ | ✅ |
| **minimized** | ✅ | ✅ (actions fire in place) | ❌ silent no-op — use `set_value` or click equivalent | ❌ no on-screen bounds |
| hidden | ✅ | ✅ | depends | ❌ |
The skill documents writing screenshots to disk and optionally recording sessions, but does not require a prominent user-facing warning before these data collection actions occur. Because this skill can capture sensitive application contents and persist them to files, missing disclosure and consent language raises privacy and data-handling risk, especially on real host systems.
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
ignored on pixel-only forms unless you want to anchor the conversion
against a specific window.
| Intent | Tool | Notes |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| List an app's windows | `list_windows({pid})` | returns `window_id`, `title`, `bounds`, `z_index`, `is_on_screen`, `on_current_space`. Already included in `launch_app`'s response — only call this for long-lived pids |
| Snapshot a window | `get_window_state({pid, window_id})` | returns `tree_markdown` + `screenshot_*`; populates the `(pid, window_id)` element_index cache |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
ignored on pixel-only forms unless you want to anchor the conversion
against a specific window.
| Intent | Tool | Notes |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| List an app's windows | `list_windows({pid})` | returns `window_id`, `title`, `bounds`, `z_index`, `is_on_screen`, `on_current_space`. Already included in `launch_app`'s response — only call this for long-lived pids |
| Snapshot a window | `get_window_state({pid, window_id})` | returns `tree_markdown` + `screenshot_*`; populates the `(pid, window_id)` element_index cache |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
ignored on pixel-only forms unless you want to anchor the conversion
against a specific window.
| Intent | Tool | Notes |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| List an app's windows | `list_windows({pid})` | returns `window_id`, `title`, `bounds`, `z_index`, `is_on_screen`, `on_current_space`. Already included in `launch_app`'s response — only call this for long-lived pids |
| Snapshot a window | `get_window_state({pid, window_id})` | returns `tree_markdown` + `screenshot_*`; populates the `(pid, window_id)` element_index cache |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| Intent | Tool | Notes |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| List an app's windows | `list_windows({pid})` | returns `window_id`, `title`, `bounds`, `z_index`, `is_on_screen`, `on_current_space`. Already included in `launch_app`'s response — only call this for long-lived pids |
| Snapshot a window | `get_window_state({pid, window_id})` | returns `tree_markdown` + `screenshot_*`; populates the `(pid, window_id)` element_index cache |
| Left click | `click({pid, window_id, element_index})` | default `action: "press"`. Pixel form: `click({pid, x, y})` (window_id optional) — `modifier: ["cmd"\|"ctrl"]` |
| Double-click / open | `double_click({pid, window_id, element_index})` | Default action
...[truncated 25 chars]
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| Intent | Tool | Notes |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| List an app's windows | `list_windows({pid})` | returns `window_id`, `title`, `bounds`, `z_index`, `is_on_screen`, `on_current_space`. Already included in `launch_app`'s response — only call this for long-lived pids |
| Snapshot a window | `get_window_state({pid, window_id})` | returns `tree_markdown` + `screenshot_*`; populates the `(pid, window_id)` element_index cache |
| Left click | `click({pid, window_id, element_index})` | default `action: "press"`. Pixel form: `click({pid, x, y})` (window_id optional) — `modifier: ["cmd"\|"ctrl"]` |
| Double-click / open | `double_click({pid, window_id, element_index})` | Default action
...[truncated 25 chars]
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| -------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| List an app's windows | `list_windows({pid})` | returns `window_id`, `title`, `bounds`, `z_index`, `is_on_screen`, `on_current_space`. Already included in `launch_app`'s response — only call this for long-lived pids |
| Snapshot a window | `get_window_state({pid, window_id})` | returns `tree_markdown` + `screenshot_*`; populates the `(pid, window_id)` element_index cache |
| Left click | `click({pid, window_id, element_index})` | default `action: "press"`. Pixel form: `click({pid, x, y})` (window_id optional) — `modifier: ["cmd"\|"ctrl"]` |
| Double-click / open | `double_click({pid, window_id, element_index})` | Default action when the element advertises one (Open on Finder items / openable rows), else stamped pixel double-click at the element's center |
| Right click / context menu | `right_click({pid, window_id, element_index})` or `click({pid, window_id, element_index, action: "show_menu"})` | Browser page c
...[truncated 25 chars]
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| Snapshot a window | `get_window_state({pid, window_id})` | returns `tree_markdown` + `screenshot_*`; populates the `(pid, window_id)` element_index cache |
| Left click | `click({pid, window_id, element_index})` | default `action: "press"`. Pixel form: `click({pid, x, y})` (window_id optional) — `modifier: ["cmd"\|"ctrl"]` |
| Double-click / open | `double_click({pid, window_id, element_index})` | Default action when the element advertises one (Open on Finder items / openable rows), else stamped pixel double-click at the element's center |
| Right click / context menu | `right_click({pid, window_id, element_index})` or `click({pid, window_id, element_index, action: "show_menu"})` | Browser page content should use the typed route where available; see `BROWSER.md` |
| Type at cursor | `type_text({pid, text, window_id, element_index})` (ax) or `type_text({pid, text, window_id, x, y})` (px) | ax focuses the element then writes via the platform's text-set primitive; **px** pixel-clicks `(x,y)` to focus the renderer, then types — the one-call fix for Chromium/Electron inputs the AX path can't reach |
| Set whole non-text control value | `set_value({pid, window_id, element_index, value})` | **AX-only by d
...[truncated 25 chars]