T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/memory_summarizer.py:863- Finding
Arbitrary Local File Read, Persistent Archival, and External Transmission
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
DeepRecall has a coherent memory purpose, but it stores raw session memory permanently and has under-scoped paths that can read, transmit, or delete more local data than users would reasonably expect.
Review this skill carefully before installing. Use it only for memory content you are comfortable storing long term, set no_store_raw or store_raw_content false where possible, avoid scheduling automatic jobs until retention and provider settings are understood, and do not process arbitrary file paths. Prefer an explicit trusted provider or local-only extraction, and keep sensitive secrets, credentials, private keys, and regulated data out of memory files.
scripts/memory_summarizer.py:863Arbitrary Local File Read, Persistent Archival, and External Transmission
scripts/memory_summarizer.py:233Sensitive Agent Memory Sent to an Unrestricted Automatically Selected Endpoint
scripts/memory_retriever.py:489Cleanup Command Can Delete Markdown Files Outside the Agent Workspace
scripts/memory_retriever.py:90Unencrypted Permanent Storage of Complete Session Memory Without Retention Controls
requirements.txt:3Unpinned Network-Facing Runtime Dependency
The skill explicitly states that exact raw session content is stored permanently and that records are never deleted. Indefinite retention of verbatim user content materially increases the chance of long-term exposure of secrets, personal data, proprietary information, and prompt history through later retrieval, compromise, or misuse.
This code transmits complete memory content to an external LLM provider for processing, and the prompt explicitly solicits user profile, identity, project, and technical information. In the context of a memory system, that content is especially likely to contain sensitive disclosures, credentials, internal architecture notes, or personal data, making third-party exfiltration a serious confidentiality risk.
The guide documents configuration that sends content to third-party LLM providers but does not clearly warn users that their data may leave the local environment. In a memory/summarization feature, users may reasonably include sensitive notes or workspace content, so omission of a transmission warning creates a real privacy and compliance risk even if the document is otherwise instructional.
The documented default store_raw_content: true means original user content is retained, but the guide does not clearly warn about persistence, retention scope, or privacy implications. Retaining raw content can increase exposure of secrets, personal data, and internal documents if storage is later accessed, backed up, or exfiltrated.
The skill instructs automatic tool registration and broad future-use retrieval for prior work, decisions, people, preferences, and todos, effectively enabling persistent cross-session memory by default. This widens the blast radius of any sensitive data captured once, because future interactions may surface it without fresh user intent or contextual authorization.
The skill documents permanent storage of raw session content and the use of an external LLM for summarization, but it does not present a clear, prominent privacy warning or require informed user consent before either action. This creates a real risk that sensitive prompts, notes, credentials, or personal data are retained indefinitely and potentially disclosed to third-party model providers.
Describing the database as a permanent vault for all extracted knowledge promotes indefinite accumulation of user-derived information and normalizes over-retention. Even without an exploit chain in the markdown itself, this design encourages broad preservation and later resurfacing of sensitive context beyond the original purpose of collection.
Self-initializing persistent storage is not inherently unsafe, but in this skill it materially supports silent, durable session persistence without explicit setup or user review. In the context of a memory system that stores raw content and facts across sessions, automatic database creation lowers friction for broad retention and increases the chance of unnoticed data accumulation.
## Self-Bootstrapping Design
DeepRecall features zero-config deployment:
- Tables are created automatically on first use (`CREATE TABLE IF NOT EXISTS`)
- No "no such table" errors - database self-initializes
- Indexes are created for optimal query performance
- Works out-of-the-box with no manual setup
The manifest auto-registers several tools, including data retrieval and cleanup operations, without any explicit trigger boundaries, consent requirements, or examples of when they must not be invoked. In an agent setting, ambiguous tool scope can lead to unintended access to stored memory or accidental destructive actions such as cleanup being invoked without a clearly scoped user request.
The module docstring presents this file as a memory retrieval engine focused on searching and retrieving content. In practice, constructing MemoryRetriever bootstraps the database schema, creates directories, creates triggers/indexes, and other functions mark files as processed and delete raw files, which are active write/delete side effects rather than retrieval-only behavior.
L1 retrieval returns content in full with no truncation or output-size controls, and L2 retrieval also returns complete raw content. In an agent environment, this can leak excessive sensitive memory contents into model context, logs, or downstream tools and can also cause denial-of-service-like token bloat when large records are retrieved.
clean_type = fact_type
# Compact format: [date | type | source:file] content
# Note: no truncation is applied; content is returned in full
line = f"[{date} | {clean_type} | source:{source_file}] {content}"
formatted.append(line)
The cleanup function claims to operate only on workspace memory files, but it accepts an arbitrary memory_dir and then deletes matching .md files in that directory. In an agent/tool context, any caller able to influence memory_dir can turn a maintenance helper into a generic file-deletion primitive against accessible paths, causing unintended data loss.
The function deletes files automatically once retention or size thresholds are met, with no interactive confirmation or user-visible warning at execution time. In an autonomous agent setting, silent destructive behavior increases the chance of accidental or policy-bypassing data loss, especially if invoked with unexpected parameters or against the wrong directory.
The tool stores full raw memory files in the archive database by default, creating long-term retention of potentially sensitive information beyond what may be necessary for fact extraction. Persistent storage increases blast radius if the SQLite database is accessed by other local users, included in backups, or later exfiltrated.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
print("Warning: No LLM API configuration found, using rule-based extraction")
return await self._extract_facts_with_rules(content)
base_url = api_config.get("baseUrl", "https://api.deepseek.com/v1")
# Remove trailing slash to avoid double slashes in URL concatenation
if base_url.endswith('/'):
base_url = base_url.rstrip('/')
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
print("Warning: No LLM API configuration found, using rule-based extraction")
return await self._extract_facts_with_rules(content)
base_url = api_config.get("baseUrl", "https://api.deepseek.com/v1")
# Remove trailing slash to avoid double slashes in URL concatenation
if base_url.endswith('/'):
base_url = base_url.rstrip('/')
The code sends raw memory content to a configured external LLM endpoint during normal processing, but there is no explicit user consent or warning at the point of transmission. Because the prompt explicitly targets personal, project, and technical facts, users may unknowingly export sensitive material to third-party providers.
The statement "All content in English for international compatibility" imposes a language policy rather than offering a user choice. This is a natural-language policy violation because it forces a specific language without opt-in or documented necessity.
Allowing an empty query to return the latest facts creates a permissive default that may disclose memory contents even when the user did not ask for retrieval with sufficient specificity. Because this skill is a persistent memory system, broad default recall increases the chance of unintended exposure of prior session data or sensitive stored facts.
The dependency is specified with a minimum version only, which allows installation of any later release and makes builds non-reproducible. This increases supply-chain risk because different environments may resolve to different versions, including ones with breaking changes or known vulnerabilities.
# DeepRecall Dependencies
# Required for LLM summarization functionality
aiohttp>=3.8.0
# SQLite3 is included in Python standard library
# No additional dependencies needed for core memory retrieval functions
Because aiohttp is not pinned, it is impossible to verify from this manifest whether the installed version is one affected by known advisories. In a skill that performs LLM summarization over networked components, using a vulnerable HTTP client library could expose the system to issues such as request handling flaws, injection, cookie handling weaknesses, or denial of service depending on the resolved version.
The function unlinks .md.processed marker files automatically when their corresponding source files are absent. This is another file-deletion path with no confirmation or explicit user-facing notification at execution time.
The code labels the prompt template as an English version and uses fixed English instructions for analysis. This imposes a specific language choice in natural-language behavior without any user opt-in or documented justification for the locale constraint.
The --test-config help text says it will "Test OpenClaw configuration and API connectivity," which implies an active network connectivity check. However, when invoked, the code only calls test_configuration(), and that function reads config files and reports provider/model selection details without making any API request.
No suspicious patterns detected.