Back to skill

Security audit

ChronoSync

Security checks for vulnerabilities and agentic risk

Overview

The skill is locally focused and mostly does what it advertises, but it needs Review because it broadly copies private chat history into persistent shared files and runs plugins over that data without strong scoping or storage protections.

Install only if you intentionally want all OpenClaw sessions copied into shared local memory files. Keep the output directory private, review any files under plugins before running, avoid syncing sessions that may contain secrets, and remember that the redaction is best-effort and may miss credentials or confidential text. I found no remote download, network exfiltration, destructive action, or privilege escalation in the inspected artifacts.

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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
session_sync.py:73
Finding
Incomplete redaction exposes sensitive cross-session chat content in persistent shared storage<![CDATA[ ## Vulnerability Details **File Location**: `session_sync.py:73-78`, `session_sync.py:269-302` **Vulnerability Type**: Incomplete sensitive-data sanitization and plaintext data persistence **Risk Level**: Medium ### Vulnerable Code ```python # Sensitive information sanitization patterns SENSITIVE_PATTERNS = [ (r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', '[EMAIL]'), (r'\b\d{11}\b', '[PHONE]'), (r'\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b', '[CARD]'), (r'\b[A-Za-z0-9]{32,}\b', '[TOKEN]'), ] ``` ```python def parse_messages(self, content: str) -> List[Dict]: """Parse message content""" messages = [] for line in content.strip().split('\n'): line = line.strip() if not line: continue try: msg = json.loads(line) # Sanitize content msg_content = msg.get("content", "") msg_content = sanitize_content(msg_content) messages.append({ "role": msg.get("role", "unknown"), "content": msg_content, "timestamp": msg.get("timestamp", "") }) except json.JSONDecodeError: continue return messages def sync_session(self, session_id: str) -> bool: """Synchronize one session""" content = self.get_session_content(session_id) if not content: return False # Check for changes if not self.detector.has_changed(session_id, content): return False # Parse messages messages = self.parse_messages(content) if not messages: return False # Build session data session_data = { "id": session_id, "timestamp": datetime.now().isoformat(), "hash": self.detector.calculate_hash(content), "message_count": len(messages), "messages": messages[-50:] } # Write files self.file_manager.append_json(session_data) self.file_manager.append_markdown(session_data) ``` ## ...[truncated 2455 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Expand secret detection to cover well-known API-token prefixes, bearer credentials, authorization headers, password assignments, JWTs, private keys, and tokens containing punctuation. 2. Allow administrators to define application-specific deny patterns. 3. Prefer allowlisted message fields and structured secret metadata over relying exclusively on regular expressions. 4. Provide per-session opt-in or exclusion controls before copying data into cross-session storage. 5. Minimize retained content and consider storing summaries rather than complete message bodies. 6. Encrypt sensitive output at rest where cross-session plaintext access is unnecessary. 7. Clearly document that redaction is best-effort and cannot guarantee removal of every secret. 8. Add tests for private keys, JWTs, bearer tokens, prefixed API keys, hyphenated tokens, passwords, and confidential non-credential data. 9. Ensure plugins receive only the minimum sanitized data required for their operation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
session_sync.py:140
Finding
Sensitive chat and memory files are created without explicit restrictive permissions or symlink protection<![CDATA[ ## Vulnerability Details **File Location**: `session_sync.py:140-194`, `plugins/knowledge.py:115-132`, `plugins/todo.py:144-171` **Vulnerability Type**: Insecure permissions and unsafe predictable-file handling **Risk Level**: Medium ### Vulnerable Code ```python def ensure_dirs(self): """Ensure directories exist""" try: self.output_dir.mkdir(parents=True, exist_ok=True) (self.output_dir / "decisions").mkdir(exist_ok=True) (self.output_dir / "todos").mkdir(exist_ok=True) except OSError as e: print(f"[Session Sync] Failed to create directory: {e}") raise ``` ```python try: with open(self.json_file, 'w', encoding='utf-8') as f: json.dump(data, f, indent=2, ensure_ascii=False) except IOError as e: print(f"[Session Sync] Failed to write JSON: {e}") ``` ```python try: with open(self.md_file, 'a', encoding='utf-8') as f: f.write(md_content) except IOError as e: print(f"[Session Sync] Failed to write Markdown: {e}") ``` The plugins use the same unrestricted file-opening model: ```python with open(file_path, 'a', encoding='utf-8') as f: for d in decisions: f.write(f"\n## {d['timestamp']}\n\n") f.write(f"**Source:** {d['role']}\n\n") f.write(f"{d['content']}\n\n") f.write("---\n") ``` ```python def _save_todos(self, todos: List[Dict]): """Save tasks""" with open(self.todos_file, 'w', encoding='utf-8') as f: json.dump(todos, f, indent=2, ensure_ascii=False) ``` ### Technical Analysis The Skill writes aggregated chat history, extracted decisions, technical notes, and todo records using the process's default filesystem permissions. It does not explicitly create directories with mode `0700` or files with mode `0600`, and it does not validate file ownership. The output names are predictable, and ordinary `open()` calls follow symbolic links. The implementation does not reject symlinks, use `O_NOFOLLOW`, verify that existin ...[truncated 1861 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create the synchronization directory and all child directories with mode `0700`. 2. Create sensitive output files with mode `0600`, and explicitly correct overly permissive modes on existing files after confirming ownership. 3. Reject symbolic links and non-regular files before reading or writing. 4. On supported platforms, open files with `os.open()` using `O_NOFOLLOW`, `O_CREAT`, and restrictive creation modes. 5. Use atomic writes through a temporary file created securely in the same protected directory, followed by `os.replace()`. 6. Verify that existing directories and files are owned by the current user before using them. 7. Warn or refuse to run when a custom output directory is group-writable, world-writable, or owned by a different user. 8. Apply the same controls consistently to the hash file, shared chat files, decision notes, technical notes, and todo files. 9. Add automated tests that run under permissive umasks and test pre-created symbolic links. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
plugins/knowledge.py:49
Finding
Plugin outputs ignore the configured secure output directory and create undisclosed duplicate data<![CDATA[ ## Vulnerability Details **File Location**: `session_sync.py:51`, `plugins/knowledge.py:49-52`, `plugins/todo.py:48-52` **Vulnerability Type**: Inconsistent security configuration and unintended sensitive-data duplication **Risk Level**: Low ### Vulnerable Code The core synchronization engine honors `SESSION_SYNC_OUTPUT`: ```python OPENCLAW_DIR = get_openclaw_dir() OUTPUT_DIR = Path(os.environ.get( "SESSION_SYNC_OUTPUT", OPENCLAW_DIR / "workspace" / "memory" / "sync" )) ``` The knowledge plugin ignores that setting: ```python def __init__(self): # Obtain location from environment or use the default openclaw_dir = Path(os.environ.get( "OPENCLAW_STATE_DIR", Path.home() / ".openclaw" )) self.output_dir = ( openclaw_dir / "workspace" / "memory" / "sync" / "decisions" ) self.output_dir.mkdir(parents=True, exist_ok=True) ``` The todo plugin also ignores it: ```python def __init__(self): # Obtain location from environment or use the default openclaw_dir = Path(os.environ.get( "OPENCLAW_STATE_DIR", Path.home() / ".openclaw" )) self.output_dir = ( openclaw_dir / "workspace" / "memory" / "sync" / "todos" ) self.output_dir.mkdir(parents=True, exist_ok=True) self.todos_file = self.output_dir / "active.json" ``` ### Technical Analysis The documented `SESSION_SYNC_OUTPUT` setting changes the destination used by the core `FileManager`, but both built-in plugins independently construct output paths under the OpenClaw state directory. As a result, configuring a custom output directory does not relocate all synchronized information. Extracted decisions, technical notes, and todo content continue to be persisted under the default memory tree. This violates the expected security boundary of a centralized output configuration and can leave unexpected copies in a less-protected or differently managed location. ### Attack Path 1. A user sets `SESSION_SYNC_O ...[truncated 1094 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define one canonical output-directory resolver shared by the core engine and all plugins. 2. Pass the resolved output directory into plugin constructors instead of allowing each plugin to reconstruct it. 3. Store knowledge output under `OUTPUT_DIR / "decisions"` and todo output under `OUTPUT_DIR / "todos"`. 4. Document every generated file and ensure the documentation reflects custom-output behavior. 5. On upgrade, detect old plugin output locations and offer a safe migration or cleanup process. 6. Add integration tests asserting that no files are created beneath the default directory when `SESSION_SYNC_OUTPUT` is set. 7. Apply the same restrictive permissions and symlink protections to plugin output paths as to the primary output files. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (37)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Dynamic loading and execution of local plugin code, plus writing derived artifacts into additional directories, materially expands the attack surface beyond simple backup/sync. In a skill that processes private conversations, executing plugin hooks on session content can enable unauthorized data access, transformation, or persistence, especially if plugin trust boundaries are undocumented.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Dynamic loading and execution of local plugin code, plus writing derived artifacts into additional directories, materially expands the attack surface beyond simple backup/sync. In a skill that processes private conversations, executing plugin hooks on session content can enable unauthorized data access, transformation, or persistence, especially if plugin trust boundaries are undocumented.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
Dynamic loading and execution of local plugin code, plus writing derived artifacts into additional directories, materially expands the attack surface beyond simple backup/sync. In a skill that processes private conversations, executing plugin hooks on session content can enable unauthorized data access, transformation, or persistence, especially if plugin trust boundaries are undocumented.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Dynamic loading and execution of local plugin code, plus writing derived artifacts into additional directories, materially expands the attack surface beyond simple backup/sync. In a skill that processes private conversations, executing plugin hooks on session content can enable unauthorized data access, transformation, or persistence, especially if plugin trust boundaries are undocumented.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Dynamic loading and execution of local plugin code, plus writing derived artifacts into additional directories, materially expands the attack surface beyond simple backup/sync. In a skill that processes private conversations, executing plugin hooks on session content can enable unauthorized data access, transformation, or persistence, especially if plugin trust boundaries are undocumented.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Dynamic loading and execution of local plugin code, plus writing derived artifacts into additional directories, materially expands the attack surface beyond simple backup/sync. In a skill that processes private conversations, executing plugin hooks on session content can enable unauthorized data access, transformation, or persistence, especially if plugin trust boundaries are undocumented.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
Dynamic loading and execution of local plugin code, plus writing derived artifacts into additional directories, materially expands the attack surface beyond simple backup/sync. In a skill that processes private conversations, executing plugin hooks on session content can enable unauthorized data access, transformation, or persistence, especially if plugin trust boundaries are undocumented.

Ssd 3

High
Confidence
97% confidence
Finding
The skill explicitly promotes aggregating chat histories from separate sessions into shared files to enable cross-session access. This breaks session isolation and can leak sensitive user data, secrets, and context from one conversation into another, even if done locally and without network access.

Ssd 3

High
Confidence
98% confidence
Finding
The examples normalize reading and revealing content from another session's records in plain language, directly encouraging disclosure across conversation boundaries. In a chat system, this undermines privacy expectations and can expose confidential user inputs, credentials, or sensitive operational data to the wrong context or user.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The manifest describes a tool that automatically backs up OpenClaw chat records across sessions to preserve and share context. This file instead filters message content for decision and technical-note patterns and writes only selected excerpts into separate markdown knowledge files, which is a different purpose than syncing or backing up chat history.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The plugin’s documented behavior and implementation are materially different from the skill manifest: it extracts todo-like statements and stores them as cross-session memory rather than synchronizing chat records. This kind of capability mismatch is dangerous because users and reviewers may grant the skill broader trust based on the manifest while sensitive user intent is silently transformed and retained in a different form.

Description-Behavior Mismatch

High
Confidence
95% confidence
Finding
The code persists derived todo state to JSON and Markdown files instead of backing up or syncing full chat records as advertised. This undisclosed divergence increases privacy and trust risk because user messages are being mined for actionable memory artifacts and written to disk under the guise of a different feature.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The plugin loader dynamically imports and executes every Python file in the local plugins directory via exec_module, then calls plugin.on_sync on chat-derived data. This extends the skill from passive session synchronization into arbitrary code execution with the user's privileges, which is far beyond the declared purpose and creates a strong code-execution and data-exfiltration surface.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The design explicitly promotes silent periodic syncing and '无感运行' while persisting cross-session chat history, but it does not mention user consent, visibility, retention limits, or privacy notices. In a chat-memory skill, silently capturing and storing conversation content can expose sensitive prompts, credentials, personal data, or confidential project information without the user's awareness.

Ssd 3

Medium
Confidence
95% confidence
Finding
The design calls for silent cross-session capture and shared storage of conversation data, which changes ephemeral chat into durable shared memory without any stated access boundaries or data minimization. Because the skill's purpose is to aggregate context across sessions, it is especially likely to collect sensitive user content from unrelated conversations and make it available more broadly than intended.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The file format examples show full session messages being written to JSON and Markdown on disk, including human-readable transcripts, with no safeguards described for secrets, personal data, or access control. Persisting verbatim chat logs materially increases the blast radius of any local compromise, accidental sharing, backup leakage, or multi-user system exposure.

Ssd 3

Medium
Confidence
96% confidence
Finding
The Markdown example includes verbatim '用户' and 'AI' messages in a human-readable synchronized record, which makes accidental disclosure easier through editors, screenshots, git commits, backups, or shared folders. Human-readable transcript storage is particularly risky because it lowers the barrier to casual access compared with a more restricted internal format.

Lp3

Medium
Category
MCP Least Privilege
Confidence
75% confidence
Finding
The skill requests or implies capabilities to read environment variables and read/write files, but the manifest does not declare any explicit tool scope or permissions. This weakens reviewability and least-privilege controls, making it easier for a skill that handles sensitive chat data to access more than users expect.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The natural-language content of the skill, including its description and usage instructions, is presented only in Chinese. Under the policy, forcing a specific language without user opt-in or a documented regional justification is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The natural-language content in the docstrings and all user-facing print messages is exclusively in Chinese, with no indication that language selection is optional or that the skill is region-specific. This can violate a language/locale policy when users are not given an opt-in or alternative locale.

Intent-Code Divergence

Medium
Confidence
92% confidence
Finding
The module docstring states that it will automatically classify content into a PARA structure and generate topic notes. In the implementation, there is no PARA categorization logic and no topic-note generation; the code only identifies decision/tech-note snippets and appends them to dated files.

Ssd 3

Medium
Confidence
94% confidence
Finding
The plugin persistently stores user and assistant message content, including technical notes and decisions, into local files under a predictable path. In the context of session memory sharing, this creates a durable data-retention surface where sensitive natural-language content can be exposed to other local users, backup systems, or later processes beyond the original conversation scope.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The plugin automatically persists raw conversation content to local markdown files without any visible consent, warning, sensitivity filtering, or access control handling in this file. In a chat-memory/session-sync context, conversations often contain secrets, personal data, credentials, or proprietary content, so silent retention increases privacy and data exposure risk.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The in-file documentation identifies this as a todo-sync plugin, which directly conflicts with the skill’s stated purpose of chat-record synchronization. Such contradictions are security-relevant because they obscure actual data handling behavior and make informed user consent and reviewer validation difficult.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The plugin writes extracted user todo content to persistent files without any visible notice, consent flow, or retention disclosure. Because todo-like statements often contain plans, obligations, or sensitive personal/work details, silent persistence creates a privacy and data-governance risk across sessions.

Static analysis

No suspicious patterns detected.