Back to skill

Security audit

Claw Recall

Security checks for vulnerabilities and agentic risk

Overview

The skill is a memory search tool, but it documents broad searchable access to private conversations and external sources without enough scoping or remote-access safeguards.

Review carefully before installing. This skill is intended to make private agent transcripts and external sources searchable, including across agents, so only use it with data sources you are comfortable centralizing. Prefer a pinned release or reviewed commit, isolate it in a virtual environment, avoid exposing the SSE endpoint directly, keep keyword-only mode unless external embedding processing is acceptable, and do not index secrets, regulated data, or high-sensitivity accounts without explicit controls.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:41
Finding
Mutable Remote Code Is Retrieved and Executed Without Version Pinning<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:41-45` **Vulnerability Type**: Remote code retrieval and supply-chain exposure **Risk Level**: High ### Vulnerable Code ```bash git clone https://github.com/rodbland2021/claw-recall.git cd claw-recall pip install -r requirements.txt python3 -m claw_recall.indexing.indexer --source ~/.openclaw/agents-archive/ --incremental ``` ### Technical Analysis The installation procedure clones the mutable default branch of an external Git repository and immediately installs its dependencies and executes one of its Python modules. It does not pin a reviewed commit, signed tag, package version, or dependency hashes. Consequently, the code executed by a user can differ from the code that was reviewed during this audit. The referenced `requirements.txt` is also outside the supplied project, so its packages, versions, package indexes, and build-time behavior could not be verified. This most directly represents remote payload retrieval and execution. The unverified requirements file also creates a secondary dependency supply-chain risk. ### Attack Path 1. An attacker compromises the referenced repository, a maintainer account, or a dependency used by its `requirements.txt`. 2. The attacker adds malicious Python code or package installation behavior to the mutable upstream source. 3. A user follows the documented installation commands. 4. `pip install` executes malicious package build or installation logic, or the subsequent `python3 -m` command executes the modified module. 5. The payload runs with the privileges of the installing user and can access that user's files, environment variables, agent archives, and configured credentials. ### Impact Assessment Successful exploitation provides arbitrary code execution under the installing user's account. The accessible scope may include OpenClaw conversation archives, agent configuration files, API keys in the environment, the local memory database, and any othe ...[truncated 114 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin the repository to a specific reviewed commit or cryptographically signed release tag. - Publish and verify checksums or signatures for release artifacts. - Replace the unconstrained requirements file with a lockfile containing exact versions and cryptographic hashes. - Install with hash verification, such as `pip install --require-hashes`. - Use a dedicated virtual environment or container with minimal filesystem and network permissions. - Review dependency installation hooks and transitive dependencies before installation. - Avoid executing the indexer until the downloaded source and dependencies have been independently verified. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:31
Finding
Cross-Agent Search Breaks Least-Privilege Boundaries for Sensitive Records<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:31-35`, `SKILL.md:98-112`, `SKILL.md:143-149` **Vulnerability Type**: Insufficient authorization and data isolation **Risk Level**: High ### Vulnerable Documentation ```markdown - **Post-compaction recovery**: Get the full transcript from before compaction wiped your context - **Cross-agent search**: Any agent can search any other agent's conversations - **Unified search**: Conversations, captured thoughts, Gmail, Google Drive, and Slack in one query - **Hybrid search**: Keyword (FTS5) + semantic (OpenAI embeddings) with automatic detection - **Self-hosted**: Your data stays on your machine. No cloud, no subscription, no vendor lock-in. ``` The documented tools expose both broad searches and complete recent transcripts: ```markdown **`search_memory`** — The main search tool. Searches ALL sources in one call: conversations, captured thoughts (Gmail, Drive, Slack), and markdown files. search_memory query="what did we decide about the API" [agent=butler] [days=7] **`browse_recent`** — Full transcript of the last N minutes. The go-to tool for context recovery after compaction. browse_recent [agent=kit] [minutes=30] Returns the complete conversation with timestamps. Use this FIRST after any context reset. ``` ### Technical Analysis The design intentionally centralizes complete transcripts and data from Gmail, Google Drive, Slack, and Markdown files. It explicitly states that any agent can search another agent's conversations. The supplied documentation does not describe caller authentication, per-agent access-control lists, tenant isolation, consent controls, secret filtering, result redaction, or authorization checks on the optional `agent` parameter. A query filter is not an access-control boundary unless the server independently restricts which values each caller may use. Because the server implementation was not included, it is not possible to verify whether undocumented controls exist. N ...[truncated 1322 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Authenticate every MCP client and associate it with a specific user, agent, and security role. - Enforce server-side authorization for every record returned by `search_memory`, `browse_recent`, and related tools. - Default searches to records owned by the authenticated caller. - Require explicit, revocable grants before permitting cross-agent or cross-source access. - Treat the `agent` argument only as a query filter after authorization has been evaluated. - Separate databases or encryption keys for agents that operate across different trust boundaries. - Detect and redact credentials, tokens, and other secrets before indexing. - Provide configurable retention, deletion, and source-level consent controls. - Encrypt the database at rest and maintain tamper-resistant access logs. - Add tests proving that one agent cannot retrieve another agent's records without an explicit grant. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:82
Finding
Remote SSE Deployment Uses Plaintext HTTP Without Documented Authentication<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:82-92` **Vulnerability Type**: Insecure remote service configuration **Risk Level**: High ### Vulnerable Code ```markdown ### Remote agents (SSE) Start the SSE server on the Claw Recall machine, then connect from anywhere: ```bash python3 -m claw_recall.api.mcp_sse ``` ```bash claude mcp add --transport sse -s user claw-recall "http://your-server:8766/sse" ``` ``` ### Technical Analysis The remote deployment procedure uses plaintext HTTP and states that agents can connect “from anywhere.” It does not document TLS, client authentication, authorization, a safe bind address, firewall restrictions, a VPN, or a reverse proxy. Plaintext HTTP does not provide transport confidentiality or server authenticity. If the endpoint is reachable over an untrusted network, MCP requests and responses may be observed or modified in transit. If the server lacks authentication, an unauthenticated client may also be able to invoke memory tools directly. The server implementation was not supplied, so its actual bind address and authentication defaults could not be confirmed. The confirmed issue is that the documented deployment path does not establish a secure remote configuration. ### Attack Path 1. An operator starts the SSE server using the documented command. 2. Port `8766` is exposed to a LAN, public network, container network, or cloud security group. 3. An attacker discovers the endpoint or intercepts plaintext traffic. 4. If authentication is absent, the attacker connects directly and invokes available MCP tools. 5. Alternatively, a network-positioned attacker reads or modifies plaintext searches and responses. 6. Sensitive indexed conversations or external-source records are disclosed or manipulated through exposed tool operations. ### Impact Assessment The potential impact includes unauthorized invocation of memory-search tools, disclosure of complete conversation transcripts, exposure of Gmail/Driv ...[truncated 290 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Bind the SSE service to `127.0.0.1` by default. - Do not expose port `8766` directly to untrusted networks. - Place the service behind an authenticated TLS reverse proxy, mutually authenticated TLS endpoint, or trusted VPN. - Require strong per-client credentials and rotate them regularly. - Apply the same per-agent authorization controls to remote and local clients. - Validate the expected `Host` and origin information where applicable. - Add rate limiting, request-size limits, security logging, and connection timeouts. - Document firewall and cloud security-group requirements. - Replace the example HTTP URL with an HTTPS endpoint and provide a complete hardened deployment example. ]]>

other

Warning
Location
SKILL.md:35
Finding
Local-Only Privacy Claim Conflicts With External OpenAI Embedding Use<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:35`, `SKILL.md:149-155` **Vulnerability Type**: Privacy disclosure inconsistency **Risk Level**: Medium ### Conflicting Documentation The Skill makes the following categorical local-storage claim: ```markdown - **Self-hosted**: Your data stays on your machine. No cloud, no subscription, no vendor lock-in. ``` It later documents external embedding functionality: ```markdown All data is stored locally in a SQLite database. Keyword search uses FTS5 (zero API keys). Semantic search uses OpenAI embeddings (requires `OPENAI_API_KEY` in `.env`). ## Requirements - Python 3.10+ - SQLite 3.35+ (bundled with Python) - OpenAI API key (optional, only for semantic search) ``` ### Technical Analysis Semantic embeddings supplied by OpenAI normally require sending text to an external service. The Skill indexes conversations and can ingest Gmail, Google Drive, Slack, and Markdown content, so embedding generation may involve sensitive material. The statement that data stays on the user's machine is therefore incomplete or potentially misleading when semantic search is enabled. The external implementation was not supplied, so the exact fields transmitted, preprocessing behavior, retention settings, and provider endpoint cannot be confirmed. ### Attack Path 1. A user relies on the claim that all data remains on the local machine. 2. The user configures `OPENAI_API_KEY` and enables or triggers semantic search. 3. The implementation submits transcript content, captured content, or search text to the external embedding provider. 4. Sensitive information leaves the local trust boundary without the user having received a clear disclosure of what is transmitted. 5. The data becomes subject to the external provider's processing, retention, logging, and jurisdictional controls. ### Impact Assessment Potentially exposed information includes agent conversations, user queries, captured thoughts, email content, Drive ...[truncated 344 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace the categorical local-only claim with an explicit statement that semantic search may transmit content to an external embedding provider. - Clearly identify every field sent externally, including document text, transcript excerpts, metadata, and user queries. - Require explicit opt-in consent before enabling external embeddings. - Keep keyword-only search as the default mode. - Display a warning before processing Gmail, Drive, Slack, or conversation data through an external service. - Redact credentials and sensitive fields before embedding generation. - Document the provider's retention, logging, regional-processing, and deletion behavior. - Offer a verified local embedding backend for users who require fully offline processing. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (1)

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill prominently advertises indexing and unified search across conversation transcripts, Gmail, Google Drive, and Slack, but does not provide a strong, explicit warning about the sensitivity, scope, and privacy implications of ingesting those data sources. This can cause users to enable the skill without appreciating that highly sensitive messages, documents, and cross-agent conversations may become locally searchable and broadly accessible to any connected agent, increasing the risk of unintended disclosure.

Static analysis

No suspicious patterns detected.