Back to skill

Security audit

Self-Repair System — Autonomous AI Automation

Security checks for vulnerabilities and agentic risk

Overview

This self-repair skill has plausible repair features, but it also grants broad automatic file, process, command, network, and scheduling capabilities that are not tightly scoped.

Review before installing. Use only in a tightly scoped workspace with trusted configuration, do not expose its SelfRepair or RoutineManager objects to untrusted callers, and avoid running automatic repair unless you accept possible file overwrites, service disruption, and local command/process effects.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
src/self-repair.js:162
Finding
Workspace Repair Path Traversal Allows Writes Outside the Workspace<![CDATA[ ## Vulnerability Details **File Location**: `src/self-repair.js:162-177` **Vulnerability Type**: Path traversal and arbitrary file write **Risk Level**: High ### Vulnerable Code ```javascript for (const backupPath of this.backupPaths) { for (const item of missing) { const source = path.join(backupPath, item); const dest = path.join(this.workspacePath, item); if (fs.existsSync(source)) { const dir = path.dirname(dest); if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); if (item.endsWith('/')) { fs.mkdirSync(dest, { recursive: true }); } else { fs.copyFileSync(source, dest); } this.log('repair', `Restored ${item} from backup`); } } } ``` ### Technical Analysis The values in `requiredFiles`, `requiredDirs`, and `backupPaths` are accepted from configuration and used to construct filesystem paths without validating their canonical locations. An entry containing parent-directory components, such as `../../target/file`, can cause `dest` to resolve outside `workspacePath`. The same issue affects `source`, allowing the repair process to read from locations outside the intended backup directory. For directory entries, the code can create directories outside the workspace. For file entries, `fs.copyFileSync()` can overwrite any destination file writable by the current process. Checking `fs.existsSync(source)` does not establish that the source remains within an approved backup root. The implementation also does not protect against symbolic-link traversal, where a path lexically inside the workspace or backup directory resolves to a location outside it. ### Attack Path 1. An attacker gains influence over the `SelfRepair` configuration, such as through an application configuration file, plugin input, deployment parameter, or other integration that constructs the instance. 2. The attacker supplies a crafted required item containing traversal components, for ex ...[truncated 1504 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject absolute paths and any item containing `..` path components. 2. Resolve each destination with `path.resolve()` and verify that it remains beneath the canonical workspace root: ```javascript const workspaceRoot = fs.realpathSync(this.workspacePath); const dest = path.resolve(workspaceRoot, item); const workspacePrefix = workspaceRoot.endsWith(path.sep) ? workspaceRoot : workspaceRoot + path.sep; if (dest !== workspaceRoot && !dest.startsWith(workspacePrefix)) { throw new Error(`Required item escapes workspace: ${item}`); } ``` 3. Apply the same containment validation to every source path relative to its approved backup root. 4. Canonicalize existing source paths with `fs.realpathSync()` before reading them to detect symbolic-link escapes. 5. Before writing, inspect existing parent components with `lstatSync()` and reject symbolic links unless explicitly permitted. 6. Define a strict schema for required items, such as normalized workspace-relative paths with an explicit file or directory type, rather than identifying directories by a trailing slash. 7. Fail the repair cycle when an invalid path is detected and record the rejected path without attempting a partial repair. 8. Run the service under a least-privileged account with write permission limited to the intended workspace. 9. Add tests covering `../`, nested traversal, absolute paths, symbolic links, mixed path separators, and backup-root escapes. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
src/self-repair.js:296
Finding
Public Process-Control Methods Permit Arbitrary Program Execution and Broad Process Termination<![CDATA[ ## Vulnerability Details **File Location**: `src/self-repair.js:296-329` **Vulnerability Type**: Excessive process-control capability and insufficient authorization **Risk Level**: Medium ### Vulnerable Code ```javascript /** Kill a process by name (validated against safe characters) */ killProcess(processName) { if (!/^[\w.\-]+$/.test(processName)) return Promise.resolve(false); return new Promise((resolve) => { const { execFile } = require('child_process'); if (process.platform === 'win32') { execFile('taskkill', ['/IM', processName, '/F'], () => resolve(true)); } else { execFile('pkill', ['-f', processName], () => resolve(true)); } }); } /** Run a command and return stdout. * @no-shell — uses spawn(shell:false), no shell interpolation. * Shell injection operators are blocked unconditionally before execution. * Only use with trusted, internally-constructed command strings. */ runCommand(command) { // Block shell injection operators — no exceptions if (/[;&|`$<>\n]/.test(command)) { return Promise.reject(new Error(`Blocked: shell operators not permitted in command: "${command}"`)); } const parts = command.trim().split(/\s+/); return new Promise((resolve, reject) => { let stdout = ''; const child = spawn(parts[0], parts.slice(1), { shell: false }); child.stdout.on('data', d => { stdout += d; }); const killTimer = setTimeout(() => { child.kill(); reject(new Error('Command timeout')); }, 30000); child.on('error', (err) => { clearTimeout(killTimer); reject(err); }); child.on('close', (code) => { clearTimeout(killTimer); if (code !== 0) reject(new Error(`Command exited with code ${code}`)); else resolve(stdout.trim()); }); }); } ``` ### Technical Analysis `runCommand()` prevents direct shell metacharacter injection and launches the child with `shell: false`. However, it still accepts the executable name and every argument from a single caller-suppl ...[truncated 2450 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `runCommand()` and `killProcess()` if they are not required by the documented repair workflow. 2. If process management is necessary, make the methods private and expose narrowly scoped operations such as `restartOllama()`. 3. Maintain an explicit allowlist of canonical executable paths. Do not accept an executable name from a caller. 4. Pass arguments as structured arrays and validate them against a command-specific schema rather than splitting a command string. 5. Do not allow interpreters, shells, package managers, download tools, or general-purpose system utilities. 6. Replace name-based process termination with PID-based management: - Record the PID of the process started by the component. - Verify the process identity before termination. - Terminate only that recorded child process. 7. Avoid `pkill -f`, because complete-command-line matching can affect unrelated processes. 8. Add an explicit authorization boundary if any process-control operation is exposed through an API, plugin, routine, or agent tool. 9. Execute the application under a least-privileged operating-system account and constrain child processes using platform sandboxing where available. 10. Log authorized process-control operations, including the requested action, validated target, caller identity, and outcome. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description focuses narrowly on automated self-diagnostics and recovery behavior. This code does include that via SelfRepair.fullRepairCycle() and periodic health checks, which aligns with the declared purpose. However, it also provides materially broader capabilities not disclosed in the description: an ask/smartAsk interface that sends arbitrary prompts to Ollama's /api/generate endpoint, a RoutineManager that starts and manages scheduled routines, and a general-purpose automation hub role. Those are not merely supporting details for self-diagnostics; they add unrelated orchestration and model-invocation functionality. Therefore the description does not accurately represent the full behavior of this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The code chunk is a general-purpose RoutineManager. It parses schedules, runs registered async callbacks on intervals/daily schedules, tracks run history/errors, emits events, and supports persistence of timing state. There is no logic to restart Ollama, inspect crashes, repair configuration files, verify workspace integrity, or recover from common failures. The primary purpose is materially different from the declared self-diagnostics/recovery description, so this is a clear mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The core declared behavior is largely represented: the module does restart Ollama, verify workspace integrity, repair workspace/config issues, and perform health/recovery flows. However, it also exposes materially broader operational capabilities that are not declared. Specifically, runCommand() can execute arbitrary commands, killProcess() can terminate arbitrary processes by name, and checkHTTPService() can probe non-Ollama HTTP services. These go beyond a narrowly described self-diagnostics/self-repair utility for Ollama/config/workspace recovery, so this is a description-behavior mismatch.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The manifest describes a self-healing skill for diagnosing and repairing Ollama, configs, and workspace files. This file instead implements a generic routine scheduler that registers arbitrary actions, runs them on timers, emits events, and persists execution history, with no Ollama recovery, config repair, or workspace-integrity logic present.

Intent-Code Divergence

High
Confidence
97% confidence
Finding
The top-level documentation asserts network traffic is limited to localhost Ollama health checks, but the code later implements arbitrary HTTP requests. That mismatch is dangerous because it can mislead reviewers and operators into granting trust to a component that has broader network capability than disclosed.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
This exposes a generic process-killing primitive that can terminate arbitrary processes by name, which is destructive and not tightly scoped to repairing Ollama. In an agent context, this can be abused for denial of service against local applications, developer tools, or security software.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The runCommand method is a generic command-execution primitive. Although shell metacharacters are filtered and spawn uses shell:false, arbitrary executable invocation is still possible, enabling broad local code execution and abuse well beyond the declared self-repair function.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README explicitly promotes automatic repair behaviors such as restoring files from backup, killing and restarting services, and repairing corrupted configs 'without human intervention,' but it does not clearly foreground confirmation requirements, dry-run behavior, rollback guarantees, or safety boundaries. In a self-repair/orchestration skill, these actions can overwrite valid state, destroy forensic evidence, or cause unintended service disruption if detection logic is wrong or manipulated.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The description uses broad 'self-repair' and 'auto-healing' language without defining when the skill may act, what resources it may modify, or what actions are excluded. In a repair-oriented skill, vague activation scope can normalize invasive behavior and increase the chance of unsafe or unauthorized file, process, or configuration changes.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The markdown advertises repairing configs and files but provides no warning that such actions can overwrite data, restart services, or alter workspace state. Without disclosure of these risks, users may invoke the skill without informed consent, making harmful changes more likely and harder to detect or attribute.

Description-Behavior Mismatch

Medium
Confidence
87% confidence
Finding
The manifest limits the skill to self-diagnostics, restarts, config repair, integrity verification, and recovery from common failures. This file also imports a `RoutineManager`, starts it automatically, and exposes `schedule()` for recurring arbitrary tasks, which is a broader automation/orchestration capability not described in the manifest.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
Automatic repair is executed at startup and repeatedly on a timer without confirmation, dry-run mode, or visible authorization checks. In a self-repair skill, this is more dangerous because the intended behavior includes modifying configs and files, so a bad repair decision, corrupted state, or manipulated inputs could repeatedly alter the workspace without user awareness.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest describes automated self-diagnostics and repair of Ollama, configs, and workspace files. However, this module exposes `ask()` and `smartAsk()` methods that send arbitrary prompts to Ollama and return model output, which is a general LLM interaction capability rather than a repair or integrity-check function.

Session Persistence

Medium
Category
Rogue Agent
Content
return { response, model: this.config.defaultModel };
  }

  /** Schedule a recurring task */
  schedule(name, cronExpr, taskFn) {
    this.routines.add(name, cronExpr, taskFn);
  }
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.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The `add` API explicitly accepts a caller-supplied `routine.action` async function, and `_tick` later executes it via `await routine.action(routine)`. A generic scheduler capable of running arbitrary injected actions is a broader orchestration capability than the manifest's narrowly described diagnostics and repair role.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The module claims network access is limited to localhost Ollama checks, but this function accepts arbitrary host, port, and path values and can probe any HTTP service. In an agent skill, that becomes a reusable SSRF/internal reconnaissance primitive that expands the attack surface beyond the stated purpose.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The workspace and config repair paths perform automatic file creation, overwrite, and copy operations without user confirmation, dry-run mode, or strong path constraints. In practice this can cause destructive or unauthorized changes to project files, especially if configuration values such as workspacePath, backupPaths, or configPath are influenced by untrusted input.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
Process termination is an inherently destructive action, and here it occurs without any user-facing warning, confirmation, or scope limitation. Within a self-repair skill, this makes accidental or malicious disruption easier because the function can kill processes unrelated to the repair task.

Scope Creep

Low
Category
Excessive Agency
Content
**USE AT YOUR OWN RISK.**

- The author(s) are NOT liable for any damages, losses, or consequences arising from 
  the use or misuse of this software — including but not limited to financial loss, 
  data loss, security breaches, business interruption, or any indirect/consequential damages.
- This software does NOT constitute financial, legal, trading, or professional advice.
- Users are solely responsible for evaluating whether this software is suitable for
Confidence
70% confidence
Finding
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Intent-Code Divergence

Low
Confidence
81% confidence
Finding
The header comment says this module 'ties together self-repair and scheduled routines' and presents it as a central orchestrator for those functions. In contrast, the code later adds `ask()`/`smartAsk()` methods for sending arbitrary prompts to Ollama, which is not reflected in the documentation and changes the module's intent beyond repair orchestration.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/self-repair.js:9