Skip to content

Optional app allowlist restricting which apps can be automated - #2

Merged
otykier merged 2 commits into
mainfrom
feature/app-allowlist
Aug 19, 2026
Merged

Optional app allowlist restricting which apps can be automated#2
otykier merged 2 commits into
mainfrom
feature/app-allowlist

Conversation

@otykier

@otykier otykier commented Aug 19, 2026

Copy link
Copy Markdown

Optional app allowlist

By default, FlaUI-MCP can automate any application on the desktop — File Explorer, browsers, terminals. If the driving agent is ever misled (e.g. by prompt injection), that is a large attack surface. This PR adds an opt-in allowlist restricting automation to specific apps, plus a fix to the blocked-provider guidance messages discovered while testing it.

App allowlist (c090b00)

Set the FLAUI_MCP_ALLOWED_APPS environment variable in the MCP config to a semicolon- or comma-separated list of process names (case-insensitive, .exe optional, full paths reduced to their file name):

"env": { "FLAUI_MCP_ALLOWED_APPS": "TabularEditor3" }

Unset or empty preserves the previous allow-everything behavior.

Enforcement points:

  • windows_launch refuses to start non-allowed executables.
  • Every window-handle registration in SessionManager funnels through one process check, so handles and element refs can only ever point at allowed apps — transitively scoping snapshot, click, type, fill, get_text, and screenshot by handle/ref. windows_list_windows silently filters other apps' windows and registers no handles for them.
  • Ref-less keyboard input (windows_send_keys / windows_type / batch type without a ref) verifies the foreground window belongs to an allowed process, and Win-key chords are rejected outright (they open system UI like Start and Win+R outside any allowlist) — even when the foreground app is allowed.
  • windows_screenshot refuses fullScreen capture and foreground capture of non-allowed apps, so other windows' content is not disclosed.

Scope, honestly stated (also in the README): matching is by process name, so this guards against a misdirected or prompt-injected agent driving unintended apps through this server — it is not a sandbox against a local attacker, and it does not constrain other tools the agent may hold. In-process dialogs of allowed apps (including the common file dialogs) keep working; separately spawned processes (e.g. a browser for OAuth) need their own list entry.

Guidance-string fix (b548936)

The blocked-provider and modal-detected messages recommended windows_screenshot with fullScreen: true — which is refused while the allowlist is active. They now recommend finding the dialog's own window handle via windows_list_windows (same process, so always allowed) and capturing by handle, which is the better advice in every mode: the Win32 window-bounds fallback works while the provider is blocked and includes an overlapping modal once painted. Also corrects "will hang" to "will fail" (blocked tools fail fast since the modal-aware-invoke change) and mentions waiting for the dialog to appear and take focus before sending keys, which a scripted sequence otherwise races.

Testing

  • Unit tests: new ProcessPolicyTests (parsing, name/path/PID matching, environment round-trip, denial messages, foreground check) — suite now 42 tests, all passing.
  • Verified live over MCP stdio with FLAUI_MCP_ALLOWED_APPS=TabularEditor3:
    • launching notepad → denied with a message naming the allowed apps;
    • windows_list_windows → only TE3 windows listed;
    • ref-less send_keys with a non-allowed foreground window → denied; Win+R → blocked even with the foreground app allowlisted;
    • full TE3 automation unaffected: launch, list, focus, ref-less keys (positive foreground path), snapshot with refs, screenshots by handle — including the complete modal-dialog workflow (click "Open..." → fail-fast guidance → dialog found via windows_list_windows → focused, dismissed with Esc → UIA recovered).

🤖 Generated with Claude Code

otykier and others added 2 commits August 19, 2026 10:12
By default the server can automate any application on the desktop - File
Explorer, browsers, terminals - which is a large attack surface if the
driving agent is misled (e.g. by prompt injection). Setting
FLAUI_MCP_ALLOWED_APPS (semicolon/comma-separated process names, case-
insensitive, ".exe" optional) restricts automation to the listed apps;
unset preserves the previous allow-everything behavior.

Enforcement points:
- windows_launch refuses non-allowed executables.
- Every window-handle registration in SessionManager verifies the owning
  process, so refs and handles - and with them all ref-based tools - can
  only point at allowed apps. windows_list_windows lists only allowed
  apps' windows and registers no handles for others.
- Ref-less keyboard input (send_keys/type/batch type without ref) checks
  that the foreground window belongs to an allowed process, and the
  Windows key is rejected outright since it opens system UI (Start, Win+R)
  outside any allowlist.
- windows_screenshot refuses fullScreen capture and foreground capture of
  non-allowed apps.

Matching is by process name: this guards against a misdirected agent
driving unintended apps through this server, not against a local attacker
who can rename executables, and it does not constrain other tools the
agent may hold. In-process dialogs of allowed apps (including common file
dialogs) keep working.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The blocked-provider and modal-detected messages told the agent to use
windows_screenshot with fullScreen: true, which is refused while the app
allowlist is active - conflicting guidance discovered while driving TE3
with FLAUI_MCP_ALLOWED_APPS set. Window-handle capture is the better
recommendation in every mode: its Win32 window-bounds fallback works while
the provider is blocked, includes an overlapping modal once painted, and
the dialog itself can be found and captured by its own handle via
windows_list_windows (same process, so always allowed).

Also corrects "will hang" to "will fail" (blocked tools fail fast since
the modal-aware-invoke change) and mentions giving the dialog a moment to
appear and take focus before sending keys, which a scripted sequence
otherwise races.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@otykier
otykier merged commit 6a39906 into main Aug 19, 2026
2 checks passed
@otykier
otykier deleted the feature/app-allowlist branch August 19, 2026 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant