Back to skill

Security audit

content-matrix-factory

Security checks for vulnerabilities and agentic risk

Overview

The skill’s content-generation purpose is mostly clear, but it also adds persistent learning and self-modifying instruction behavior without clear user control.

Review or remove the self-learning section before installing. Do not let this skill store secrets, customer data, account details, or private business notes in learned_patterns.json, and require explicit approval before any update to SKILL.md or any real platform posting/distribution action.

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

Warning
Location
scripts/learner.py:70
Finding

Persistent Untrusted Learning Data Can Influence Future Agent Behavior

Content
View full analysis

Vulnerability Details

File Location: scripts/learner.py:70-126, with the persistence workflow documented in SKILL.md:205-225
Vulnerability Type: Persistent memory poisoning through unsanitized user-controlled learning records
Risk Level: Medium

Vulnerable Code

python
def record_op(skill_dir, capability, success=True, error=None, note=None):
    data = load_learning(skill_dir)
    data["totalOps"] += 1
    cap = data["capabilityStats"].setdefault(capability, {"count": 0, "success": 0, "fail": 0})
    cap["count"] += 1
    if success:
        cap["success"] += 1
    else:
        cap["fail"] += 1
        data["totalErrors"] += 1
    if error:
        ep = data["errorPatterns"].setdefault(error, {"count": 0, "lastNote": "", "lastTime": ""})
        ep["count"] += 1
        ep["lastNote"] = note or ""
        ep["lastTime"] = data["lastUpdated"] or datetime.datetime.now().strftime("%Y-%m-%dT%H:%M")
    rec = {"t": data["lastUpdated"], "cap": capability, "ok": success, "err": error, "note": note}
    data["recentOps"].append(rec)
    data["recentOps"] = data["recentOps"][-20:]
    save_learning(skill_dir, data)
    return data

def record_preference(skill_dir, key, value):
    data = load_learning(skill_dir)
    data["preferences"][key] = value
    save_learning(skill_dir, data)
    return data
python
def self_reflect(skill_dir):
    data = load_learning(skill_dir)
    suggestions = []
    for err, info in data["errorPatterns"].items():
        if info["count"] >= THRESHOLD_ERROR:
            suggestions.append(
                f"⚠️ Error “{err}” has occurred {info['count']} times; add validation or fallback steps, "
                f"and write the experience back into SKILL.md "
                f"(lastNote: {info.get('lastNote','')})"
            )
    return suggestions

The corresponding workflow in SKILL.md directs the agent to retai ...[truncated 2408 chars]

Remediation
View remediation

Remediation Suggestions

  1. Treat all persisted capability names, errors, notes, preference keys, and values as untrusted data.
  2. Define an allowlisted schema for preference keys and enforce type, character, and length restrictions on all stored fields.
  3. Reject or quarantine values containing instruction-like directives, role changes, tool commands, markup intended to alter prompts, or requests to bypass policy.
  4. Keep observations separate from executable or authoritative instructions. Never concatenate raw stored values into agent prompts without clear quoting and provenance labels.
  5. Remove the instruction to automatically rewrite SKILL.md. Require an explicit, human-reviewed approval step for every proposed skill modification.
  6. Require confirmation before applying a stored preference in a new session, especially when it changes tool use, security behavior, destination URLs, or output constraints.
  7. Store structured error identifiers rather than arbitrary error labels, and render free-form notes only as quoted diagnostic data.
  8. Add integrity controls and an audit trail recording who created, reviewed, approved, or deleted each persistent entry.
  9. Provide commands to inspect, reset, and selectively delete learned state before it affects future sessions.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/learner.py:65
Finding

Free-Form User Data Is Persisted in a Predictable Plaintext File

Content
View full analysis

Vulnerability Details

File Location: scripts/learner.py:65-103
Vulnerability Type: Insecure persistent storage of potentially sensitive notes and preferences
Risk Level: Low

Vulnerable Code

python
def save_learning(skill_dir, data):
    data["lastUpdated"] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M")
    p = learn_path(skill_dir)
    with open(p, "w", encoding="utf-8") as f:
        f.write(json.dumps(data, indent=2, ensure_ascii=False))

def record_op(skill_dir, capability, success=True, error=None, note=None):
    data = load_learning(skill_dir)
    data["totalOps"] += 1
    cap = data["capabilityStats"].setdefault(capability, {"count": 0, "success": 0, "fail": 0})
    cap["count"] += 1
    if success:
        cap["success"] += 1
    else:
        cap["fail"] += 1
        data["totalErrors"] += 1
    if error:
        ep = data["errorPatterns"].setdefault(error, {"count": 0, "lastNote": "", "lastTime": ""})
        ep["count"] += 1
        ep["lastNote"] = note or ""
        ep["lastTime"] = data["lastUpdated"] or datetime.datetime.now().strftime("%Y-%m-%dT%H:%M")
    rec = {"t": data["lastUpdated"], "cap": capability, "ok": success, "err": error, "note": note}
    data["recentOps"].append(rec)
    data["recentOps"] = data["recentOps"][-20:]
    save_learning(skill_dir, data)
    return data

def record_preference(skill_dir, key, value):
    data = load_learning(skill_dir)
    data["preferences"][key] = value
    save_learning(skill_dir, data)
    return data

Technical Analysis

The helper stores arbitrary notes and preference values verbatim in learned_patterns.json. The file is written to a predictable location using the process's default file permissions. There is no sensitive-data detection, redaction, encryption, retention limit for preferences and error patterns, explicit consent mechanism, or restrictive permission enforcement.

Alt ...[truncated 1574 chars]

Remediation
View remediation

Remediation Suggestions

  1. Minimize persistence by storing only identifiers and aggregate counters required for the learning feature.
  2. Explicitly prohibit secrets, credentials, personal data, and confidential business information in notes and preference values.
  3. Detect and redact common credential formats, authorization headers, private keys, tokens, and sensitive personal data before writing.
  4. Create the file with restrictive permissions, such as owner read and write only, and verify permissions on every save.
  5. Use atomic writes to a securely created file and avoid inheriting unexpectedly permissive process defaults.
  6. Add configurable expiration periods for notes, preferences, and error details instead of retaining them indefinitely.
  7. Provide clear inspection and deletion controls, including a complete state-reset operation.
  8. Obtain explicit user consent before enabling cross-session storage.
  9. If sensitive persistence is genuinely required, use an operating-system credential store or encryption with keys maintained separately from the skill directory.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill advertises a content-generation and distribution workflow, but the documented actionable behavior adds a separate persistent learning/logging subsystem that records usage history, preferences, and self-reflection state. This mismatch is dangerous because users and orchestrators may invoke the skill under false assumptions about scope, while hidden or undeclared stateful behavior can collect data and alter future behavior outside the declared purpose.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger phrases are broad enough to match many ordinary content-marketing requests, increasing the chance that the skill is invoked in contexts where users did not intend its persistent or distribution-related behaviors. Overbroad routing is risky when the skill also contains undeclared state retention and behavioral drift mechanisms.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The description references automation/distribution behavior and, in the broader skill text, persistent preference storage, but does not present a clear user-facing warning or consent mechanism. Users may unknowingly allow retention or broader content operations than expected, which creates privacy and trust risks.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill documentation introduces a persistent self-learning system and instructs writing experience back into local files, including SKILL.md itself. Self-modifying or self-updating instructions are risky because they can create undocumented drift, preserve unsafe prompts, and make future executions behave differently from what reviewers originally approved.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Persisting user preferences and operational history is not necessary for the advertised one-shot content factory use case and expands data collection beyond user expectations. Unnecessary retention increases the chance of privacy leakage, cross-session profiling, and unintended reuse of prior user data in later outputs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The learning section explicitly instructs writing learned data back to SKILL.md and learned_patterns.json without any warning, approval step, or retention policy. Silent persistence and prompt-file modification are dangerous because they create hidden state, enable prompt drift, and may preserve sensitive user-derived information beyond the current session.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill plainly instructs persistent storage of usage history, errors, preferences, and insights in local files, creating a straightforward data-retention and leakage risk. Even if the stored fields look operational, they can accumulate sensitive behavioral information and be exposed to other tools, users, or future runs.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes a self-media content factory for multi-platform content generation, scheduling, and trend-driven creation. This file instead implements a generic telemetry and persistence utility that records arbitrary skill usage, user preferences, recurring errors, and optimization suggestions for any WorkBuddy skill, which is outside the manifest-described business behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This Python file contains its module docstring, CLI descriptions, comments, and user-visible messages entirely in Chinese, with no indication that the skill is China-specific or that users may select another language. That creates a natural-language policy issue because it imposes a locale on all users without opt-in.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The module accepts an arbitrary directory path or skill name and then reads/writes learned_patterns.json in that target location. In a multi-skill environment, this enables unintended cross-skill inspection and modification of state, which breaks isolation boundaries and could overwrite or poison other skills’ metadata if the caller has filesystem permissions.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The inline documentation says the capability name should reflect the current skill use, but the provided examples use '简历优化' and '比价', which belong to unrelated skill domains. This actively misrepresents the intended operation of the content-matrix skill and suggests copy-pasted instructions disconnected from the actual skill purpose.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The example stores an output language preference directly as Chinese without showing any opt-in or choice, which normalizes silent preference profiling. While lower severity on its own, it reinforces the broader pattern of unauthorized persistence and can surprise users or affect future interactions without their knowledge.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.