Back to skill

Security audit

abra

Security checks for vulnerabilities and agentic risk

Overview

This skill is for a local secrets vault and is mostly well-scoped, but one documented fallback can write fetched secrets to disk with incomplete path-hardening, so it should be reviewed before installation.

Install only if you intend agents to use abracadabra for scoped secret access. Prefer MCP or in-memory environment injection, keep API keys narrowly scoped and expiring, avoid the private-file fallback unless the implementation hardens parent-directory symlink checks and cleanup, and require explicit confirmation for treasury payments, sync, restore, or license purchase flows.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:167
Finding

Parent-directory symlink allows secrets to be written outside the intended storage directory

Content
View full analysis
{ const res = await fetch("http://127.0.0.1:7331/secret", { method: "POST", headers: { authorization: `Bearer ${key}`, "content-type": "application/json" }, body: JSON.stringify({ project, keys: allow }), }); if (!res.ok) { console.error(`abra /secret failed: HTTP ${res.status}`); process.exit(1); } const j = await res.json(); if (j.error) { console.error("abra error (see abra serve log)"); process.exit(1); } const out = {}; for (const k of allow) if (typeof j[k] === "string") out[k] = j[k]; // opaque fs.mkdirSync(dir, { recursive: true, mode: 0o700 }); if (fs.lstatSync(dir).uid !== os.userInfo().uid) { console.error("agent-env dir not owned by user"); process.exit(1); } try { if (fs.lstatSync(file).isSymbolicLink()) { console.error("refusing symlink"); process.exit(1); } } catch {} const fd = fs.openSync(file, "wx", 0o600); // exclusive: fails if it already exists ``` ### Technical Analysis The example intends to constrain secret files to `~/.abracadabra/agent-env`, but the containment check uses `path.resolve()`, which performs lexical path normalization and does not resolve filesystem symlinks. The code verifies that `dir` is owned by the current user but does not verify that it is a real directory rather than a symbolic link: ```js fs.lstatSync(dir).uid !== os.userInfo().uid ``` For a user-owned symbolic link, `lstatSync(dir).uid` ordinarily reports the owner of the link itself. Consequently, a link such as: ```text ~/.abracadabra/agent-env -> /another/user-owned ...[truncated 2287 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
Findings (13)

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

md
secrets the human has scoped to this agent (issued abra key or Touch ID grant),
  key issue/scope/revoke, health checks, keygen/connectors, USB/LAN sync, cartridge
  checkpoints, and treasury USDC payments (Touch ID). Do not use for generic env var,
  API token, wallet, or SSH key questions, or for other vaults or .env files. Never
  print secret values in chat.
---

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
65% 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 · SKILL.md (reported line 100)May include surrounding context.

md
Rules for this path:

- **Keep `ABRA_KEY` out of process arguments.** Never put it in a `curl -H` argument,
  a URL, or a command string — other local processes can read argv. Read it from the
  environment inside the HTTP client process.
- **Prefer no file at all.** Inject secrets straight into the target process's

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
65% 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 · SKILL.md (reported line 422)May include surrounding context.

abra serve --open # + web dash abra serve --lan # HTTPS 0.0.0.0; writes ~/.abracadabra/lan-serve.pem abra serve --lan --tls-cert c.pem --tls-key k.pem

Clients: curl --cacert ~/.abracadabra/lan-serve.pem … — NEVER curl -k

text

`GET /health` · `GET /grants` · `DELETE /grants` · `POST /secret`

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
65% 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 · SKILL.md (reported line 422)May include surrounding context.

abra serve --open # + web dash abra serve --lan # HTTPS 0.0.0.0; writes ~/.abracadabra/lan-serve.pem abra serve --lan --tls-cert c.pem --tls-key k.pem

Clients: curl --cacert ~/.abracadabra/lan-serve.pem ... — NEVER curl -k

text

`GET /health` · `GET /grants` · `DELETE /grants` · `POST /secret`

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

Clients: curl --cacert ~/.abracadabra/lan-serve.pem … — NEVER curl -k

text

`GET /health` · `GET /grants` · `DELETE /grants` · `POST /secret`

## Anti-patterns (do not)

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% 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 · SKILL.md (reported line 44)May include surrounding context.

md
**Default for unattended work:** scoped API key + `POST /secret` (no Touch ID).
**Default when human is at the keyboard:** MCP `get_secrets` with `ttl`.

Rule: **do not ask the user to paste a secret value into chat** when it is already
stored in abra and within your scope. Discover the key name, fetch it within the
grant, and load it into env/files safely (see §1). Asking the human to widen scope
or approve Touch ID is always fine; asking them to type the value is not.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
Rules for this path:

- **Keep `ABRA_KEY` out of process arguments.** Never put it in a `curl -H` argument,
  a URL, or a command string — other local processes can read argv. Read it from the
  environment inside the HTTP client process.
- **Prefer no file at all.** Inject secrets straight into the target process's

Session Persistence

Medium
Category
Rogue Agent
Confidence
68% confidence
Finding

The skill permits writing fetched secrets to a persistent file under ~/.abracadabra/agent-env/ when a runtime cannot take environment variables. Even with 0600 permissions and exclusive create, persistence increases the window for local compromise, accidental backup/sync inclusion, or later misuse if cleanup fails or the process crashes before deletion.

Content

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

md
environment inside the HTTP client process.
- **Prefer no file at all.** Inject secrets straight into the target process's
  environment and let them die with it.
- **If a file is unavoidable**, write it under `~/.abracadabra/agent-env/` — never in
  the repository or current working directory — with exclusive create (`wx`),
  mode `0600`, a symlink check, and a chmod after open. Remove it when done.
- **Error output** must never include the response body, headers, or env.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
const [cmd, ...args] = rest;
if (!cmd) { console.error("usage: node - -- <command> [args]"); process.exit(2); }
(async () => {
  const res = await fetch("http://127.0.0.1:7331/secret", {
    method: "POST",
    headers: { authorization: `Bearer ${key}`, "content-type": "application/json" },
    body: JSON.stringify({ project: process.env.ABRA_PROJECT, keys: allow }),

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
const [cmd, ...args] = rest;
if (!cmd) { console.error("usage: node - -- <command> [args]"); process.exit(2); }
(async () => {
  const res = await fetch("http://127.0.0.1:7331/secret", {
    method: "POST",
    headers: { authorization: `Bearer ${key}`, "content-type": "application/json" },
    body: JSON.stringify({ project: process.env.ABRA_PROJECT, keys: allow }),

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

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

md
const [cmd, ...args] = rest;
if (!cmd) { console.error("usage: node - -- <command> [args]"); process.exit(2); }
(async () => {
  const res = await fetch("http://127.0.0.1:7331/secret", {
    method: "POST",
    headers: { authorization: `Bearer ${key}`, "content-type": "application/json" },
    body: JSON.stringify({ project: process.env.ABRA_PROJECT, keys: allow }),

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

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

md
const [cmd, ...args] = rest;
if (!cmd) { console.error("usage: node - -- <command> [args]"); process.exit(2); }
(async () => {
  const res = await fetch("http://127.0.0.1:7331/secret", {
    method: "POST",
    headers: { authorization: `Bearer ${key}`, "content-type": "application/json" },
    body: JSON.stringify({ project: process.env.ABRA_PROJECT, keys: allow }),

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

md
**LAN (`abra serve --lan`):** point the fetch/curl at `https://$LAN_IP:7331/secret`
and trust only `~/.abracadabra/lan-serve.pem` (Node: `NODE_EXTRA_CA_CERTS`; curl:
`--cacert`). **Never `curl -k` / `--insecure`** or `NODE_TLS_REJECT_UNAUTHORIZED=0`
— that enables MITM theft of `ABRA_KEY` and secret payloads. Prefer loopback when
the agent is on the same machine.