Back to skill

Security audit

Anima Aios

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent memory and agent-growth skill, but it under-discloses remote LLM data flow and performs broad persistent local memory processing.

Install only if you are comfortable with persistent local indexing of OpenClaw memory/session data. Keep `team_mode` disabled unless cross-agent ranking is intended, avoid configuring remote LLM endpoints unless memory prompts may leave the machine, use private storage paths, and do not follow the `chmod -R 755` repair guidance on sensitive memory or config directories.

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

T09 · Insecure Skill Coding Practices

Error
Location
core/distill_engine.py:118
Finding

Undisclosed transmission of Agent memory to external LLM endpoints

Content
View full analysis
str: base_url = self.config.get("base_url") api_key = ( self.config.get("api_key") or os.getenv("ANIMA_LLM_API_KEY") or os.getenv("OPENAI_API_KEY") or os.getenv("DASHSCOPE_API_KEY") ) if not base_url or not api_key: return "" model = ( self.config.get("models", {}).get(task) or self.config.get("default_model", "") ) import urllib.request import json as _json url = f"{base_url.rstrip('/')}/chat/completions" payload = _json.dumps({ "model": model, "messages": [{"role": "user", "content": prompt}], "max_tokens": max_tokens, "temperature": 0.3 }).encode("utf-8") req = urllib.request.Request(url, data=payload, headers={ "Content-Type": "application/json", "Authorization": f"Bearer {api_key}" }) try: with urllib.request.urlopen(req, timeout=60) as resp: data = _json.loads(resp.read().decode("utf-8")) return data.get("choices", [{}])[0].get( "message", {} ).get("content", "").strip() except Exception as e: logger.warning(f"Direct API call failed: {e}") return "" ``` The fallback channel also submits the complete prompt to the OpenClaw Agent: ```python def _call_openclaw(self, prompt: str) -> str: try: cmd = ["openclaw", "agent", "--message", prompt] if self._agent_name: cmd.extend(["--agent", self._a ...[truncated 3605 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
post-install.sh:30
Finding

Post-install script silently installs an optional dependency without a fixed version or hashes

Content
View full analysis
=3.0.0" 2>/dev/null || pip install -q "watchdog>=3.0.0" 2>/dev/null || echo "watchdog installation failed; memory monitoring will use polling mode" echo "Python dependency check completed" ``` The Skill documentation presents this package as optional: ```markdown pip install watchdog # Optional: enable automatic memory monitoring ``` ### Technical Analysis The post-install script automatically contacts the configured Python package index and installs the newest release satisfying `watchdog>=3.0.0`. This is an open-ended version constraint rather than a reviewed, reproducible dependency specification. The installation also suppresses standard error and uses quiet mode, reducing the visibility of: - The selected package version. - The package source or index. - Dependency-resolution warnings. - TLS or certificate warnings. - Installation failures and fallback behavior. Python package installation may execute build backends or package installation logic with the privileges of the user running the Skill installer. Consequently, a compromised future release, malicious package index, or unsafe index configuration could introduce code that was not present during the Skill audit. The dependency is described as optional but is installed automatically, so the installer performs more network and package-management activity than the minimum installation flow requires. ### Attack Path 1. The user invokes `post-install.sh`. 2. Pip queries the user's configured package index or mirror. 3. The resolver selects any future version matching `watchdog>=3.0.0`. 4. A compromised release, malicious mirror, or manipulated index supplies an unsafe distri ...[truncated 741 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
anima_doctor.py:551
Finding

Permission repair guidance makes private Agent data readable by other local users

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
core/fact_store.py:128
Finding

Unsanitized Agent and fact identifiers allow storage path traversal

Content
View full analysis
str: target_dir = self._get_dir(fact.fact_type) filepath = target_dir / f"{fact.fact_id}.md" filepath.write_text( fact.to_markdown(), encoding="utf-8" ) logger.debug( f"Writing fact: {fact.fact_id} ({fact.fact_type})" ) return str(filepath) def read( self, fact_id: str, fact_type: FactType ) -> Optional[Fact]: target_dir = self._get_dir(fact_type) filepath = target_dir / f"{fact_id}.md" if not filepath.exists(): ...[truncated 2594 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (136)

Tainted flow: 'req' from os.getenv (line 139, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The engine sends memory-derived prompt content to a configurable external endpoint using credentials partly sourced from environment variables, with no allowlist or trust validation on the destination. In this skill context, the transmitted data contains episodic and semantic memory content, so a malicious or misconfigured base_url can exfiltrate sensitive internal data and API secrets to an attacker-controlled service.

Content

Scanner excerpt · core/distill_engine.py (reported line 145)May include surrounding context.

python
})
        
        try:
            with urllib.request.urlopen(req, timeout=60) as resp:
                data = _json.loads(resp.read().decode("utf-8"))
                return data.get("choices", [{}])[0].get("message", {}).get("content", "").strip()
        except Exception as e:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file title and all user-facing instructions are written in Chinese, and there is no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking or region-specific context. Under the policy, a fixed language without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation states that all data processing is local with no network requests, yet other sections describe optional LLM-based classification, deduplication, and quality assessment using configurable providers. This contradiction can mislead users into enabling the skill under false privacy assumptions, resulting in unexpected transmission of memory or cognitive-profile data to external LLM services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill advertises silent automatic scanning of a .learnings/ directory from another tool and extraction of high-value records, but the notice does not clearly present this as a privacy-sensitive local data access feature requiring explicit user consent. Silent discovery and ingestion of data from adjacent tooling increases the risk of collecting sensitive material users did not intend this skill to process.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The team ranking feature is presented as auto-scanning all agents' cognitive profiles and generating shared leaderboard files, but this section omits the privacy constraint that such cross-agent access should remain disabled by default and explicitly consented to. In a multi-agent shared filesystem, this can normalize unnecessary lateral data access and expose behavioral or profile data of other agents/users.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The Chinese section claims the scripts perform only local operations with no network calls, while nearby configuration and feature descriptions allow LLM API usage through providers such as OpenAI or other external services. This inconsistency creates a real privacy and transparency issue because users relying on the Chinese documentation may unknowingly expose local memory data to remote APIs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest’s user-facing environment variable descriptions and defaults are written in Chinese only, such as lines L14, L19, and L24-L25. This imposes a specific language/locale in natural-language metadata without any opt-in, alternative language, or documented region-specific justification.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The top-level documentation presents the tool as only performing self-check and self-repair, but the implementation also supports bulk memory synchronization and cross-agent profile generation. This mismatch can mislead operators into invoking a tool with broader data-processing side effects than advertised, reducing informed consent and increasing the chance of unintended writes or data propagation.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · anima_doctor.py (reported line 220)May include surrounding context.

python
self.checks = {}
        self.fixes = []
    
    def diagnose(self, auto_fix=False, auto_confirm=False):
        """
        自检 Anima 状态

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · anima_doctor.py (reported line 226)May include surrounding context.

python
self.checks = {}
        self.fixes = []
    
    def diagnose(self, auto_fix=False, auto_confirm=False):
        """
        自检 Anima 状态

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · anima_doctor.py (reported line 253)May include surrounding context.

python
self.checks = {}
        self.fixes = []
    
    def diagnose(self, auto_fix=False, auto_confirm=False):
        """
        自检 Anima 状态

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · anima_doctor.py (reported line 789)May include surrounding context.

python
self.checks = {}
        self.fixes = []
    
    def diagnose(self, auto_fix=False, auto_confirm=False):
        """
        自检 Anima 状态

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The recover() path is described as repairing detected local Anima issues, but it unconditionally attempts _generate_all_profiles(), which iterates across all agent directories under FACTS_BASE. That broad side effect exceeds the apparent repair scope and can modify data for unrelated agents without a diagnosis-driven need.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

sync_memory_to_facts() performs bulk file creation by reading all memory markdown files and writing generated fact files without an interactive confirmation, dry-run preview, or explicit warning about the number and destination of writes. In an agent skill context, that can cause unexpected mass persistence of user content and filesystem changes from a single command.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The synchronization feature copies free-form memory content into new fact files in plain text, along with metadata, potentially duplicating sensitive user or agent data into additional storage locations. This increases data exposure, retention footprint, and the chance that secrets or private notes are propagated into less controlled directories.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The function automatically persists supplied memory content to disk and also triggers EXP/quest side effects, but the interface does not clearly warn the user that content will be stored locally. This is a privacy and consent issue: sensitive user data may be written unexpectedly into workspace files. In a memory-management skill, silent persistence is especially risky because users may provide personal or confidential information.

Content

No source excerpt is available for this finding.

Tainted flow: 'memory_file' from os.getenv (line 361, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
92% confidence
Finding

The file write target is derived from WORKSPACE, which itself can be influenced by the ANIMA_WORKSPACE environment variable. That means an attacker who can control the runtime environment can redirect memory writes to an arbitrary filesystem location writable by the process, causing unintended file creation or modification. In this skill, the risk is amplified because the function persists user-provided content automatically.

Content

Scanner excerpt · anima_tools.py (reported line 281)May include surrounding context.

python
# 追加写入
    timestamp = datetime.now().strftime("%H:%M")
    with open(memory_file, "a", encoding="utf-8") as f:
        f.write(f"\n- [{timestamp}] {content} #{type}\n")
        if tags:
            f.write(f"  标签:{', '.join(tags)}\n")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code creates structured fact files containing content, timestamps, author identity, tags, and derived metadata, but there is no clear user-facing disclosure that these artifacts will be written to disk. That increases privacy and retention risk because the stored material is more detailed and searchable than a transient operation. The context makes it more dangerous because the feature explicitly builds a persistent knowledge base.

Content

No source excerpt is available for this finding.

Tainted flow: 'quest_file' from os.getenv (line 831, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
90% confidence
Finding

The quest file path ultimately depends on FACTS_BASE and agent_name, both of which are influenced by environment/configuration and user-controlled identifiers. Without path validation, the code can be steered to write JSON files outside the intended quest storage area, enabling arbitrary file overwrite within the process's permissions. Because this function writes structured data automatically, it can be abused without additional confirmation.

Content

Scanner excerpt · anima_tools.py (reported line 814)May include surrounding context.

python
def _save_quests(quests: List[Dict], quest_file: Path):
    """保存任务"""
    quest_file.parent.mkdir(parents=True, exist_ok=True)
    with open(quest_file, "w", encoding="utf-8") as f:
        json.dump(quests, f, ensure_ascii=False, indent=2)

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The team-ranking feature enumerates other agent directories and reads their EXP history, expanding the skill from self-oriented memory/profile management into cross-agent data access. If exposed to users who should only access their own data, this leaks metadata about other agents' activity and progression without clear authorization checks. The documented purpose does not justify that broader read scope.

Content

No source excerpt is available for this finding.

Tainted flow: 'log_file' from os.getenv (line 1124, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
87% confidence
Finding

The error log path is built from WORKSPACE, which can come from an environment variable. If an attacker can influence that value, they can redirect log writes to arbitrary writable files or locations, potentially clobbering files or planting attacker-controlled content in sensitive paths. Even though this is 'just logging,' it is still a filesystem write primitive.

Content

Scanner excerpt · anima_tools.py (reported line 1126)May include surrounding context.

python
try:
        log_file = WORKSPACE / "anima_exp_errors.log"
        timestamp = datetime.now().isoformat()
        with open(log_file, "a", encoding="utf-8") as f:
            f.write(f"[{timestamp}] EXP 记录失败 - Agent: {agent_name}, 错误:{error}\n")
    except (IOError, OSError, PermissionError) as e:
        # 日志写入失败,静默处理(避免无限递归)

Tainted flow: 'exp_file' from os.getenv (line 587, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
90% confidence
Finding

The fallback EXP history file is written under WORKSPACE, which can be attacker-influenced via environment variables. This creates another arbitrary-write sink where attacker-controlled execution context can redirect writes to unintended files, and the JSON content includes fields influenced by inputs such as agent_name and details. In a skill that runs automatically, this is a meaningful integrity risk.

Content

Scanner excerpt · anima_tools.py (reported line 1164)May include surrounding context.

python
}
    
    try:
        with open(exp_file, "a", encoding="utf-8") as f:
            f.write(json.dumps(record, ensure_ascii=False) + "\n")
    except (IOError, OSError, PermissionError) as e:
        # 文件写入失败,记录到错误日志

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This Python file contains natural-language documentation and printed output entirely in Chinese, including the module docstring and runtime messages. Under the policy, forcing a specific language without user opt-in is a locale-policy violation unless the constraint is explicitly documented and justified, 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
97% confidence
Finding

This Python file contains natural-language documentation entirely in Chinese, and its runtime test output strings are also Chinese-only. The policy requires flagging language or locale constraints when a skill forces a specific language without user opt-in, and this file does not offer any language selection or explain a justified region-specific requirement.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The top-level module docstring presents operational documentation exclusively in Chinese, and the function docstrings/comments continue that pattern. Per the policy, forcing a specific language without user opt-in is a natural-language policy concern unless the locale restriction is explicitly justified, which it is not here.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.