Skip to content

Permission dialogs execute unescaped model-generated text via os.system on macOS/Linux #196

Description

@MackDing

Summary

The CLI permission dialog interpolates model-generated code and action_description directly into shell commands passed to os.system(...) on macOS and Linux.

This means a malicious or simply malformed action string can break quoting and execute arbitrary shell commands before the user approves the action.

Affected code

Examples:

  • gui_agents/s3/cli_app.py
  • gui_agents/s2_5/cli_app.py
  • gui_agents/s2/cli_app.py
  • gui_agents/s1/cli_app.py

Current pattern:

result = os.system(
    f'osascript -e \'display dialog "Do you want to execute this action?\n\n{code} which will try to {action_description}" ...\''
)

and on Linux:

result = os.system(
    f'zenity --question --title="Action Permission" --text="Do you want to execute this action?\n\n{code}" ...'
)

Impact

Because code originates from the agent/model, an attacker who can influence the generated action text may inject quotes / shell metacharacters and achieve command execution in the host shell that launches the permission prompt.

That defeats the purpose of the confirmation barrier.

Expected behavior

Permission dialogs should treat the action text as data, not shell syntax.

Suggested fix

  • Replace os.system(...) with subprocess.run([...], check=False).
  • Pass dialog arguments as argv items instead of shell strings.
  • Escape/encode the displayed action text safely for osascript / zenity.
  • Add regression tests covering quotes, backticks, $(), semicolons, and newlines in code / action_description.

Extra note

There are other intentionally dangerous execution paths in this repo (for example explicit exec(...) of approved GUI code, and the optional local code environment). Those are documented features. This issue is narrower: the permission prompt itself is currently shell-injection-prone.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions