Back to skill

Security audit

Weekly Self Improve Loop

Security checks for vulnerabilities and agentic risk

Overview

The skill is a self-improvement workflow, but it reads recent agent memory and can create or update persistent local skills from raw blocker text without clear approval or sanitization.

Review carefully before installing. Use it only if you are comfortable with an agent reading recent memory files and proposing skill changes, and require explicit human approval plus redaction or allowlisted categories before any local skill is created or updated.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (2)

other

Warning
Location
SKILL.md:22
Finding
Unrestricted Processing of Sensitive Agent Memory## Vulnerability Details **File Location**: `SKILL.md`, lines 22-38 **Vulnerability Type**: Privacy-sensitive agent memory reconnaissance **Risk Level**: Medium ### Vulnerable Code ```powershell # Get last 7 days of memory $startDate = (Get-Date).AddDays(-7) $memoryFiles = Get-ChildItem "memory/" -Filter "*.md" | Where-Object { $_.LastWriteTime -ge $startDate } # Aggregate metrics $totalTasks = 0 $completedTasks = 0 $blockedTasks = 0 $patterns = @{} foreach ($file in $memoryFiles) { $content = Get-Content $file.FullName -Raw # Count tasks $totalTasks += ([regex]::Matches($content, "Task:")).Count $completedTasks += ([regex]::Matches($content, "Status: complete")).Count $blockedTasks += ([regex]::Matches($content, "Blocker:")).Count # Extract patterns $blockers = [regex]::Matches($content, "Blocker: (.+)") ``` ### Technical Analysis The workflow enumerates every recently modified Markdown file in the `memory/` directory and loads each file in full through `Get-Content -Raw`. It then extracts the complete text following each `Blocker:` field. This behavior conflicts with the stated privacy control of using “aggregate data only.” Although task-status metrics are aggregated, blocker values are retained as raw strings for subsequent processing. Memory files can contain private conversation-derived information, project details, operational failures, internal paths, credentials, or other sensitive data. There is no field-level data minimization, schema validation, secret redaction, access confirmation, or provenance check before memory content is processed. No network transmission is present in the reviewed file, so the confirmed exposure is limited to local processing and any downstream local reports or generated skills. ### Attack Path 1. Sensitive or attacker-influenced text is recorded in a recent `memory/*.md` file, particularly on a line beginning wi ...[truncated 1122 chars]
Remediation
## Remediation Suggestions - Replace full memory-file reads with a dedicated, schema-validated metrics store containing only task counts, status values, and approved blocker category identifiers. - Require explicit user authorization before inspecting conversational or long-term memory. - Apply an allowlist of accepted fields and reject free-form blocker text. - Categorize blocker details at ingestion time and retain only non-sensitive category labels for analytics. - Add secret and personally identifiable information redaction before any data reaches reports, logs, or skill-generation workflows. - Ensure raw memory content is discarded immediately after processing and is never copied into generated skills. - Restrict filesystem access to the minimum required directory and verify that symbolic links cannot redirect reads outside the intended memory location. - Document which memory data is accessed, how long derived information is retained, and where reports are written.

T02 · Agent Memory Poisoning

Error
Location
SKILL.md:52
Finding
Persistent Skill Generation from Untrusted Memory Content## Vulnerability Details **File Location**: `SKILL.md`, lines 52-70 **Vulnerability Type**: Agent memory poisoning through persistent skill creation **Risk Level**: High ### Vulnerable Code ```powershell # Find top friction patterns $topPatterns = $patterns.GetEnumerator() | Sort-Object Value -Descending | Select-Object -First 3 foreach ($p in $topPatterns) { Write-Host "Pattern: $($p.Key) ({$p.Value} occurrences)" # Create or update skill $skillName = $p.Key -replace '[^a-z]', '-' -replace '-+', '-' $skillPath = "skills/local/$skillName-recovery" if (Test-Path $skillPath) { Write-Host " Updating existing skill..." } else { Write-Host " Creating new skill..." # Create skill (see memory-to-skill-crystallizer) } } ``` The persistence expectation is reinforced by the completion criterion: ```markdown | Skills created/updated | At least 1 skill actioned | ``` ### Technical Analysis The workflow treats blocker text extracted from memory as trusted input for creating or updating persistent local skills. Frequency is the only selection control: the three most common strings become candidate skill actions. Filename normalization removes characters outside lowercase `a-z`, but it does not validate the meaning or safety of the source text. It therefore does not prevent malicious instructions, unsafe behavioral rules, or misleading recovery procedures from influencing generated skill content. The actual creation operation is delegated to an unspecified `memory-to-skill-crystallizer`. No human approval, trusted-provenance requirement, semantic policy validation, generated-content review, or rollback mechanism is required. Consequently, an attacker able to influence repeated memory entries could promote attacker-controlled content into persistent agent instructions. The reviewed file does not itself contain the implementation t ...[truncated 1792 chars]
Remediation
## Remediation Suggestions - Prohibit direct conversion of free-form memory content into executable or authoritative skill instructions. - Treat every memory-derived value as untrusted data, regardless of repetition frequency. - Map blocker entries to a fixed allowlist of non-executable categories rather than using raw strings. - Generate proposed skill changes in a quarantined staging directory and display a complete diff before installation. - Require explicit human approval for every new skill and every modification to an existing skill. - Validate generated content against policies that prohibit changes to safety constraints, authorization boundaries, tool permissions, hidden instructions, and autonomy baselines. - Record provenance for every generated instruction, including the source memory entries and the generation mechanism. - Use version control, integrity hashes, audit logs, and an immediate rollback mechanism for generated skills. - Prevent generated skills from being automatically loaded or executed until they pass independent review. - Define and audit the referenced `memory-to-skill-crystallizer`; it should use deterministic templates and must not copy raw memory text into instruction-bearing sections. - Apply rate limits and deduplication so repeated attacker-controlled entries cannot gain authority merely through frequency.
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (3)

Self-Modification

High
Category
Rogue Agent
Content
foreach ($p in $topPatterns) {
    Write-Host "Pattern: $($p.Key) ({$p.Value} occurrences)"
    
    # Create or update skill
    $skillName = $p.Key -replace '[^a-z]', '-' -replace '-+', '-'
    $skillPath = "skills/local/$skillName-recovery"
Confidence
98% confidence
Finding
This skill performs self-modification by creating or updating local skills based on patterns extracted from memory, which is effectively untrusted input. That creates a feedback loop where malformed, adversarial, or sensitive blocker text can influence future agent behavior, persist bad logic, or introduce unsafe skills without meaningful review.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The skill claims it only uses aggregate data and avoids content-specific details, but the workflow extracts raw blocker text and uses it to derive pattern labels and skill names. If blocker entries contain sensitive project names, personal data, secrets, or internal incident details, those details can be propagated into generated artifacts and reports, violating the stated privacy boundary.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The self-use trigger is broad enough to activate during routine conditions like every Sunday, manual request, or after major project completion, which increases the chance of the skill running without careful operator review. In a skill that reads historical memory and can create or update skills, ambiguous triggering expands the attack surface for unintended execution and cascading changes.