Back to skill

Security audit

container-host-aiops

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed container-host administration skill, but it exposes root-equivalent container controls and lacks an internal read-only or approval gate.

Treat this as an administrator-only skill. Install it only in a trusted environment, prefer read-only Docker socket mounts or Portainer accounts without write scope for observation, avoid exposing it to untrusted prompts, keep TLS verification enabled outside labs, and use dry-run plus backups before destructive prune, remove, or redeploy actions.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Docker Socket Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The skill explicitly supports connecting to the local Docker socket at /var/run/docker.sock and correctly notes that socket access is root-equivalent. Any agent or user invoking this skill against that socket can inspect the host and perform powerful container operations, including writes such as restart, remove, prune, resource-limit updates, and stack recreation; in practice this can be leveraged for host compromise or destructive actions if the skill is exposed to untrusted prompts or over-privileged accounts.

Content

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

md
compatibility: >
  Standalone, self-governed Docker + Portainer + Podman container-host operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency. Multi-platform by construction (a platform registry); a per-target 'platform' field (docker / portainer / podman) selects the API shape.
  All write operations are audited to a local SQLite DB under ~/.container-host-aiops/ (relocatable via CONTAINER_HOST_AIOPS_HOME).
  Connection: a Docker target speaks the Docker Engine API over a local unix socket (httpx uds transport, default /var/run/docker.sock — treat socket access as root-equivalent) or a TCP host; a Portainer target speaks the Portainer management API over HTTPS with an X-API-Key token, and also proxies the Docker API of a managed endpoint at /api/endpoints/{id}/docker/...; a Podman target speaks over the rootful/rootless service socket (autodetected: $XDG_RUNTIME_DIR/podman/podman.sock, then /run/podman/podman.sock), reusing the Docker-compat paths at the root plus libpod-native endpoints (pods) under the libpod prefix.
  Credentials: only Portainer needs a secret — its API token is stored ENCRYPTED in ~/.container-host-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. A local Docker or Podman socket needs no secret. Run 'container-host-aiops init' to onboard, or 'container-host-aiops secret set <target>' to add a Portainer token. The store is unlocked by a master password from CONTAINER_HOST_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CONTAINER_HOST_<TARGET_NAME_UPPER>_TOKEN is still honoured as a fallback with a deprecation warning (migrate with 'container-host-aiops secret migrate'). The token is sent in the X-API-Key header at request time and held only in memory; secrets are never logged or echoed.
  State-changing operations require double confirmation at the
...[truncated 25 chars]

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/capabilities.md (reported line 111)May include surrounding context.

md
| `stop_container` | med | `POST /containers/{id}/stop` | undo → `start_container` |
| `start_container` | med | `POST /containers/{id}/start` | undo → `stop_container` |
| `update_container` | med | `POST /containers/{id}/update` | captures prior CPU/memory limits; undo restores them |
| `remove_container` | **high** | `DELETE /containers/{id}` | `dry_run` + double-confirm; captures full inspect BEFORE; no undo |
| `prune_images` | **high** | `POST /images/prune` | `dry_run` LISTS candidates + reclaimable bytes first; no undo |
| `prune_volumes` | **high** | `POST /volumes/prune` | anonymous unused volumes only unless `all_unused`; `dry_run` LISTS the candidates for that same scope + reclaimable bytes; no undo |
| `recreate_stack` | **high** | `PUT /api/stacks/{id}/git/redeploy` | Portainer; captures prior stack; no undo |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/cli-reference.md (reported line 14)May include surrounding context.

container-host-aiops init # interactive wizard (Docker/Podman socket or Portainer) container-host-aiops doctor # verify config, secrets, connectivity # Docker/Podman: GET /version · Portainer: GET /api/endpoints container-host-aiops doctor --skip-auth # config/secret checks only (no connectivity)

text

## Secrets (Portainer only)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/cli-reference.md (reported line 23)May include surrounding context.

container-host-aiops secret set [--value ] # store a Portainer token (hidden prompt if no --value) container-host-aiops secret list # list target names with a stored token container-host-aiops secret rm # delete a stored token container-host-aiops secret migrate # import a legacy plaintext .env container-host-aiops secret rotate-password # re-encrypt under a new master password

text

Docker Socket Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The guide instructs use of /var/run/docker.sock with read/write access and correctly notes it is root-equivalent. In a skill whose purpose includes container writes, this is inherently dangerous because any agent or user granted socket access can effectively control the host, start privileged containers, mount the filesystem, or escape into full host compromise.

Content

Scanner excerpt · references/setup-guide.md (reported line 16)May include surrounding context.

md
## 2. What you need

- **Docker (unix socket)** — read/write access to the Docker socket (default
  `/var/run/docker.sock`). No secret is stored; the socket's file permissions are
  the trust boundary. Treat socket access as **root-equivalent** on the host.
- **Docker (TCP)** — a host + port (2375 plain, 2376 TLS). Enable TLS in
  production; a plain TCP daemon is unauthenticated.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/setup-guide.md (reported line 21)May include surrounding context.

md
- **Docker (TCP)** — a host + port (2375 plain, 2376 TLS). Enable TLS in
  production; a plain TCP daemon is unauthenticated.
- **Portainer** — the Portainer host + HTTPS port (default 9443), an **API token**
  (Portainer → My account → Access tokens), and the **endpoint id** of the managed
  Docker environment you want to read/manage (list them with `stack endpoints`).
- **Podman (unix socket)** — a running Podman **service** socket (rootful
  `/run/podman/podman.sock`, or rootless `$XDG_RUNTIME_DIR/podman/podman.sock` after

Docker Socket Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

This onboarding section normalizes connecting directly to the Docker unix socket for an admin automation skill. Because this skill also supports guarded writes, the context makes the socket especially sensitive: compromise or misuse of the skill translates into root-equivalent control of the host.

Content

Scanner excerpt · references/setup-guide.md (reported line 37)May include surrounding context.

md
The wizard asks, per target, for the **platform** (`docker` / `portainer` / `podman`):

- **docker** — connect over a **unix socket** (path, default `/var/run/docker.sock`)
  or a **TCP host** (host + optional TLS). No secret.
- **portainer** — host, HTTPS port, managed **endpoint id**, TLS verification, and
  the **API token** (stored encrypted). A master password (used to encrypt

Docker Socket Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Providing /var/run/docker.sock in a sample config encourages deployment with the most sensitive local control channel. In this skill context, that can expose full host administration to any process or agent able to use the configured target.

Content

Scanner excerpt · references/setup-guide.md (reported line 56)May include surrounding context.

md
targets:
  - name: local
    platform: docker
    socket_path: /var/run/docker.sock

  - name: remote-tcp
    platform: docker

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 10)May include surrounding context.

md
homepage: https://github.com/AIops-tools/Container-Host-AIops
tags: [aiops, mcp, governance, container-host]
description: >
  Use this skill whenever the user needs to operate a single container host through the Docker Engine API, Portainer, or Podman — a one-shot host overview; container reads (list/inspect, logs tail, CPU/memory stats, top processes, restart summary); image reads (list, inspect with history, dangling, disk usage); volume reads (list, inspect, dangling); network reads (list, inspect); system reads (info, version, df disk-usage, recent events); Portainer stacks + endpoints; Compose-project rollups (list_compose_stacks, docker+podman); Podman pods (list_pods, podman-only); three flagship analyses — restart-loop RCA (crash-looping containers + cause/action), resource-pressure analysis (CPU/memory vs limits), and image & volume bloat (prune candidates + reclaimable bytes); and eight guarded writes (restart/stop/start/remove a container, prune images/volumes, update resource limits, recreate a Portainer stack).
  Always use this skill for "Docker host overview", "which containers are crash-looping", "restart loop", "why does this container keep restarting", "container CPU/memory usage", "docker logs", "which containers are near their limits", "resource pressure", "dangling images/volumes", "reclaim disk", "prune images", "stop/start/restart a container", "update a container's memory limit", "Portainer stacks", "compose stacks", "Podman pods" when the context is a Docker, Portainer, or Podman container host.
  Do NOT use when the target is a cluster orchestrator, a hypervisor, a storage appliance, a backup product, network device config, or OT/industrial equipment — route those to the appropriate other AIops-tools skill. This is for NON-orchestrator container hosts.
  Governed Docker/Portainer/Podman container-host operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Exercised against a live Docker Engine 27.5.1 
...[truncated 25 chars]

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 111)May include surrounding context.

md
4. If the cause is memory: `container-host-aiops analyze resource-pressure --mem 75` →
   see how close the container runs to its ceiling, then
   `container-host-aiops manage update <id> '{"Memory": 1073741824}' --dry-run` and
   re-run without `--dry-run` (double-confirm; the write captures the prior limits as its
   undo descriptor).
5. `container-host-aiops manage restart <id>` → bring it up on the new limit, then
   re-run `analyze restart-loop` to confirm the loop stopped.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
95% confidence
Finding

This documentation explicitly states that the tool does not enforce approval or read-only mode and that write control must be provided externally by account permissions or the agent prompt. In a skill that includes destructive container-host operations such as stop/remove/prune/update/recreate, relying on prompting alone for authorization creates a real risk of unintended or unauthorized writes if the connected account has sufficient privileges.

Content

Scanner excerpt · references/agent-guardrails.md (reported line 15)May include surrounding context.

md
## Authorization is not this tool's job — decide it where it belongs

Whether a write should happen is your decision, or the account's. The tool does
not gate it — there is no read-only switch and no approval prompt to configure.
The two right places to control read vs write:

- **The account you connect with.** Give it a Docker socket mounted read-only,

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 · references/agent-guardrails.md (reported line 91)May include surrounding context.

bash
# e.g. mount the Docker socket read-only for the container running this tool,
# or use a Portainer account without write scope. Then:
container-host-aiops doctor

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · references/cli-reference.md (reported line 14)May include surrounding context.

container-host-aiops init # interactive wizard (Docker/Podman socket or Portainer) container-host-aiops doctor # verify config, secrets, connectivity # Docker/Podman: GET /version · Portainer: GET /api/endpoints container-host-aiops doctor --skip-auth # config/secret checks only (no connectivity)

text

## Secrets (Portainer only)

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 · references/setup-guide.md (reported line 15)May include surrounding context.

md
## 2. What you need

- **Docker (unix socket)** — read/write access to the Docker socket (default
  `/var/run/docker.sock`). No secret is stored; the socket's file permissions are
  the trust boundary. Treat socket access as **root-equivalent** on the host.
- **Docker (TCP)** — a host + port (2375 plain, 2376 TLS). Enable TLS in

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% 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 · references/setup-guide.md (reported line 25)May include surrounding context.

md
Docker environment you want to read/manage (list them with `stack endpoints`).
- **Podman (unix socket)** — a running Podman **service** socket (rootful
  `/run/podman/podman.sock`, or rootless `$XDG_RUNTIME_DIR/podman/podman.sock` after
  `systemctl --user enable --now podman.socket`). No secret; the socket's file
  permissions are the trust boundary. Autodetection prefers the rootless socket,
  then the rootful one.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/setup-guide.md (reported line 89)May include surrounding context.

md
- Only **Portainer** needs a secret; **Docker and Podman** sockets need none (file
  permissions are the boundary). The Portainer API token is **never** written to disk
  in plaintext — it lives encrypted in `~/.container-host-aiops/secrets.enc` (Fernet /
  AES-128 + a scrypt-derived key; chmod 600). The master password is never stored.
- The master password is resolved from `CONTAINER_HOST_AIOPS_MASTER_PASSWORD`
  (non-interactive / MCP / CI) or an interactive prompt (CLI on a TTY).
- A legacy plaintext env var `CONTAINER_HOST_<TARGET_NAME_UPPER>_TOKEN` is honoured

Static analysis

No suspicious patterns detected.