Back to skill

Security audit

多Agent记忆系统

Security checks for vulnerabilities and agentic risk

Overview

This skill is a plausible multi-agent memory prototype, but it persists user and tool content, handles API keys unsafely, and presents simulated results as operational data without enough disclosure or controls.

Review before installing. Use a dedicated MEMORY_WORKSPACE, avoid capturing secrets or regulated data, do not enter API keys into the setup wizard, prefer environment variables or a secret manager, and treat the dashboard/search results as demo-quality until the project replaces synthetic outputs with measured data. Pin dependency versions before use in a sensitive environment.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (5)

T02 · Agent Memory Poisoning

Error
Location
scripts/hook-capture.py:105
Finding

Persistent Storage of Untrusted Agent Content Enables Memory Poisoning

Content
View full analysis

Vulnerability Details

File Location: scripts/hook-capture.py, lines 105-145 and 248-257
Vulnerability Type: Persistent storage of attacker-controlled content without trust separation
Risk Level: High

Vulnerable Code

python
def capture(self, **kwargs):
    """Capture hook data"""
    if not self.enabled:
        return None
    
    data = {k: v for k, v in kwargs.items() if k in self.capture_fields}
    data["type"] = self.hook_type
    data["timestamp"] = datetime.now().isoformat()
    
    for key in data:
        if isinstance(data[key], str) and len(data[key]) > self.max_length:
            data[key] = data[key][:self.max_length] + "..."
    
    return data

def write_to_daily(self, data, agent_id="main"):
    """Write to the daily memory file"""
    MEMORY_DIR.mkdir(parents=True, exist_ok=True)
    today = datetime.now().strftime("%Y-%m-%d")
    daily_file = MEMORY_DIR / f"{today}.md"
    
    return self.safe_write(daily_file, data, agent_id)

def safe_write(self, file_path, data, agent_id):
    """Optimistic-locking write"""
    for attempt in range(MAX_RETRIES):
        try:
            if file_path.exists():
                with open(file_path, "r", encoding="utf-8") as f:
                    original_content = f.read()
                original_hash = hashlib.md5(original_content.encode()).hexdigest()
            else:
                original_content = ""
                original_hash = ""
            
            hook_line = f"### {data['type']} - {data['timestamp']}\n"
            for key, value in data.items():
                if key not in ["type", "timestamp"]:
                    hook_line += f"- **{key}**: {value}\n"
            hook_line += "\n"
            
            new_content = original_content + hook_line
            
            with open(file_path, "w", encoding="utf-8") as f:
                f.write(new_content)

...[truncated 2394 chars]
Remediation
View remediation

Remediation Suggestions

  1. Store hook records in structured JSON rather than instruction-like Markdown.
  2. Add provenance fields such as source, session, agent, authenticated identity, and trust level.
  3. Treat all prompts and tool outputs as untrusted data at both storage and retrieval time.
  4. Escape Markdown control syntax if Markdown output remains necessary.
  5. Reject or quarantine content containing instruction-like patterns where appropriate.
  6. Require explicit approval before promoting user-controlled records into trusted long-term memory.
  7. In downstream prompts, place retrieved records in a clearly delimited data section and explicitly prohibit following instructions contained in records.
  8. Separate memory by agent and tenant rather than writing every record to one shared daily file.
  9. Add tests proving that stored prompt-injection strings cannot alter downstream agent instructions.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup.py:120
Finding

API Key Is Entered, Stored, and Printed in Plaintext

Content
View full analysis

Vulnerability Details

File Location: scripts/setup.py, lines 120-135 and 149-155
Vulnerability Type: Plaintext secret exposure
Risk Level: High

Vulnerable Code

python
# 5. LLM configuration
print("\n5. LLM configuration")
api_key = input(f"  API Key (leave empty to use environment variable): ").strip()
if api_key:
    config["llm"]["api_key"] = api_key

api_host = input(f"  API Host [{config['llm']['api_host']}]: ").strip()
if api_host:
    config["llm"]["api_host"] = api_host

model = input(f"  Model [{config['llm']['model']}]: ").strip()
if model:
    config["llm"]["model"] = model

# Save configuration
print("\nSaving configuration...")
with open(self.config_file, "w", encoding="utf-8") as f:
    yaml.dump(config, f, allow_unicode=True, default_flow_style=False)
python
def main():
    """Main function"""
    wizard = ConfigWizard()
    config = wizard.run()
    
    print("\nCurrent configuration:")
    print(json.dumps(config, ensure_ascii=False, indent=2))

Technical Analysis

The setup wizard obtains the API key through ordinary input(), so the secret is visible while typed. It then places the key in the configuration object, writes it to a plaintext YAML file using process-default file permissions, and prints the entire configuration object—including the key—to standard output.

This creates several independent disclosure channels: terminal display, captured shell sessions, CI/CD logs, support transcripts, workspace backups, and access by other local users when permissions permit. Although the documentation mentions using an environment variable, the implementation actively supports and preserves plaintext key storage.

Attack Path

  1. A user runs the setup wizard and enters an LLM API key.
  2. The key is visibly echoed because input() is used.
  3. The key is written to MEMORY_WORKSPACE/config/config.yaml.
  4. main() prints ...[truncated 610 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not store API keys in the YAML configuration.
  2. Prefer environment variables, an operating-system credential store, or a dedicated secrets manager.
  3. If interactive entry is unavoidable, use getpass.getpass() so the value is not echoed.
  4. Remove the full configuration print or recursively redact fields named api_key, token, secret, and password.
  5. If a local secret file must be supported, create it atomically with permission mode 0600.
  6. Keep non-secret configuration and secrets in separate files.
  7. Warn users when an existing configuration contains a plaintext credential and provide a migration mechanism.
  8. Add tests ensuring that secrets never appear in stdout, stderr, serialized public configuration, or exception messages.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/agent-manager.py:65
Finding

Unchecked Agent Identifier Allows Directory Path Traversal

Content
View full analysis

Vulnerability Details

File Location: scripts/agent-manager.py, lines 65-102
Vulnerability Type: Path traversal through an unvalidated identifier
Risk Level: Medium

Vulnerable Code

python
def register_agent(self, agent_id, agent_config=None):
    """Register an agent"""
    print(f"[Registry] Registering agent: {agent_id}")
    
    if agent_id in self.registry["agents"]:
        print(f"[WARN] Agent already exists: {agent_id}")
        return False
    
    # Create agent configuration
    if agent_config is None:
        agent_config = {
            "id": agent_id,
            "name": f"Agent-{agent_id}",
            "status": "active",
            "registered_at": datetime.now().isoformat(),
            "last_heartbeat": datetime.now().isoformat(),
            "memory_size": AGENT_CONFIG["memory_per_agent"],
            "hooks_enabled": True,
            "rrf_enabled": True,
            "graph_enabled": True
        }
    
    self.registry["agents"][agent_id] = agent_config
    self.registry["metadata"]["updated"] = datetime.now().isoformat()
    
    # Create agent directory
    agent_path = self.agent_dir / agent_id
    agent_path.mkdir(parents=True, exist_ok=True)
    
    # Save registry
    with open(self.registry_file, "w", encoding="utf-8") as f:
        json.dump(self.registry, f, ensure_ascii=False, indent=2)
    
    print(f"[Registry] Agent registered successfully: {agent_id}")
    return True

Technical Analysis

agent_id is concatenated with self.agent_dir as a filesystem path without validation or containment verification. pathlib.Path preserves traversal components, so an identifier such as ../../outside-directory resolves outside the intended agents directory when mkdir() processes it.

The current script does not implement the command-line argument parsing advertised in the documentation, which limits direct expl ...[truncated 1419 chars]

Remediation
View remediation

Remediation Suggestions

  1. Restrict agent identifiers to a conservative allowlist, for example ^[A-Za-z0-9_-]{1,64}$.

  2. Reject absolute paths, path separators, . components, and .. components.

  3. Resolve the candidate path and verify containment before any filesystem operation:

    python
    base = self.agent_dir.resolve()
    candidate = (base / agent_id).resolve()
    if candidate.parent != base:
        raise ValueError("Invalid agent identifier")
    
  4. Keep filesystem directory names separate from externally supplied display identifiers; use generated UUIDs for storage paths.

  5. Add tests for ../, absolute paths, encoded separators, long identifiers, Unicode separator variants, and symlink-based containment bypasses.

  6. Ensure every future agent-specific read and write repeats the containment check rather than relying only on registration-time validation.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:19
Finding

Installation Uses Unpinned and Unused Third-Party Dependencies

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 19-26; README.md, lines 33-36
Vulnerability Type: Mutable dependency resolution and unnecessary supply-chain exposure
Risk Level: Medium

Vulnerable Code

yaml
install:
  - id: pip
    kind: pip
    package: lancedb
    label: "Install LanceDB"
  - id: pip2
    kind: pip
    package: numpy
    label: "Install NumPy"
bash
# Install through ClawHub
clawhub install multi-agent-memory

# Or install manually
npx clawhub@latest install multi-agent-memory

Technical Analysis

The Python packages are specified without exact versions or integrity hashes, and the documented npm command explicitly selects the mutable latest release. An installation performed at a later date can therefore resolve to different code than the version reviewed during this audit.

Neither lancedb nor numpy is imported by the supplied scripts, making their installation unnecessary for the implementation currently shipped. Every unnecessary dependency expands the number of maintainers, package releases, transitive dependencies, and installation behaviors that must be trusted.

No evidence was found that the named packages are currently malicious. The vulnerability is the unsafe and non-reproducible dependency policy, not a claim that these specific packages are compromised.

Attack Path

  1. A user follows the documented installation process.
  2. The package manager resolves lancedb, numpy, or clawhub@latest at installation time.
  3. A compromised, malicious, or unexpectedly changed future release is selected.
  4. Package installation or runtime import executes code with the installing user's privileges.
  5. That code can access resources available to the installation process.

Impact Assessment

If an upstream package or account is compromised, malicious installation code could obtain the same privileges as the user running ...[truncated 236 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove lancedb and numpy until the implementation actually requires them.
  2. Pin every dependency to a reviewed exact version.
  3. Use lockfiles and hash verification, such as pip requirements with --hash.
  4. Replace clawhub@latest with an explicitly reviewed version.
  5. Document supported dependency versions and a controlled upgrade process.
  6. Review transitive dependencies and package lifecycle scripts before release.
  7. Run dependency installation in a constrained environment with minimal filesystem and credential access.
  8. Add automated software-composition analysis and dependency integrity checks to the release process.

T07 · Tool Hijacking and Spoofing

Warning
Location
public/dashboard.html:108
Finding

Dashboard and Retrieval Components Present Fabricated Results as Operational Data

Content
View full analysis

Vulnerability Details

File Location: public/dashboard.html, lines 108-123; scripts/rrf-search.py, lines 109-134
Vulnerability Type: Tool output spoofing and misleading operational telemetry
Risk Level: Medium

Vulnerable Code

javascript
function updateDashboard() {
    const totalMemories = Math.floor(Math.random() * 100) + 1200;
    document.getElementById('totalMemories').textContent = totalMemories.toLocaleString();
    
    const accuracy = (Math.random() * 5 + 90).toFixed(1);
    document.getElementById('retrievalAccuracy').textContent = accuracy + '%';
    
    const cost = (Math.random() * 20 + 120).toFixed(1);
    document.getElementById('tokenCost').textContent = '¥' + cost;
    
    const triggers = Math.floor(Math.random() * 50) + 300;
    document.getElementById('hookTriggers').textContent = triggers;
    
    const resolution = (Math.random() * 3 + 94).toFixed(1);
    document.getElementById('conflictResolution').textContent = resolution + '%';
    
    document.getElementById('updateTime').textContent = new Date().toLocaleString('zh-CN');
}
python
def _bm25_search(self, query):
    """BM25 search simulation"""
    return [
        ("doc1", 0.95),
        ("doc2", 0.85),
        ("doc3", 0.75)
    ]

def _vector_search(self, query):
    """Vector search simulation"""
    return [
        ("doc1", 0.92),
        ("doc4", 0.88),
        ("doc2", 0.82)
    ]

def _graph_search(self, query):
    """Graph search simulation"""
    return [
        ("doc1", 0.90),
        ("doc5", 0.80),
        ("doc3", 0.70)
    ]

Technical Analysis

The dashboard describes itself as a real-time monitoring interface, but its memory count, retrieval accuracy, token cost, hook count, and conflict-resolution rate are randomly generated. The retrieval class similarly ignores the supplied query and returns fixed document identifiers and ...[truncated 1542 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace random dashboard values with data loaded from authenticated, measured local reports.
  2. Clearly label all demonstration values as synthetic and disable them in production mode.
  3. Display an explicit “data unavailable” state instead of generating plausible fallback values.
  4. Implement actual BM25, vector, and graph retrieval or rename the component as a simulation.
  5. Validate that retrieval results vary appropriately with the query and are derived from configured memory sources.
  6. Include data provenance and collection timestamps for every dashboard metric.
  7. Add integration tests comparing displayed values with source log and graph files.
  8. Remove unsupported claims such as real-time monitoring and measured accuracy until reproducible benchmarks exist.
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (49)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 136)May include surrounding context.

环境变量

bash
# .env
MEMORY_WORKSPACE=/path/to/workspace
MEMORY_VECTOR_MODEL=nomic-embed-text-v1.5
MEMORY_LLM_API_KEY=your-api-key

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 162)May include surrounding context.

环境变量

bash
# .env
MEMORY_WORKSPACE=/path/to/workspace
MEMORY_VECTOR_MODEL=nomic-embed-text-v1.5
MEMORY_LLM_API_KEY=your-api-key

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description overclaims major capabilities while the analyzed content primarily shows wrappers that invoke external scripts and adds agent lifecycle management not clearly reflected in the primary purpose. This mismatch is dangerous because users and reviewers may approve or run the skill under false assumptions about what it does, especially where automation, scaling, persistence, and shell execution are involved.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description overclaims major capabilities while the analyzed content primarily shows wrappers that invoke external scripts and adds agent lifecycle management not clearly reflected in the primary purpose. This mismatch is dangerous because users and reviewers may approve or run the skill under false assumptions about what it does, especially where automation, scaling, persistence, and shell execution are involved.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description overclaims major capabilities while the analyzed content primarily shows wrappers that invoke external scripts and adds agent lifecycle management not clearly reflected in the primary purpose. This mismatch is dangerous because users and reviewers may approve or run the skill under false assumptions about what it does, especially where automation, scaling, persistence, and shell execution are involved.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill description overclaims major capabilities while the analyzed content primarily shows wrappers that invoke external scripts and adds agent lifecycle management not clearly reflected in the primary purpose. This mismatch is dangerous because users and reviewers may approve or run the skill under false assumptions about what it does, especially where automation, scaling, persistence, and shell execution are involved.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description overclaims major capabilities while the analyzed content primarily shows wrappers that invoke external scripts and adds agent lifecycle management not clearly reflected in the primary purpose. This mismatch is dangerous because users and reviewers may approve or run the skill under false assumptions about what it does, especially where automation, scaling, persistence, and shell execution are involved.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill description overclaims major capabilities while the analyzed content primarily shows wrappers that invoke external scripts and adds agent lifecycle management not clearly reflected in the primary purpose. This mismatch is dangerous because users and reviewers may approve or run the skill under false assumptions about what it does, especially where automation, scaling, persistence, and shell execution are involved.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill description overclaims major capabilities while the analyzed content primarily shows wrappers that invoke external scripts and adds agent lifecycle management not clearly reflected in the primary purpose. This mismatch is dangerous because users and reviewers may approve or run the skill under false assumptions about what it does, especially where automation, scaling, persistence, and shell execution are involved.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language instructions and section headings are entirely in Chinese, with no indication that the skill supports other languages or that Chinese is a deliberate region-specific requirement. This effectively forces a specific language without user opt-in, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README advertises automatic capture, knowledge graphing, contradiction detection, and token tracking, but provides no notice about what data is collected, retained, or exposed. In a multi-agent memory system, silent capture can include prompts, tool outputs, secrets, and user content, creating privacy, compliance, and data leakage risks.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The README instructs users to execute npx clawhub@latest install multi-agent-memory, which fetches and runs remote package code without a fixed version. This creates a supply-chain risk: if the package or a dependency is compromised or changes unexpectedly, users may execute unreviewed code during installation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill advertises and invokes capabilities that imply shell execution, file access, environment-variable use, and package installation, but it does not declare any explicit tool scope or permission boundaries. That makes the operational trust boundary unclear and increases the risk of over-broad execution in hosts that rely on manifest-declared permissions for safe review and enforcement.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill promotes automatic capture and Git snapshot management but does not warn that user prompts, project files, or other sensitive workspace data may be collected and persisted. In a memory system, silent retention is especially risky because the core function is data accumulation, making accidental capture of secrets, proprietary code, or personal data more likely.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

Using npx clawhub@latest pulls and executes whatever package version is current at install time, which creates a supply-chain and reproducibility risk. If the upstream package is compromised or a breaking version is published, users may execute unreviewed code during installation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation instructs users to configure an API key but does not explain whether content may be transmitted to external LLM or embedding services or how the key should be protected. This can lead to unsafe credential handling and unintentional exfiltration of sensitive memory contents to third-party services.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This YAML file contains a Chinese-only natural-language comment ('多Agent记忆系统配置'). Under the policy, locale-specific language is a finding when the skill appears to force a specific language without user opt-in or documented justification, and no such justification is present in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module docstring and all user-facing console messages are written exclusively in Chinese, with no indication that language is configurable or optional. This creates a natural-language locale constraint without user opt-in, which matches the policy-violation category for language or locale restrictions.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The page presents itself as a real-time health monitoring dashboard, but the values are generated with Math.random() entirely on the client side. This can mislead operators into trusting fabricated system status, causing missed incidents, incorrect operational decisions, or false assurance about memory, retrieval accuracy, token cost, and conflict resolution health.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes a multi-agent memory system focused on automatic capture, RRF retrieval, knowledge graphs, contradiction detection, and token tracking. This file instead provides agent registration, discovery, health monitoring, and automatic scale up/down behavior, which are agent orchestration capabilities rather than memory functionality.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code file contains natural-language descriptions and runtime messages that force a specific language/locale for users and operators. Under the policy, language-specific behavior should either offer user opt-in/choice or clearly justify the locale constraint, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring is written entirely in Chinese and provides no indication that users may choose another language or locale. Under the policy for natural-language violations, forcing a specific language without opt-in should be flagged unless the locale restriction is clearly documented and justified, which it is not here.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The header documentation says the script integrates conflict detection into the memory lifecycle and 'automatically resolves conflicts'. In code, resolve_conflicts() only annotates conflict records in conflicts.json, and for llm_judge content conflicts it explicitly leaves them unresolved as '待人工审核'; it also never edits the memory files themselves.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The configuration and conflict records label content-conflict handling as llm_judge, implying model-based adjudication. However, the script contains no LLM invocation, network call, subprocess, or local model logic; resolve_conflicts() instead marks those conflicts as unresolved and pending human review.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code file contains natural-language documentation and runtime messages in a single forced language, including the module docstring and printed status output. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.