Back to skill

Security audit

Agented

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent editing tool, but it deserves review because it pushes agents to trust an external editor, persistent shared annotations, and a risky install path.

Install only if you want an agent-focused editor that persists workspace state and coordinates across sessions. Prefer the Homebrew path over the `curl | sh` installer, review any commands that write to agent config or skill directories, and treat annotations as untrusted context rather than instructions that override the current user request or normal verification.

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
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
README.md:50
Finding

Unpinned Remote Installation Script Is Executed Directly by the Shell

Content
View full analysis
Remediation
View remediation
' install.sh | sha256sum -c - less install.sh sh install.sh ``` 5. Pin source-based installation examples to a specific release rather than `@latest` or a mutable branch. 6. Document the files, directories, network destinations, and configuration entries affected by installation. 7. Prefer a package manager that verifies signed, versioned artifacts and provides an auditable uninstall process. ]]>

T02 · Agent Memory Poisoning

Warning
Location
SKILL.md:160
Finding

Persistent Annotations Are Treated as Mandatory Trusted Instructions

Content
View full analysis
Remediation
View remediation

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:49
Finding

Skill Instructions Force Use of an External Editor and Discourage Independent Tool Verification

Content
View full analysis
`. Not `Read`, not `Edit`, not `cat`. The response is the input to the rest of the session. `ae open` returns six things: the file's id, line count, head_edit_id, content_hash, state_token, and any active annotations inline. Treat that response as authoritative. Annotations were left by a prior session for you to read. Read them. The state_token threads forward into your next write. The line_count tells you whether your assumptions about the file's shape match. ... Skipping this step costs you. If you `Read` first, the agent runtime has the bytes, but the editor doesn't know you've seen the file. Subsequent writes through `ae` will treat your context as a fresh actor and may surface conflicts that wouldn't have happened otherwise. ``` Related instructions at `SKILL.md:420-429` further characterize using native `Read`, `Edit`, and `Write` tools as an anti-pattern. ### Technical Analysis The declared functionality is a stateful text editor with history and concurrency support. That functionality requires access to files selected by the user, but it does not inherently require forbidding trusted native inspection tools or declaring the external editor's output authoritative. The Skill uses absolute instructions to redirect initial file access through the `ae` executable and discourage independent verification through `Read`, `cat`, or other built-in tools. Because the executable implementation is not included in the audited package, the behavior and integrity of the binary cannot be verified from these files. This creates an avoidable trust concentration: file contents, persistent annotations, conflict information, and writes are all mediated by one opaque external ...[truncated 1582 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (17)

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · CHANGELOG.md (reported line 65)May include surrounding context.

md
### Features

- **`ae permissions disable-internals` now writes a Codex deny rule too**, completing the Claude / Gemini / Codex matrix. Codex's only edit primitive at the public surface is `apply_patch`, so the implementation maps the canonical Read/Edit/Write/NotebookEdit input down to one TOML line — `apply_patch = false` under a `[tools]` table in `~/.codex/config.toml` — written idempotently with our own minimal section editor (no external TOML lib).

  Honesty caveat: Codex accepts `tools.apply_patch = false` via `-c` parsing without error, but the published config docs don't explicitly state that this disables the tool at runtime. Treated as **experimental** — the docs flag it, the rule gets written, and users can verify the behavior in their own Codex session.

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · CHANGELOG.md (reported line 72)May include surrounding context.

md
### Features

- **`ae permissions disable-internals` now writes a Codex deny rule too**, completing the Claude / Gemini / Codex matrix. Codex's only edit primitive at the public surface is `apply_patch`, so the implementation maps the canonical Read/Edit/Write/NotebookEdit input down to one TOML line — `apply_patch = false` under a `[tools]` table in `~/.codex/config.toml` — written idempotently with our own minimal section editor (no external TOML lib).

  Honesty caveat: Codex accepts `tools.apply_patch = false` via `-c` parsing without error, but the published config docs don't explicitly state that this disables the tool at runtime. Treated as **experimental** — the docs flag it, the rule gets written, and users can verify the behavior in their own Codex session.

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · CHANGELOG.md (reported line 71)May include surrounding context.

md
| Target | Mechanism | File |
  |---|---|---|
  | claude | `permissions.deny` array | `~/.claude/settings.json` (global) or `.claude/settings.local.json` (project) |
  | codex | `tools.apply_patch = false` (experimental) | `~/.codex/config.toml` (global) |
  | gemini | Policy Engine TOML rules | `~/.gemini/policies/agented-deny.toml` (global) |
  | openclaw | n/a — managed at agent level | — |

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · CHANGELOG.md (reported line 91)May include surrounding context.

md
| Target | Mechanism | File |
  |---|---|---|
  | claude | `permissions.deny` array | `~/.claude/settings.json` (global) or `.claude/settings.local.json` (project) |
  | codex | `tools.apply_patch = false` (experimental) | `~/.codex/config.toml` (global) |
  | gemini | Policy Engine TOML rules | `~/.gemini/policies/agented-deny.toml` (global) |
  | openclaw | n/a — managed at agent level | — |

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · CHANGELOG.md (reported line 105)May include surrounding context.

md
| Target | Mechanism | File |
  |---|---|---|
  | claude | `permissions.deny` array | `~/.claude/settings.json` (global) or `.claude/settings.local.json` (project) |
  | codex | `tools.apply_patch = false` (experimental) | `~/.codex/config.toml` (global) |
  | gemini | Policy Engine TOML rules | `~/.gemini/policies/agented-deny.toml` (global) |
  | openclaw | n/a — managed at agent level | — |

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

Scanner excerpt · CHANGELOG.md (reported line 151)May include surrounding context.

/plugin install agented@frane-agented

text

The plugin layout under `plugin/` ships the embedded `SKILL.md` plus `.mcp.json` (registers `ae serve`). The `ae` binary still has to be on PATH (Homebrew or curl); plugins don't ship cross-platform binaries.

- **Codex CLI plugin manifest**. Same plugin directory carries `plugin/.codex-plugin/plugin.json` for OpenAI Codex CLI. Codex's marketplace mechanism is still per-user (`~/.agents/plugins/marketplace.json`); users add the plugin manually via that file until the official Codex directory opens up.

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · CHANGELOG.md (reported line 186)May include surrounding context.

md
- **Per-workspace LSP daemons**. The LSP daemon model follows the same shape: each workspace gets its own daemon, lazily spawned on the first write that targets it. `lsp.SpawnBackground` and `lsp.EnsureDaemon` are now in the `lsp` package (used by both CLI and MCP), and spawn explicitly with `--workspace-dir <wsDir>` so the daemon attaches to the right project regardless of the parent process's cwd. New `Engine.NotifyLSPIfWrite` hook is invoked from MCP after every successful tool call.
- **Per-LSP `init_options` pass-through**. `IDEServerCfg.InitOptions` (a free-form `map[string]any`) is forwarded verbatim as the LSP `initialize` request's `initializationOptions` field. ae does no validation; the schema is whatever the server accepts. Closes the recurring "rust-analyzer / clippy / linkedProjects" round-trip — users can drop `init_options: { check: { command: "clippy" } }` directly into ae's config instead of wrangling a separate `rust-analyzer.toml`.
- **Unified `internal/agents` registry**. The skill-target list (`internal/skill/targets.go`) and MCP-install-target list (`internal/mcpinstall`) used to duplicate per-agent definitions for Claude, Codex, Cursor, Gemini, OpenClaw. They now both build their slices from a single source of truth in `internal/agents/agents.go` — adding a new client is a one-place change.
- **Gemini CLI integration**. New target across both surfaces: `ae skill install --target gemini` writes to `~/.gemini/extensions/agented/GEMINI.md` plus a sibling `gemini-extension.json` so Gemini recognises the directory; `ae mcp install --target gemini` writes the agented entry to `~/.gemini/settings.json`.

### Fixes

Chaining Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

The | sh construct is a direct command-chaining pattern that feeds network-retrieved content into a shell, enabling immediate arbitrary command execution. Within a skill meant for LLM-driven tooling, this is especially risky because an agent may execute it as written, and any compromise of the upstream content, repository, or transport assumptions would yield full code execution under the user's privileges.

Content

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

curl (any platform):

sh
curl -sSL https://raw.githubusercontent.com/frane/agented/master/install.sh | sh

From source: go install github.com/frane/agented/cmd/ae@latest, or clone and make install. Pure Go, no cgo, single static binary, Apache 2.0.

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 · CHANGELOG.md (reported line 12)May include surrounding context.

md
### Fixes

- **`ae open` no longer serves a stale head after the file changed outside ae** (data-loss bug). Opening an already-registered file now hash-checks disk against the workspace head and, on divergence, folds the disk state in as a new `load` edit with a warning — the same recoverable-on-the-tree semantics as the write verbs' auto-load, gated by the same `concurrency.auto_load_on_drift` knob. Previously `open` silently returned the old head, `replace --pattern` then matched nothing against it, and `save` clobbered the newer disk file.
- **`ae save` refuses to overwrite disk content this workspace never loaded.** If the on-disk content's hash appears nowhere in the file's edit history, the file was changed outside ae and a blind save would destroy that work: save now errors with recovery instructions (`ae load` first, then re-apply or merge). Override with `--force` (CLI) / `force: true` (MCP `ae_save`).
- **`ae replace --pattern` with 0 matches is now an error** (nonzero exit), so `replace && save` shell chains stop instead of shipping a no-op. Pass `--allow-no-match` to keep exit 0; `--dry-run` is unaffected. Pattern mode also now reconciles disk drift before matching and auto-saves after the edit — parity with the range verbs, both previously missing.
- Integration-test harness isolates `$HOME` so a developer's global `~/.agented/config.json` (e.g. `ide.enabled=true`) can't stall every spawned `ae` on LSP autostart and trip timing-sensitive scenarios.

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 · CHANGELOG.md (reported line 108)May include surrounding context.

Today writes only Claude Code's permissions.deny array in ~/.claude/settings.json (global) or .claude/settings.local.json (project). Gemini and Codex are skipped with a clear "deny-list schema not yet known" reason — their config schemas don't have a documented public deny-list field; we'll fill it in once they do.

sh
ae permissions disable-internals             # write deny rules to project scope
ae permissions disable-internals -s global   # to global scope
ae permissions disable-internals --dry-run   # preview
ae permissions enable-internals              # remove the deny rules

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · CHANGELOG.md (reported line 157)May include surrounding context.

md
- **Gemini CLI extension manifest**. Same directory carries `plugin/gemini-extension.json` plus `plugin/GEMINI.md` (Gemini insists on the `.md` being named `GEMINI.md` rather than `SKILL.md`). Distributable via `gemini extensions install <github-url>`.

- **`make stage-plugin` + drift guard**. `internal/skill/SKILL.md` stays the canonical copy; `make stage-plugin` mirrors it into the three plugin paths (`plugin/skills/agented/SKILL.md`, `plugin/GEMINI.md`) and rewrites the three manifests with the current git tag. `internal/skill/plugin_sync_test.go` runs in `go test ./...` and fails CI if any of the three skill copies drifts from the canonical, so a release can't ship a stale plugin.

## [v0.4.2] - 2026-05-07

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 · CHANGELOG.md (reported line 404)May include surrounding context.

md
- **Auto-save** by default on write verbs. `ae replace`/`insert`/`delete`/`move`/`extract` and the history verbs (`undo`/`redo`/`head`) atomically flush the new head to disk as part of the same call. Result includes `saved: true` to confirm. Config: `concurrency.auto_save = clean | off | force` (default `clean`). The five-call dance (`open + status + view + replace + save`) collapses to two for the common flow.
- **Auto-load on disk drift** by default. Before each write, ae stat-s the file. If `(mtime, size)` match the stamp recorded after the last save, no work; otherwise read + hash. On detected drift, the disk content is loaded as a new edit on the tree before the user's edit applies, so external changes are captured (recoverable via `ae undo` / `ae head`) instead of silently overwritten. Config: `concurrency.auto_load_on_drift` (default `true`). Env override: `AE_AUTO_LOAD_ON_DRIFT=false`.
- **`ae show <path>`** renders a Claude Code-style colored, syntax-highlighted diff (chroma-backed) for the most recent edit. Opt-in display command — write verbs return the lean tab format by default so agents pay no extra tokens.
- **Agent-centric `ae setup` wizard.** Detects which agents are present (claude / codex / cursor / openclaw), shows what's available, and asks per-agent which to install. `--yes` runs non-interactively for every detected agent. `--legacy` keeps the previous per-component flow.
- **Install gating symmetry.** `ae rules install` now skips undetected targets under `--target=all` (matching skill / permissions / mcp). Explicit `--target=<name>` still writes regardless. Cursor without a `.cursor/` dir and OpenClaw skip with explanatory reasons.
- **`ae rules show` rewritten.** Section body printed once at the top, followed by an aligned per-target status table. Previously duplicated the body across every target.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest description does not mention that the tool stores persistent annotations and cross-agent shared state in a SQLite-backed workspace. While persistence can support editing, durable memory and multi-agent coordination are broader behaviors than a plain text editor description suggests.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The manifest says the skill is 'A text editor for LLMs, not humans,' which implies file editing as its core scope. The documented verbs symbols and diag, plus later find/reference/definition features, expand the skill into code intelligence and workspace analysis rather than just text editing.

Content

No source excerpt is available for this finding.

External Script Fetching

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The README recommends installing via curl ... | sh, which executes remote code directly from the network without an opportunity for users or agents to inspect, pin, or verify it first. In an agent skill context, this is more dangerous because an autonomous agent may follow the instruction non-interactively, turning documentation into a path for arbitrary code execution if the source is compromised or tampered with.

Content

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

brew install agented

text

curl (any platform):

```sh
curl -sSL https://raw.githubusercontent.com/frane/agented/master/install.sh | sh

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This markdown file states that ae skill install writes a SKILL.md into every detected agent's skills directory, which changes local agent configuration/state. While installation is the feature being described, the README does not explicitly warn users that the command performs filesystem writes across multiple detected locations.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

Earlier text states 'The default is concurrency.require_expect: warn', but the configuration section later states the default is writes. These statements cannot both be true, so the documentation actively contradicts itself about an important concurrency/safety behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.