Back to skill

Security audit

Memory to Skill Crystallizer

Security checks for vulnerabilities and agentic risk

Overview

This skill is clearly about turning memory notes into reusable skills, but it can persist raw memory-derived text into future agent instructions without enough review or safeguards.

Review this skill carefully before installing. It should only be used with trusted, non-sensitive memory files and should ideally be changed to generate drafts for human review, sanitize extracted patterns, avoid copying full error messages, and refuse to overwrite existing skills.

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

T02 · Agent Memory Poisoning

Error
Location
SKILL.md:22
Finding
Persistent Skill Poisoning Through Untrusted Memory Content## Vulnerability Details **File Location**: `SKILL.md`, lines 22-69 **Vulnerability Type**: Persistent injection of untrusted content into generated agent skills **Risk Level**: High ### Vulnerable Code ```powershell $memoryFiles = Get-ChildItem "memory/" -Filter "*.md" | Sort-Object LastWriteTime -Descending | Select-Object -First 7 $patterns = @{} foreach ($file in $memoryFiles) { $content = Get-Content $file.FullName -Raw if ($content -match "Failed|Blocker|Error") { # Extract pattern $matches = [regex]::Matches($content, "(Failed|Blocker|Error): (.+)") foreach ($m in $matches) { $key = $m.Groups[2].Value $patterns[$key] = $patterns[$key] + 1 } } } # Find repeated patterns (2+ occurrences) $repeated = $patterns.GetEnumerator() | Where-Object { $_.Value -ge 2 } ``` ```powershell foreach ($pattern in $repeated) { $skillName = $pattern.Key -replace '[^a-z]', '-' -replace '-+', '-' $skillPath = "skills/local/$skillName-recovery" New-Item -ItemType Directory -Path $skillPath -Force | Out-Null $skillContent = @" --- name: $skillName-recovery description: Auto-recovery for: $($pattern.Key) --- # $($pattern.Key) Recovery ## Trigger When $($pattern.Key) occurs ## Steps 1. Detect the error pattern 2. Execute recovery steps 3. Verify resolution ## Verification - [ ] Error resolved - [ ] Task can continue "@ $skillContent | Out-File "$skillPath/SKILL.md" -Encoding UTF8 } ``` ### Technical Analysis The complete value following an `Error:`, `Failed:`, or `Blocker:` prefix is treated as a trusted pattern. It is interpolated directly into the metadata, title, and trigger text of a persistent `SKILL.md` file. There is no validation of the content's origin, semantic meaning, Markdown structure, or suitability as an agent instruction. Although filename characters a ...[truncated 1705 chars]
Remediation
## Remediation Suggestions - Treat all memory-file content as untrusted input. - Parse only a strict, structured error identifier rather than arbitrary text following an error prefix. - Enforce length limits and an allowlist of permitted characters and error identifiers. - Reject line breaks, YAML delimiters, Markdown headings, code fences, links, tool directives, and instruction-like phrases. - Serialize generated metadata using a YAML library rather than string interpolation. - Escape content before placing it in Markdown and keep data separate from executable agent instructions. - Require explicit human review and approval before generated skills are written, registered, or loaded. - Store generated drafts in a non-discoverable quarantine directory until approved. - Record the source files and hashes used to generate each skill to support provenance checks. - Prevent generated skills from granting themselves tools, permissions, or automatic activation behavior.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:29
Finding
Sensitive Memory Data Can Be Copied Into Persistent Skill Files## Vulnerability Details **File Location**: `SKILL.md`, lines 29-33 and 49-67 **Vulnerability Type**: Unredacted sensitive-data persistence **Risk Level**: High ### Vulnerable Code ```powershell $matches = [regex]::Matches($content, "(Failed|Blocker|Error): (.+)") foreach ($m in $matches) { $key = $m.Groups[2].Value $patterns[$key] = $patterns[$key] + 1 } ``` ```powershell $skillContent = @" --- name: $skillName-recovery description: Auto-recovery for: $($pattern.Key) --- # $($pattern.Key) Recovery ## Trigger When $($pattern.Key) occurs ## Steps 1. Detect the error pattern 2. Execute recovery steps 3. Verify resolution ## Verification - [ ] Error resolved - [ ] Task can continue "@ $skillContent | Out-File "$skillPath/SKILL.md" -Encoding UTF8 ``` The stated privacy claim at lines 96-99 is not technically enforced: ```markdown ## Privacy/Safety - No sensitive data in extracted patterns - Pattern names only, no specific content - Local skills only (not published) ``` ### Technical Analysis The regular expression captures the entire remainder of an error line and assigns it to `$key`. That raw value is subsequently copied into several locations in a persistent skill file. No secret scanning, redaction, tokenization, data classification, or entropy check occurs before persistence. Error and blocker messages commonly contain access tokens, credentials, connection strings, private repository URLs, customer identifiers, email addresses, internal hostnames, filesystem paths, or application data. Calling the extracted value a “pattern name” does not prevent such information from being captured. The implementation therefore does not substantiate its explicit privacy guarantee. ### Attack Path 1. A memory entry contains an error message with a credential, token, private path, customer record, internal URL, or other sensitive value. 2. The same message appears ...[truncated 979 chars]
Remediation
## Remediation Suggestions - Never copy complete error messages into generated skills. - Extract only normalized error classes or approved identifiers, such as a fixed error code. - Apply secret detection and redaction for API keys, credentials, tokens, connection strings, private keys, URLs with embedded credentials, email addresses, and high-entropy values. - Replace variable data such as paths, identifiers, hostnames, and user-provided values with typed placeholders. - Fail closed when content cannot be confidently classified as non-sensitive. - Present the sanitized output and source references for human approval before persistence. - Set restrictive filesystem permissions on generated drafts and exclude them from source control, synchronization, and automated publication. - Add automated tests proving that representative secrets and personal data are never written to generated files. - Remove or revise the privacy claims until the safeguards are technically enforced.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:43
Finding
Generated Skill Names Can Collide With and Overwrite Existing Skills## Vulnerability Details **File Location**: `SKILL.md`, lines 43-69 **Vulnerability Type**: Unsafe path derivation and destructive file overwrite **Risk Level**: Medium ### Vulnerable Code ```powershell foreach ($pattern in $repeated) { $skillName = $pattern.Key -replace '[^a-z]', '-' -replace '-+', '-' $skillPath = "skills/local/$skillName-recovery" New-Item -ItemType Directory -Path $skillPath -Force | Out-Null $skillContent = @" --- name: $skillName-recovery description: Auto-recovery for: $($pattern.Key) --- # $($pattern.Key) Recovery ## Trigger When $($pattern.Key) occurs ## Steps 1. Detect the error pattern 2. Execute recovery steps 3. Verify resolution ## Verification - [ ] Error resolved - [ ] Task can continue "@ $skillContent | Out-File "$skillPath/SKILL.md" -Encoding UTF8 } ``` ### Technical Analysis Skill names are produced through lossy normalization: every character other than a lowercase ASCII letter is replaced with a hyphen, and consecutive hyphens are collapsed. Distinct source patterns can consequently resolve to the same directory name. Patterns containing uppercase letters, digits, punctuation, or different separators are especially likely to collide. A value containing no lowercase letters may also normalize to a trivial name such as `-`. The workflow creates the destination directory with `-Force` and writes `SKILL.md` using `Out-File`, which replaces existing file content by default. It does not check whether the destination already belongs to a trusted skill, whether another pattern generated the same normalized name, or whether replacement was authorized. ### Attack Path 1. The attacker identifies or predicts the normalized directory name of an existing skill under `skills/local/`. 2. The attacker introduces a repeated memory pattern that normalizes to the same name. 3. The workflow selects the repeated pattern and c ...[truncated 1003 chars]
Remediation
## Remediation Suggestions - Canonicalize names using a well-defined slugging function and reject empty or trivial results. - Add a stable cryptographic digest of the complete source identifier to generated directory names so distinct patterns cannot silently collide. - Check whether the destination directory or `SKILL.md` already exists before writing. - Use create-new semantics and abort on collisions instead of overwriting files. - Maintain a registry that maps each generated path to its source pattern and provenance. - Require explicit approval before replacing any existing skill. - Write to a newly created temporary file, validate the completed document, and then perform an atomic move only when the destination is confirmed absent. - Apply ownership or signature verification so generated content cannot replace manually maintained or trusted skills. - Detect duplicate normalized names within the same generation run and report them as errors.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (1)

Vague Triggers

Medium
Confidence
96% confidence
Finding
The self-use trigger conditions are broad enough that the skill could activate in many normal workflows, causing automatic generation of new skills from memory content without strong scoping or review. In this context, that increases the chance of turning noisy, malformed, or sensitive memory-derived text into persistent local skills, which can create unsafe automation and prompt-surface expansion.