Back to skill

Security audit

IATerm WebSocket Agent

Security checks for vulnerabilities and agentic risk

Overview

This skill is purpose-built to control IATerm terminals, but it gives agents high-impact terminal access with approval bypass and persistent authorization paths.

Install only if you intentionally want an agent to control IATerm terminal sessions, including remote SSH or serial sessions. Avoid --auto-approve and the always-approve option unless you fully trust every caller and workflow using the skill; clear ~/.cache/iaterm-ws-client if approval state should be reset. Prefer a pinned, reviewed websockets dependency and treat interactive raw JSON mode as unsafe for sensitive terminal operations until it enforces the same approval checks as the normal commands.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/ws_client.py:317
Finding

Interactive Mode Bypasses Approval Controls for Sensitive Terminal Operations

Content
View full analysis
", end="", flush=True) except websockets.exceptions.ConnectionClosed: pass reader_task = asyncio.create_task(reader()) loop = asyncio.get_event_loop() try: while True: print("> ", end="", flush=True) line = await loop.run_in_executor(None, sys.stdin.readline) line = line.strip() if not line: continue if line == "q": break if line in shortcuts: method, params = shortcuts[line] req_id = str(uuid.uuid4())[:8] msg = {"id": req_id, "method": method, "params": params, "toke ...[truncated 3630 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:22
Finding

Unpinned Runtime Installation of the WebSockets Dependency

Content
View full analysis
/dev/null || pip3 install websockets 2>/dev/null ``` ``` ### Technical Analysis The installation instruction requests the package named `websockets` without specifying a reviewed version, lock file, package hash, index, or trusted-source policy. The effective dependency can therefore change after the Skill has been audited. Installing a mutable latest release at runtime creates both supply-chain and reliability risks. A future compromised release, compromised package repository, maliciously configured Python package index, or unexpected dependency resolution result could introduce code that was not present during this audit. Python packages may execute code during installation and are subsequently imported at client startup: ```python import websockets ``` The suppression of standard error with `2>/dev/null` also reduces visibility into resolver warnings, repository errors, and other diagnostic information that could reveal an unsafe installation source. No evidence was found that the currently named `websockets` project is malicious. The finding concerns the unsafe dependency acquisition practice and the resulting inability to reproduce the audited dependency set. ### Attack Path 1. An operator follows the prerequisite command from `SKILL.md`. 2. `pip` resolves `websockets` using the active Python and package-index configuration. 3. Because no version or hash is specified, the resolver selects whatever release and artifact are currently available and compatible. 4. An attacker who has compromised the selected release, package repository, index configuration, or network/package-distribution path supplies a malicious artifact. 5. The artifact executes code during installation or when `ws_client.py` imports `webso ...[truncated 834 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (32)

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
85% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · SKILL.md (reported line 81)May include surrounding context.

md
### List active connections

**IMPORTANT:** `list_connections` only returns **remote** connections (SSH, Serial, JumpServer). Local terminal connections are automatically filtered out by the backend. If this command returns connections, they are ALL remote — do NOT judge by the `name` field. Always check the `connection_type` field to determine the actual type:
- `ssh` — SSH remote connection
- `serial` — Serial port connection

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill exposes powerful capabilities—environment-variable access, file reads/writes, and network interaction with a localhost terminal-control WebSocket API—but declares no explicit tool scope or permission boundaries. In an agent setting, this increases the chance that the skill can be invoked with broader authority than intended, enabling terminal interaction and local state modification without a machine-readable restriction layer.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

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.

Content

Scanner excerpt · SKILL.md (reported line 14)May include surrounding context.

CRITICAL: Always use the ws_client.py script

NEVER write inline WebSocket code. Always use the provided CLI script at scripts/ws_client.py (relative to this skill file).

Find the script path:

bash

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
93% confidence
Finding

The skill describes caching a ws_token so subsequent connections can skip fresh user approval. In a terminal-control skill, persistent authorization materially increases risk because later invocations may gain command and output access without renewed user intent, especially if the invoking agent or local account is compromised.

Content

Scanner excerpt · SKILL.md (reported line 32)May include surrounding context.

md
`IATERM_SESSION_ID` environment variable must be set by the host application (e.g. IATerm) before invoking the client. **Do NOT generate this value yourself** — if the variable is missing, the client will exit with an error, indicating the host application has not properly initialized the session.

The first command triggers user approval in the IATerm UI. Once approved, the WS token is cached at `~/.cache/iaterm-ws-client/ws_token.json` (permissions 0600). Subsequent commands reuse the cached token and skip approval.

If the token expires, the client automatically clears the cache and re-prompts for approval.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
98% confidence
Finding

This finding is substantively the same risky behavior as the earlier auto-approve reference: it advertises a flag that suppresses all prompts before sending terminal input. That creates a straightforward path for automated command execution without human review.

Content

Scanner excerpt · SKILL.md (reported line 50)May include surrounding context.

  • n — reject (command exits with error)
  • a — always approve for this specific target (saved to ~/.cache/iaterm-ws-client/approval.json)

Use --auto-approve to skip all confirmation prompts (for automated pipelines):

bash
python3 "$WS_CLIENT" --auto-approve send_input --connection-id <id> --data "ls\n"

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
98% confidence
Finding

This finding is substantively the same risky behavior as the earlier auto-approve reference: it advertises a flag that suppresses all prompts before sending terminal input. That creates a straightforward path for automated command execution without human review.

Content

Scanner excerpt · SKILL.md (reported line 50)May include surrounding context.

  • n — reject (command exits with error)
  • a — always approve for this specific target (saved to ~/.cache/iaterm-ws-client/approval.json)

Use --auto-approve to skip all confirmation prompts (for automated pipelines):

bash
python3 "$WS_CLIENT" --auto-approve send_input --connection-id <id> --data "ls\n"

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
98% confidence
Finding

This duplicate occurrence again documents full prompt suppression for automated pipelines, which weakens the intended safeguard model. In a terminal-control skill, repeated encouragement of such bypass materially increases the chance of unsafe integration patterns.

Content

Scanner excerpt · SKILL.md (reported line 53)May include surrounding context.

Use --auto-approve to skip all confirmation prompts (for automated pipelines):

bash
python3 "$WS_CLIENT" --auto-approve send_input --connection-id <id> --data "ls\n"

Commands

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
98% confidence
Finding

This duplicate occurrence again documents full prompt suppression for automated pipelines, which weakens the intended safeguard model. In a terminal-control skill, repeated encouragement of such bypass materially increases the chance of unsafe integration patterns.

Content

Scanner excerpt · SKILL.md (reported line 53)May include surrounding context.

Use --auto-approve to skip all confirmation prompts (for automated pipelines):

bash
python3 "$WS_CLIENT" --auto-approve send_input --connection-id <id> --data "ls\n"

Commands

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
97% confidence
Finding

This repeated mention confirms immediate execution after cached auth plus optional prompt bypass, reducing friction for remote terminal manipulation. The context makes it more dangerous than generic automation because the target surface includes live remote connections and terminal output streams.

Content

Scanner excerpt · SKILL.md (reported line 109)May include surrounding context.

md
2. **First connection** — sends `identify(session_id)` → user approves in IATerm UI (up to 60s) → receives `ws_token` → cached to disk.
3. **Subsequent connections** — sends `identify(session_id + cached token)` → server recognizes the token → skips approval → executes immediately.
4. **Token expiry** — if the server rejects a cached token (error -15 or `connection_rejected`), the client clears the cache and retries with a fresh approval flow.
5. **Approval gate** — `send_input` and `subscribe_output` prompt for interactive confirmation (y/n/a) unless `--auto-approve` is set.

## Configuration

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
97% confidence
Finding

This repeated mention confirms immediate execution after cached auth plus optional prompt bypass, reducing friction for remote terminal manipulation. The context makes it more dangerous than generic automation because the target surface includes live remote connections and terminal output streams.

Content

Scanner excerpt · SKILL.md (reported line 109)May include surrounding context.

md
2. **First connection** — sends `identify(session_id)` → user approves in IATerm UI (up to 60s) → receives `ws_token` → cached to disk.
3. **Subsequent connections** — sends `identify(session_id + cached token)` → server recognizes the token → skips approval → executes immediately.
4. **Token expiry** — if the server rejects a cached token (error -15 or `connection_rejected`), the client clears the cache and retries with a fresh approval flow.
5. **Approval gate** — `send_input` and `subscribe_output` prompt for interactive confirmation (y/n/a) unless `--auto-approve` is set.

## Configuration

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
97% confidence
Finding

The repeated changelog entry documents persistent approvals and approval bypass as product features, not incidental behavior. That normalizes insecure operation for a capability that can control remote terminals, increasing the impact of misuse.

Content

Scanner excerpt · SKILL.md (reported line 138)May include surrounding context.

md
**操作审批**
- `send_input` / `subscribe_output` 执行前交互式确认:y(本次通过)/ n(拒绝)/ a(始终通过)
- 选 `a` 记入 `~/.cache/iaterm-ws-client/approval.json`,后续同目标操作自动通过
- `--auto-approve` CLI 参数跳过所有确认(用于自动化流水线)

**文档补充**
- `list_connections` 明确只返回远程连接(SSH/Serial/JumpServer),本地终端被后端过滤

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
97% confidence
Finding

The repeated changelog entry documents persistent approvals and approval bypass as product features, not incidental behavior. That normalizes insecure operation for a capability that can control remote terminals, increasing the impact of misuse.

Content

Scanner excerpt · SKILL.md (reported line 138)May include surrounding context.

md
**操作审批**
- `send_input` / `subscribe_output` 执行前交互式确认:y(本次通过)/ n(拒绝)/ a(始终通过)
- 选 `a` 记入 `~/.cache/iaterm-ws-client/approval.json`,后续同目标操作自动通过
- `--auto-approve` CLI 参数跳过所有确认(用于自动化流水线)

**文档补充**
- `list_connections` 明确只返回远程连接(SSH/Serial/JumpServer),本地终端被后端过滤

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/ws_client.py (reported line 11)May include surrounding context.

python
Connection flow:
  - Session ID from IATERM_SESSION_ID env var (required)
  - First connection: identify(session_id) → IATerm UI approval → ws_token → cached
  - Subsequent connections: identify(session_id + cached token) → server recognizes → skip approval
  - Token invalidated: auto-clear cache, re-prompt approval

Usage:

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
94% confidence
Finding

The approval function is designed to permit sensitive terminal actions without fresh human confirmation when auto_approve is enabled or persistent approvals exist. In a skill that can send terminal input and subscribe to output, this weakens the human-in-the-loop control boundary and can allow an external agent to act autonomously on a local terminal session.

Content

Scanner excerpt · scripts/ws_client.py (reported line 125)May include surrounding context.

python
json.dump(approvals, f, indent=2)


def _check_approval(method, params, auto_approve=False):
    """Check if an operation needs approval. Returns True if approved, False if rejected."""
    # Only gate sensitive operations
    if method not in ("send_input", "subscribe_output"):

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
96% confidence
Finding

This branch causes all approval checks for sensitive operations to be skipped whenever --auto-approve is set. Because the skill can inject input into active terminal connections and read terminal output, an agent or caller that can enable this flag gains unattended command execution and surveillance capability over local terminal sessions.

Content

Scanner excerpt · scripts/ws_client.py (reported line 131)May include surrounding context.

python
if method not in ("send_input", "subscribe_output"):
        return True

    if auto_approve:
        return True

    # Check persistent approvals

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/ws_client.py (reported line 286)May include surrounding context.

python
print(json.dumps(data.get("result", data), ensure_ascii=False, indent=2))


async def cmd_execute(method, params=None, auto_approve=False, client_type="ws-client", client_id=None):
    """Execute a single command: connect, request, disconnect."""
    session_id = _get_session_id()
    params = params or {}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/ws_client.py (reported line 292)May include surrounding context.

python
print(json.dumps(data.get("result", data), ensure_ascii=False, indent=2))


async def cmd_execute(method, params=None, auto_approve=False, client_type="ws-client", client_id=None):
    """Execute a single command: connect, request, disconnect."""
    session_id = _get_session_id()
    params = params or {}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/ws_client.py (reported line 304)May include surrounding context.

python
print(json.dumps(data.get("result", data), ensure_ascii=False, indent=2))


async def cmd_execute(method, params=None, auto_approve=False, client_type="ws-client", client_id=None):
    """Execute a single command: connect, request, disconnect."""
    session_id = _get_session_id()
    params = params or {}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/ws_client.py (reported line 309)May include surrounding context.

python
print(json.dumps(data.get("result", data), ensure_ascii=False, indent=2))


async def cmd_execute(method, params=None, auto_approve=False, client_type="ws-client", client_id=None):
    """Execute a single command: connect, request, disconnect."""
    session_id = _get_session_id()
    params = params or {}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/ws_client.py (reported line 443)May include surrounding context.

python
print(json.dumps(data.get("result", data), ensure_ascii=False, indent=2))


async def cmd_execute(method, params=None, auto_approve=False, client_type="ws-client", client_id=None):
    """Execute a single command: connect, request, disconnect."""
    session_id = _get_session_id()
    params = params or {}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/ws_client.py (reported line 446)May include surrounding context.

python
print(json.dumps(data.get("result", data), ensure_ascii=False, indent=2))


async def cmd_execute(method, params=None, auto_approve=False, client_type="ws-client", client_id=None):
    """Execute a single command: connect, request, disconnect."""
    session_id = _get_session_id()
    params = params or {}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/ws_client.py (reported line 448)May include surrounding context.

python
print(json.dumps(data.get("result", data), ensure_ascii=False, indent=2))


async def cmd_execute(method, params=None, auto_approve=False, client_type="ws-client", client_id=None):
    """Execute a single command: connect, request, disconnect."""
    session_id = _get_session_id()
    params = params or {}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/ws_client.py (reported line 453)May include surrounding context.

python
print(json.dumps(data.get("result", data), ensure_ascii=False, indent=2))


async def cmd_execute(method, params=None, auto_approve=False, client_type="ws-client", client_id=None):
    """Execute a single command: connect, request, disconnect."""
    session_id = _get_session_id()
    params = params or {}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/ws_client.py (reported line 455)May include surrounding context.

python
print(json.dumps(data.get("result", data), ensure_ascii=False, indent=2))


async def cmd_execute(method, params=None, auto_approve=False, client_type="ws-client", client_id=None):
    """Execute a single command: connect, request, disconnect."""
    session_id = _get_session_id()
    params = params or {}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/ws_client.py (reported line 460)May include surrounding context.

python
print(json.dumps(data.get("result", data), ensure_ascii=False, indent=2))


async def cmd_execute(method, params=None, auto_approve=False, client_type="ws-client", client_id=None):
    """Execute a single command: connect, request, disconnect."""
    session_id = _get_session_id()
    params = params or {}