Back to skill

Security audit

MOCI — Memory-bound OpenClaw Identity

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed agent identity and memory skill, but it needs Review because key security promises are contradicted by its reference implementation and it creates persistent local identity state.

Install only if you are comfortable with a skill that creates long-lived local identity and memory files under ~/.openclaw and may update them on a schedule. Do not rely on this version for production trust, provenance, or identity recovery until the caller-token authentication, encrypted export, import validation, nonce replay handling, and recovery-phrase guidance are fixed. Keep passphrases and recovery phrases out of chat, logs, shared files, and diagnostics.

Vulnerability Patterns
  • 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
  • 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
references/moci.ts:345
Finding

Unsigned Caller Tokens Allow Unauthorized Memory Writes

Content
View full analysis
300_000) throw new Error("Expired"); return p as CallerToken; } catch { throw new Error("Invalid caller token"); } } // --- Memory Write (FIX #14, #12) --- interface WriteResult { success: boolean; seq?: number; error?: string; } async function addMemory( identity: MociIdentity, content: string, source: string, callerToken: string, hmacKey: string ): Promise { let caller: CallerToken; try { caller = verifyCallerToken(callerToken); } catch (e) { return { success: false, error: `Auth: ${(e as Error).message}` }; } if (!ALLOWED_WRITERS.includes(caller.callerId)) return { success: false, error: `Writer not allowed: ${caller.callerId}` }; ``` ### Technical Analysis `verifyCallerToken()` only Base64-decodes and parses caller-controlled JSON. It does not verify a digital signature, message authentication code, trusted issuer, audience, or single-use nonce. Consequently, the `callerId` used by the writer allowlist is not authenticated. A caller can select an authorized value such as `gateway`, `heartbeat`, or `skill:moci`. The timestamp check is also incomplete: a future `issuedAt` value produces a negative age and remains valid because only tokens older than five minutes are rejected. This directly contradicts the authenticated write-gate described in `references/memory-security.md`. Base64 is an encoding format and provides no authenticity or integrity. ### Attack Path 1. The attacker constructs a JSON object such as: ```json { "callerId": "skill:moci", "issuedAt": 4102444800000, "nonce": "attacker-controlled" ...[truncated 1076 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
references/moci.ts:512
Finding

Export Function Returns Plaintext Identity Data Under an Encrypted Filename

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
references/moci.ts:522
Finding

Identity Import Accepts Fabricated State Without Integrity Verification

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
references/moci.ts:681
Finding

CIT Replay Protection Is Optional and Absent from the Documented Integration

Content
View full analysis
CIT_MAX_NONCE_CACHE) { const first = options.seenNonces.values().next().value; if (first) options.seenNonces.delete(first); } } ``` The documented usage omits the nonce store: ```js const identity = await verifyCIT( req.headers["x-moci-token"], req.headers["x-moci-sig"], { mySkillId: "skill:weather", verifyKey: VERIFY_KEY } ); ``` ### Technical Analysis Nonce validation only executes when `options.seenNonces` is supplied. If it is omitted, a correctly signed token can be reused without restriction until its expiration time. The integration example in `SKILL.md` omits `seenNonces`, making the insecure mode the documented default. This conflicts with the specification's assertion that nonce reuse is rejected. The 60–300 second token lifetime limits but does not eliminate replay. During that window, an intercepted token and signature can authorize repeated requests. An in-memory `Set` also provides weak protection across process restarts, multiple workers, or distributed instances. ### Attack Path 1. The attacker captures a valid `X-MOCI-Token` and `X-MOCI-Sig` pair from logs, local IPC, a compromised intermediary, or another request-observation point. 2. The target skill verifies CITs using the documented options, without `seenNonces`. 3. The attacker submits the captured pair to the same `skill_target`. 4. Signature, target, and expiry checks pass. 5. Because no nonce store was supplied, replay detection is skipped. 6. The attacker repeats the request until the token exp ...[truncated 571 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (16)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
→ Best for: HashiCorp Vault, AWS Secrets Manager, any external secret store
   → Also works: "pass show moci", "op read op://vault/moci/pass"

3. System keychain (if available, auto-detected):
   → macOS: security CLI (built-in, no install)
   → Windows: wincred via native API (built-in, no install)
   → Linux desktop: libsecret / gnome-keyring / kwallet (present on GNOME/KDE)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/memory-security.md (reported line 284)May include surrounding context.

md
→ Best for: HashiCorp Vault, AWS Secrets Manager, any external secret store
   → Also works: "pass show moci", "op read op://vault/moci/pass"

3. System keychain (if available, auto-detected):
   → macOS: security CLI (built-in, no install)
   → Windows: wincred via native API (built-in, no install)
   → Linux desktop: libsecret / gnome-keyring / kwallet (present on GNOME/KDE)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/memory-security.md (reported line 287)May include surrounding context.

md
3. System keychain (if available, auto-detected):
   → macOS: security CLI (built-in, no install)
   → Windows: wincred via native API (built-in, no install)
   → Linux desktop: libsecret / gnome-keyring / kwallet (present on GNOME/KDE)
   → Linux headless / Docker / WSL / cloud: skipped silently

4. Interactive prompt:     "Enter passphrase: ********"

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation criteria are extremely broad and overlap with many identity, trust, auth, provenance, and compliance topics. That can cause the skill to trigger in contexts where sensitive identity operations are unnecessary, increasing the chance of exposing secrets, performing risky actions, or confusing users into credential-related flows unintentionally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The export/import section handles highly sensitive materials such as encrypted identity packages, passphrases, and recovery phrases, but does not lead with a strong user-facing warning about irreversibility, theft risk, and approved handling practices. In a credential-management skill, weak upfront safety messaging materially raises the likelihood of secret disclosure, unsafe storage, or social-engineering success.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation is internally inconsistent: it states the system will never ask for the recovery phrase, but the import flow says the user may provide a mnemonic. In an identity/credential-management skill, contradictory guidance increases phishing and operator-error risk because users may be trained to ignore a core anti-social-engineering rule.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
This skill supports these operations when invoked:

- `generate` — Create a new MOCI (with optional name input)
- `validate` — Check if a MOCI string is well-formed (CRC check)
- `verify` — Full dual-factor verification (key + memory chain)
- `verify-cit` — Verify a MOCI Identity Token from another skill

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% 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 · SKILL.md (reported line 800)May include surrounding context.

md
| Field | Default | Purpose |
|-------|---------|---------|
| `identity_file` | `~/.openclaw/moci-identity.enc` | Encrypted identity + memory store |
| `auto_promote` | `true` | Automatically run ring promotion on schedule |
| `promote_schedule` | `0 4 * * *` | Cron expression for ring promotion (4am daily) |
| `trust_score_enabled` | `false` | Compute and expose trust score in ACP metadata |
| `acp_provenance` | `off` | ACP Provenance mode: `off`, `meta`, `meta+receipt` |

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
# Agent A — has its own MOCI
shared:
  - path: ~/.openclaw/shared/pipeline
    access: readwrite

# Agent B — different MOCI, same shared path
shared:

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The write-gate example allows gateway and heartbeat writers in addition to skill:moci (L007-L015), while the summary later says 'WHO CANNOT write? → The agent itself, other skills, external callers' (L499). As written, the documentation presents a broader set of authorized writers than the summary implies, creating an intent-level contradiction about who may modify the memory chain.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/memory-security.md (reported line 110)May include surrounding context.

  1. Compare promotion_counter with breadcrumb file → If file counter < breadcrumb counter → ROLLBACK DETECTED
  2. Verify all Ring 0/1/2 entry HMACs → Invalid HMAC → entry was modified after write
text

#### 3d. Anti-Rollback: Breadcrumb File

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file states in L297-L298 that every step uses only Node.js built-in modules or system commands already present. However, the documented passphrase_command examples at L280-L282 include tools such as pass and op, which are third-party utilities and not inherently built-in or already present. This is an active contradiction between the prose and the described implementation approach.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The function is named and documented as keccak256 but actually uses SHA-256 via crypto.subtle.digest. In an identity and provenance system, algorithm confusion can break interoperability, invalidate assumptions made by other components, and cause mismatched identifiers, signatures, or verification outcomes if peers expect Keccak-256 semantics.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code persists a device salt and derives a fingerprint from hostname, homedir, platform, arch, and MOCI ID, creating a stable host-linked secret without explicit user consent. In an identity system, this can reduce portability, enable unwanted device correlation, and tie identities to environmental attributes beyond the stated lifecycle purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The implementation reads host-specific data and writes a persistent salt file under the user's home directory with no in-code warning, prompt, or disclosure path. Even if intended for local security, silently collecting and persisting host signals in an agent identity skill creates privacy and consent risks because users may not expect identity creation to inspect and bind system characteristics.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The TOFU key-pinning logic silently creates and persists a pin file on first use. While common in some security models, undisclosed persistence can surprise users and may lock trust onto a malicious key if the first contact is intercepted, making later validation failures confusing rather than protective.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.