Back to skill

Security audit

Pi EvoX Loop

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly transparent about its experience-sharing purpose, but it can persistently alter future agent prompts from a global store with weak relevance controls.

Install only if you are comfortable with a persistent agent-memory workflow. Prefer project-local .pi/extensions/ over the global Pi extension, keep manual review enabled, avoid --auto-approve with --llm-refine except in isolated experiments, use a restricted API key, and treat generated transcript and experiment directories as sensitive.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • 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 (2)

T02 · Agent Memory Poisoning

Error
Location
code/evolver-bridge.ts:55
Finding
Persistent Prompt Injection Through Weakly Validated Evolver Strategies<![CDATA[ ## Vulnerability Details **File Location**: `code/evolver-bridge.ts:55-116` **Vulnerability Type**: Persistent agent memory poisoning and system-prompt injection **Risk Level**: High ### Vulnerable Code ```ts const REPAIR_SIGNAL_RE = /error|exception|traceback|failed|invalid|cannot|unable|missing|not found|wrong|instead|avoid|fix|encoding\s*[=:]|errors\s*=|utf-?8|gbk|gb18030|latin-1|\brb\b|except|skip/i; function isRepairLike(text: string): boolean { return REPAIR_SIGNAL_RE.test(text); } function loadApprovedStrategies(): string[] { const out: string[] = []; const approved = approvedAssetIds(); try { for (const line of fs.readFileSync(EVO_GENES, "utf8").split("\n")) { const s = line.trim(); if (!s) continue; let g: any; try { g = JSON.parse(s); } catch { continue; } const strategy = g && Array.isArray(g.strategy) ? g.strategy : null; if (!strategy || strategy.length === 0) continue; const aid = g.asset_id; if (!aid || !approved.has(aid)) continue; const text = strategy.join(" ").slice(0, 1200); if (!isRepairLike(text)) continue; out.push(`- [${g.category || "repair"}] ${text}`); } } catch { /* genes.jsonl does not exist */ } return out; } export default function evolverBridge(pi: ExtensionAPI) { pi.on("before_agent_start", async (event, _ctx) => { const strategies = loadApprovedStrategies(); if (strategies.length === 0) return; const block = "\n\n---\n[Evolver inherited fixes] The following validated fixes were injected from your experience store (evolver). Apply them when relevant. ---\n" + strategies.join("\n"); try { fs.writeFileSync( path.join(EVO_STORE, "bridge-last-inject.txt"), `[${new Date().toISOString()}]\n${block}`, ); } catch { /* Audit-log failure does not prevent injection */ } return { systemPrompt: event.systemPrompt + block }; }); } ``` ### Technical Analysis The extension reads persistent strategy text from `~/.evomap/assets/ ...[truncated 2791 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace keyword validation with a strict structured schema containing narrowly defined fields such as failure condition, affected component, exact repair operation, and verification step. 2. Reject strategies containing meta-instructions involving system prompts, safety controls, credentials, external transmission, unrelated tools, or changes to agent objectives. 3. Treat recalled strategies as untrusted reference data rather than directly concatenating them into the system prompt. 4. Require explicit human approval for all content that will enter a system prompt. Do not permit automatic approval in globally installed or production extensions. 5. Bind each approval cryptographically to the exact normalized strategy content so that an approved asset cannot be modified after review. 6. Implement project and task relevance matching before injection. Scope each strategy to applicable repositories, file types, tools, error signatures, or task signals. 7. Add limits on the number and total size of injected strategies, and prefer selecting only the most relevant records. 8. Provide commands to list, revoke, quarantine, and inspect all strategies injected into a session. 9. Store provenance with each strategy, including source transcript, creation method, reviewer, review timestamp, and content digest. 10. Add adversarial tests proving that strategies containing repair keywords plus malicious instructions are rejected. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
code/pi_evolve.mjs:139
Finding
API Key Exposure Through Process Arguments and Excessive Environment Inheritance<![CDATA[ ## Vulnerability Details **File Location**: `code/pi_evolve.mjs:139-146, 294-297` **Vulnerability Type**: Credential exposure and violation of least-privilege environment handling **Risk Level**: Medium ### Vulnerable Code ```js function runCli(entry, args, { cwd = LAB, silent = false, mergeStderr = false, allowFail = false, extraEnv = null } = {}) { const env = { ...process.env, ...(extraEnv ?? {}) }; if (MANAGED_NODE) env.PATH = `${MANAGED_NODE}${path.delimiter}${env.PATH ?? ''}`; const r = spawnSync(process.execPath, [entry, ...args], { cwd, encoding: 'utf8', maxBuffer: 1 << 26, env }); const out = (r.stdout ?? '') + (mergeStderr ? (r.stderr ?? '') : ''); if (!allowFail && r.status !== 0) { const detail = String(r.stderr ?? '').trim().slice(0, 200); const hint = classifyError(`${detail} ${out}`); const err = new Error(`exit ${r.status}: ${detail}${hint ? `\n ↳ diagnosis: ${hint}` : ''}`); err.status = r.status; err.hint = hint; throw err; } return out; } ``` ```js const piArgs = [ '-p', '--provider', opts.provider, '--model', opts.model, '--api-key', apiKey, '--session-dir', sessDir, ...injectArgs, taskText ]; piOut = runCli(PI_ENTRY, piArgs, { mergeStderr: true, extraEnv: { AGNES_CN_API_KEY: apiKey } }); ``` ### Technical Analysis The orchestrator places the LLM API key directly in the Pi child process argument list through `--api-key`. Command-line arguments may be observable by other local processes under applicable operating-system permissions, process-monitoring agents, debugging tools, audit systems, or crash-reporting software. The key is simultaneously passed through `AGNES_CN_API_KEY`, creating two exposure channels without a demonstrated need for both. In addition, `runCli()` copies the complete parent environment into every child process. This applies not only to the Pi provider process, but also to the adapter, token summarizer, and Evolver CLI invocation ...[truncated 1851 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not place API keys in command-line arguments. Pass the provider key only through a dedicated environment variable or another protected secret-delivery mechanism supported by Pi. 2. Avoid supplying the same key through both arguments and the environment. 3. Replace `{ ...process.env }` with a per-command allowlist. Include only variables required for execution, such as a controlled `PATH`, locale variables, and the specific provider credential for the Pi process. 4. Do not pass provider credentials to the adapter, token summarizer, or Evolver CLI unless a documented operation explicitly requires them. 5. Remove unrelated proxy and cloud credential variables from subprocess environments by default. 6. Ensure error messages, debug logs, and diagnostic reports cannot serialize child arguments or secret-bearing environments. 7. Document the expected credential scope and recommend restricted, short-lived, quota-limited API keys for experiments. 8. Add automated tests that inspect spawned argument arrays and environments and fail if secrets appear in arguments or unrelated commands receive credential variables. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (165)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The mismatch between declared experience-inheritance functionality and broader transcript-processing/export behavior can mislead users about the sensitivity of data handled by the skill. When a skill can read local session logs and write transformed copies, the main risk is unanticipated handling and persistence of potentially sensitive prompts, code, and tool output.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The mismatch between declared experience-inheritance functionality and broader transcript-processing/export behavior can mislead users about the sensitivity of data handled by the skill. When a skill can read local session logs and write transformed copies, the main risk is unanticipated handling and persistence of potentially sensitive prompts, code, and tool output.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The mismatch between declared experience-inheritance functionality and broader transcript-processing/export behavior can mislead users about the sensitivity of data handled by the skill. When a skill can read local session logs and write transformed copies, the main risk is unanticipated handling and persistence of potentially sensitive prompts, code, and tool output.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The mismatch between declared experience-inheritance functionality and broader transcript-processing/export behavior can mislead users about the sensitivity of data handled by the skill. When a skill can read local session logs and write transformed copies, the main risk is unanticipated handling and persistence of potentially sensitive prompts, code, and tool output.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The mismatch between declared experience-inheritance functionality and broader transcript-processing/export behavior can mislead users about the sensitivity of data handled by the skill. When a skill can read local session logs and write transformed copies, the main risk is unanticipated handling and persistence of potentially sensitive prompts, code, and tool output.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The mismatch between declared experience-inheritance functionality and broader transcript-processing/export behavior can mislead users about the sensitivity of data handled by the skill. When a skill can read local session logs and write transformed copies, the main risk is unanticipated handling and persistence of potentially sensitive prompts, code, and tool output.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The mismatch between declared experience-inheritance functionality and broader transcript-processing/export behavior can mislead users about the sensitivity of data handled by the skill. When a skill can read local session logs and write transformed copies, the main risk is unanticipated handling and persistence of potentially sensitive prompts, code, and tool output.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The mismatch between declared experience-inheritance functionality and broader transcript-processing/export behavior can mislead users about the sensitivity of data handled by the skill. When a skill can read local session logs and write transformed copies, the main risk is unanticipated handling and persistence of potentially sensitive prompts, code, and tool output.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The mismatch between declared experience-inheritance functionality and broader transcript-processing/export behavior can mislead users about the sensitivity of data handled by the skill. When a skill can read local session logs and write transformed copies, the main risk is unanticipated handling and persistence of potentially sensitive prompts, code, and tool output.

Ae1

High
Category
analysis-evasion
Content
以下命令均在本仓库根目录执行(`SKILL.md` 所在目录)。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node code/pi_evolve.mjs <模板目录> <任务文本> \
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node code/pi_evolve.mjs <模板目录> <任务文本> \
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

External Model or Provider Selection

High
Category
Excessive Agency
Content
- **内置 provider 示例**(deepseek 已内置,无需 models.json):
  ```bash
  node code/pi_evolve.mjs <模板目录> <任务文本> \
      --provider deepseek --model deepseek-v4-flash \
      --api-key "$DEEPSEEK_API_KEY" --rounds 2 --fresh --auto-approve
  ```
- **npm 国内镜像**(安装慢时):`npm config set registry https://registry.npmmirror.com`
Confidence
90% confidence
Finding
The skill facilitates external provider/model selection and API-key usage for an OpenAI-compatible endpoint. In context, this is security-relevant because the same skill also discusses transcript export and remote refinement, so provider selection directly controls where sensitive code/task data may be transmitted.

Ae1

High
Category
analysis-evasion
Content
node code/evolver-recall.mjs
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node code/evolver-recall.mjs
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- Pi 扩展桥(`code/evolver-bridge.ts`,放 `~/.pi/agent/extensions/` 或项目 `.pi/extensions/`)激活后,编排器自动切换为扩展注入(单通道),并附带 tool_result 失败点教学。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

External Model or Provider Selection

High
Category
Excessive Agency
Content
```bash
node code/pi_evolve.mjs <模板目录> <任务文本> \
    --provider deepseek --model deepseek-v4-flash \
    --api-key "$DEEPSEEK_API_KEY" --rounds 2 --fresh --auto-approve
```
Confidence
90% confidence
Finding
Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The manifest describes a skill for recalling, registering, and depositing validated fixes in an Evolver-style experience store, with optional closed-loop inheritance experiments. This file instead instructs editing `config/settings.json` and reading it back, which is unrelated to experience inheritance or self-evolution behavior.

Known Vulnerable Dependency: @earendil-works/pi-coding-agent==0.74.2 — 4 advisory(ies): CVE-2026-54326 (Pi Agent: Potential XSS in HTML session exports via Markdown URL sanitization by); CVE-2026-54328 (Pi Agent: Predictable temporary extension install paths allow local privilege es); CVE-2026-54325 (Pi Agent: Pi loads project-local extensions without approval) +1 more

High
Category
Supply Chain
Confidence
95% confidence
Finding
The lockfile pins @earendil-works/pi-coding-agent to 0.74.2, and the static analysis indicates multiple known advisories affecting that exact version, including unsafe local extension loading and client-side export issues. In the context of an agent skill that runs coding workflows and can interact with local projects, a vulnerable agent dependency materially increases the chance of code execution, privilege escalation, or malicious content rendering.

Credential Access

High
Category
Privilege Escalation
Content
"node": "^22.13.0 || >=23.4.0"
      },
      "optionalDependencies": {
        "@napi-rs/keyring": "^1.1.6"
      }
    },
    "node_modules/@evomap/evolver-adapter-public/node_modules/@evomap/evolver-core": {
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"node": "^22.13.0 || >=23.4.0"
      },
      "optionalDependencies": {
        "@napi-rs/keyring": "^1.1.6"
      }
    },
    "node_modules/@evomap/evolver-adapter-public/node_modules/@evomap/evolver-core": {
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"node": "^22.13.0 || >=23.4.0"
      },
      "optionalDependencies": {
        "@napi-rs/keyring": "^1.1.6"
      }
    },
    "node_modules/@evomap/evolver-adapter-public/node_modules/@evomap/evolver-core": {
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"node": "^22.13.0 || >=23.4.0"
      },
      "optionalDependencies": {
        "@napi-rs/keyring": "^1.1.6"
      }
    },
    "node_modules/@evomap/evolver-adapter-public/node_modules/@evomap/evolver-core": {
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"node": "^22.13.0 || >=23.4.0"
      },
      "optionalDependencies": {
        "@napi-rs/keyring": "^1.1.6"
      }
    },
    "node_modules/@evomap/evolver-adapter-public/node_modules/@evomap/evolver-core": {
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"node": "^22.13.0 || >=23.4.0"
      },
      "optionalDependencies": {
        "@napi-rs/keyring": "^1.1.6"
      }
    },
    "node_modules/@evomap/evolver-adapter-public/node_modules/@evomap/evolver-core": {
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.prompt_injection_instructions

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
code/pi_evolve.mjs:141

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
code/pi_evolve.mjs:32

Prompt-injection style instruction pattern detected.

Warn
Code
suspicious.prompt_injection_instructions
Location
docs/adapter-design.md:172