Back to skill

Security audit

Morgana Anti Infinite Loop V2 Zh

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent anti-loop guard, but it asks hosts to inject user-derived action text as system messages and persists raw loop actions locally without enough controls.

Review before installing in any tool-enabled or sensitive agent. Prefer pause or hard_kill mode, or modify heal mode so untrusted action/intent text is passed as quoted lower-privilege context, not a system message. Also disable or redirect LoopDNA storage where possible and avoid feeding secrets, private prompts, or raw tool arguments into observe().

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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)

T01 · Skill Instruction Hijacking

Warning
Location
anti_loop/core.py:250
Finding

Untrusted Agent Content Is Promoted into Privileged System Messages

Content
View full analysis
Dict[str, Any]: """Returns a healing directive based on mode.""" self.heal_count += 1 if self.mode == HealingMode.HARD_KILL: return { "action": "abort", "message": f"Loop detected (kill #{self.heal_count}): {last_action[:80]}", "should_continue": False, } if self.mode == HealingMode.PAUSE: return { "action": "pause", "duration_seconds": self.pause_seconds, "message": f"Loop detected, pausing {self.pause_seconds}s", "should_continue": True, } # Default: HEAL import random template = random.choice(self.HEAL_TEMPLATES) # Extract a "topic" from last action topic = last_action[:50] if last_action else "current action" return { "action": "heal", "system_message": template.format( topic=topic, intent=intent or "(no intent recorded)", last_action=last_action[:100], ), "should_continue": True, "heal_count": self.heal_count, } ``` The documented integration explicitly injects this result into the system-message context: ```python if result["directive"]["action"] == "heal": inject_system_message(result["directive"]["syst ...[truncated 2185 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
anti_loop/core.py:423
Finding

Raw Agent Actions Are Persisted in Plaintext with Ambient File Permissions

Content
View full analysis
Dict[str, Dict]: if self.storage_path.exists(): try: with open(self.storage_path) as f: return json.load(f) except Exception: return {} return {} def _save(self): with open(self.storage_path, 'w') as f: json.dump(self.known_loops, f, indent=2) def fingerprint(self, actions: List[str]) -> str: """Compute SHA-256 of a loop signature.""" canonical = json.dumps(sorted(actions), sort_keys=True) return hashlib.sha256(canonical.encode()).hexdigest() def record(self, actions: List[str], resolution: str = "healed"): """Store a new loop fingerprint.""" fp = self.fingerprint(actions) self.known_loops[fp] = { "actions_sample": actions[:3], "actions_count": len(actions), "first_seen": datetime.now().isoformat(), "resolution": resolution, "occurrences": 1, } self._save() ``` The persistent write is reached from loop handling: ```python if should_intervene: directive = self.healer.inject(action, self.last_intent) # Record DNA if loop_type or is_known: self.dna.record([action], resolution=directive["action"]) ``` ### Technical Analysis The feature is presented as SHA-256 “Loop DNA,” which implies that only fingerprints need to be retained. However, `record()` also writes `actions_sample` containing the original action strings. Agent actions may contain: - User prompts or person ...[truncated 1834 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (34)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation mentions optional upload of anonymized loop DNA to ClawHub, but it gives no concrete privacy warning, consent UX, transport/security details, or explanation of what leaves the machine. Because loop records may be derived from user actions, prompts, or internal workflows, network transmission could leak sensitive operational information despite being labeled anonymous.

Content

No source excerpt is available for this finding.

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · anti_loop/core.py (reported line 633)May include surrounding context.

python
}
    
    def reset(self):
        """Reset state between sessions."""
        self.iteration = 0
        self.entropy = PredictiveEntropy(threshold=0.3)
        self.novelty = NoveltyDetector()

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file title marks the skill as a Chinese edition and the content is entirely in Chinese, ending with a statement that it is built for the Chinese community. Under the policy criteria, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly justified; this README does not offer a language choice or explain a compliance-driven need.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill documents functionality that writes persistent data to disk (~/.anti_loop/loops.json) but does not declare any tool scope, permissions, or storage behavior in metadata. In agent ecosystems, undeclared write capability weakens operator consent and sandbox policy enforcement, making it easier for a skill to modify the local environment unexpectedly.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest explicitly sets language: "zh-CN", which indicates the skill is intended to operate in a fixed language/locale. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is clearly justified as region-specific, which is not stated here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill states that loop history is stored persistently in ~/.anti_loop/loops.json across sessions, but it does not present a clear upfront warning, consent flow, or data-minimization guidance. Even if the stored content is framed as loop fingerprints, action sequences and resolutions can still encode sensitive prompts, workflow details, or user data, creating privacy and forensic exposure on disk.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation claims known loop DNA leads to an instant kill, but the decision logic only records known-loop status and does not intervene on that basis alone. This security-behavior mismatch can cause operators to overtrust the guard and fail open in situations where they expect deterministic blocking of previously seen loops.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill persists loop data to ~/.anti_loop/loops.json even though it presents itself as a lightweight loop guard. Cross-session storage creates an undisclosed local data retention channel that may capture sensitive agent activity patterns and can surprise users who expect in-memory-only behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Persistent local storage occurs silently, with no user-facing warning, consent, or disclosure. In an agent setting, hidden persistence can retain sensitive workflow traces and violates reasonable expectations for a utility marketed as lightweight and zero-dependency.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code stores samples of agent actions across sessions in actions_sample, which can include prompts, tool arguments, secrets, or user data. Retaining raw action content is broader than necessary for loop detection and increases privacy and data-exposure risk if the local file is accessed by other processes or users.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The natural-language description says the target audience is "EXTERNAL USERS (dev solo, startup, chercheur)" and the surrounding documentation is written partly in French, indicating a locale/language constraint without offering user choice. Under the policy, forcing a specific language or locale without opt-in is a violation unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module docstring is written in French and does not indicate that language selection is optional or tied to a justified region-specific requirement. Under the policy rule, forcing a specific language without user opt-in is a natural-language locale violation.

Content

No source excerpt is available for this finding.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · examples/02_pre_flight_regex.py (reported line 12)May include surrounding context.

python
def looks_like_a_loop(plan: str) -> bool:
    """Detect: does this plan look like it could loop forever?"""
    guard = AntiLoop()
    issues = guard.pre_flight(plan)
    return len(issues) > 0

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · examples/02_pre_flight_regex.py.auto.md (reported line 26)May include surrounding context.

md
def looks_like_a_loop(plan: str) -> bool:
    """Detect: does this plan look like it could loop forever?"""
    guard = AntiLoop()
    issues = guard.pre_flight(plan)
    return len(issues) > 0

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code file contains natural-language documentation primarily in French, which can impose a language preference on users or maintainers without any opt-in or explanation. The policy requires flagging language or locale constraints when they are forced rather than optional or justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This file is a markdown wrapper around code content, and the embedded natural-language docstring includes key descriptive text in French (for example, 'Wrappers stdlib...' and 'pour minimiser les dépendances') without indicating that another language is available. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The file's user-facing documentation and healing templates are written in French, including strings returned to downstream agents, without offering a language choice or documenting a justified locale restriction. This can violate language/locale policy when the skill is intended for external users but silently enforces a specific language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The HEAL_TEMPLATES are hard-coded in French and are injected as system messages during intervention. Because these strings directly affect agent behavior and no locale opt-in or alternative language path is provided, the skill imposes a specific language policy by default.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · anti_loop/core.py (reported line 518)May include surrounding context.

python
"""Generic adapter: try common attributes."""
        for attr in ['content', 'text', 'message', 'output', 'result']:
            if hasattr(response, attr):
                return str(getattr(response, attr))
        return str(response)

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The manifest emphasizes a lightweight guard built on the standard library with optional numpy, suggesting runtime loop detection and intervention. The documented LoopDNA feature goes beyond in-memory guarding by persisting behavioral fingerprints to ~/.anti_loop/loops.json, which is a broader stateful behavior not clearly conveyed in the high-level manifest description.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

A loop guard is expected to observe and classify agent behavior, but documented wrappers for Anthropic, OpenAI, LangChain, AutoGen, Hermes, and custom harnesses introduce integration surface area beyond the narrowly stated guarding function. While not inherently unsafe, this is a broader capability than the manifest's lightweight protector framing makes explicit.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The docstring text is written in French and does not offer any language choice or explain a region-specific requirement. This creates a natural-language locale policy issue because the skill content implicitly assumes a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
tests/test_zero_dep.py:20