Back to skill

Security audit

pensieve-algorand

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly does what it says, but its recovery validation can overstate whether data is truly recoverable from the blockchain.

Install only if you are comfortable running a local MCP server with access to a dedicated Algorand wallet mnemonic, an AES encryption key, and your OpenClaw memory files. Use a low-balance wallet, isolate the workspace and secrets, pin dependencies yourself, and do not treat ok=true validation as proof of disaster recovery unless the tool is changed to require confirmed on-chain retrieval.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
server.py:217
Finding

Validation Can Falsely Certify Blockchain Recoverability Using a Local Ciphertext Cache

Content
View full analysis
str: from algosdk.transaction import PaymentTxn sp = client.suggested_params() txn = PaymentTxn(sender=sender, sp=sp, receiver=sender, amt=0, note=note) return client.send_transaction(txn.sign(sk)) # ── Note fetch (shared by validate + recover) ───────────────────────────────── def _get_note(row: dict, idx=None) -> str: """Fetch note from blockchain (preferred) or local note_b64 cache (fallback).""" txid = row.get("txid") if txid: try: client = idx if idx is not None else _indexer() tx = client.transaction(txid) note = tx.get("transaction", {}).get("note") if note: return note except Exception: pass note_local = row.get("note_b64") if note_local: return note_local raise ValueError(f"No note available for txid={txid!r}") ``` The single-transaction anchoring path immediately records the locally generated ciphertext after submission: ```python enc = _encrypt(single_bytes, note_key) if len(enc) > 1024: raise RuntimeError(f"Encrypted note {len(enc)} > 1024 bytes — reduce payload") txid = _send_tx(client, addr, sk, enc) _append_jsonl(anchors_path, { "ts": now_ts, "date": date_key, "txid": txid, "ledger_tip": ledger_tip, "entries": entries, "root_hash": base_meta["root_hash"], "content_hash": content_hash, "multi_tx": False, "note_b64": base64.b64encode(enc).decode("ascii"), "status": "anchored", }) ``` The same behavior occurs for every part of a multi-transaction anchor: ```python enc = _encrypt(payload_bytes, not ...[truncated 3556 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Security-Critical Python Dependencies Are Installed Without Version or Integrity Pinning

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (14)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill exposes capabilities involving environment-variable access and filesystem read/write behavior but does not declare an explicit tool scope such as permissions or allowed-tools. In practice, this increases the chance that a host agent grants broader access than intended, which is especially sensitive here because the documented environment contains wallet mnemonics and encryption keys and the server manages append-only memory files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The architecture explicitly states that the daily anchored payload includes full memory content (events, semantic, procedural, and self_model) and that this enables disaster recovery from the blockchain plus keys, but it does not pair that design with a clear user-facing warning about the sensitivity and persistence of this data flow. Even though the payload is encrypted with AES-GCM, storing comprehensive long-term memory snapshots in blockchain notes creates elevated confidentiality and lifecycle risk because ciphertext is durably published, may later become decryptable if keys are exposed, and users may not realize their private memory corpus is being externally anchored.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The runbook explicitly instructs users to call pensieve_recover(..., restore=True), which writes recovered files into memory/recovered/, but it does not present a prominent warning that this operation modifies the filesystem. In an agent/tooling context, omission of a clear write-side effect warning can lead to unintended file creation, overwrites, or unsafe execution by users or higher-level automation that assumes the command is read-only.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

Set restrictive permissions on the .secrets/ directory:

bash
chmod 700 <workspace>/.secrets
chmod 600 <workspace>/.secrets/*

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

bash
chmod 700 <workspace>/.secrets
chmod 600 <workspace>/.secrets/*

Never commit .secrets/ to version control.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The recovery path writes deterministic filenames like memory/recovered/recovered.jsonl using mode 'w', which will silently replace any existing recovered file for that date. An operator could lose prior recovered data, annotations, or forensic evidence if recovery is rerun, especially because this tool manages long-term memory and disaster recovery artifacts.

Content

No source excerpt is available for this finding.

Rp1

Low
Category
MCP Rug Pull
Confidence
87% confidence
Finding

The installation instructions use an unpinned dependency (pip install mcp), which makes builds non-reproducible and exposes users to supply-chain risk if a future package release is malicious or introduces breaking security changes. Because this is an MCP server handling sensitive secrets and local files, even a low-probability dependency compromise could affect confidentiality and integrity.

Content

No source excerpt is available for this finding.

Rp1

Low
Category
MCP Rug Pull
Confidence
60% confidence
Finding

pip install without ==version installs the latest release, which could include malicious changes.

Content

No source excerpt is available for this finding.

Rp1

Low
Category
MCP Rug Pull
Confidence
60% confidence
Finding

pip install without ==version installs the latest release, which could include malicious changes.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency list leaves mcp unpinned, so builds may resolve to different versions over time, including vulnerable or breaking releases. In a security-sensitive memory/anchoring skill that depends on an MCP server, this increases supply-chain risk and makes it impossible to verify whether known advisories affecting mcp are avoided.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
mcp
algosdk
cryptography

Unverifiable Dependency: mcp has 12 known advisory(ies) (CVE-2025-53366 (MCP Python SDK vulnerability in the FastMCP Server causes validation error, lead); CVE-2025-66416 (Model Context Protocol (MCP) Python SDK does not enable DNS rebinding protection); CVE-2026-52870 (MCP Python SDK: Experimental task handlers allow any client to access and cancel) +9 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The manifest does not specify which mcp version is intended, while the package has multiple known advisories. Given this skill is explicitly a single MCP server, the dependency is central to the attack surface, so an unpinned mcp could result in deployment of a release with server-side validation, DNS rebinding, or task-access flaws.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

algosdk is unpinned, which makes installations non-reproducible and exposes the skill to unexpected upstream changes or compromised releases. Because this package is used for blockchain anchoring, a bad update could affect transaction handling, key usage, or integrity guarantees central to the skill's purpose.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
mcp
algosdk
cryptography

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

Leaving cryptography unpinned is risky because it is a foundational security dependency and known issues may exist in some versions. In a skill claiming AES-GCM encryption and recoverability validation, relying on an unspecified cryptography version undermines confidence in the confidentiality and integrity controls and may silently introduce vulnerable OpenSSL-linked wheels.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
mcp
algosdk
cryptography

Unverifiable Dependency: cryptography has 16 known advisory(ies) (GHSA-39hc-v87j-747x (Vulnerable OpenSSL included in cryptography wheels); CVE-2023-50782 (Python Cryptography package vulnerable to Bleichenbacher timing oracle attack); GHSA-537c-gmf6-5ccf (Vulnerable OpenSSL included in cryptography wheels) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
98% confidence
Finding

cryptography has known advisories, but the requirements file does not constrain the version, so there is no assurance the installed package includes the necessary fixes. Because this skill advertises AES-GCM encrypted anchoring, any vulnerable cryptographic library version materially increases the risk of weakened confidentiality, integrity, or side-channel exposure.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.