Back to skill

Security audit

Investment Buddy Pet

Security checks for vulnerabilities and agentic risk

Overview

This skill is not clearly malicious, but it needs review because it stores sensitive investment data and can issue proactive financial guidance with weak controls.

Install only after reviewing the data handling and financial-advice behavior. Avoid entering real holdings or sensitive financial details unless logging, cloud sync, heartbeat notifications, and personalization are clearly controlled; treat all output as education, not investment advice.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/feedback_collector.py:57
Finding
Plaintext Storage of User Identifiers and Complete Financial Conversations## Vulnerability Details **File Location**: `scripts/feedback_collector.py`, lines 57-79 **Vulnerability Type**: Plaintext sensitive-data storage without access-control or retention safeguards **Risk Level**: High ### Vulnerable Code ```python log_entry = { "timestamp": datetime.now().isoformat(), "user_id": user_id, "pet_type": pet_type, "question": question, "response": response, "feedback": feedback, "helpful": helpful, "metadata": metadata or {} } log_file = self.feedback_dir / f"{datetime.now().strftime('%Y-%m-%d')}.jsonl" with open(log_file, 'a', encoding='utf-8') as f: f.write(json.dumps(log_entry, ensure_ascii=False) + '\n') ``` ### Technical Analysis The feedback collector stores the user's identifier, complete question, complete Agent response, free-form feedback, and arbitrary metadata in an unencrypted JSONL file. In an investment-assistant context, questions and metadata may contain holdings, investment amounts, risk preferences, or other sensitive financial information. The file is created using the process's default permissions. The implementation does not explicitly apply a restrictive mode such as `0600`, encrypt records, redact sensitive values, separate records by user, establish a retention period, or verify that the user consented to persistent conversation logging. The predictable date-based filename also makes stored records easy to locate. Any process or account with read access to the project data directory can inspect all interactions recorded for that date. ### Attack Path 1. A user asks a question containing holdings, financial circumstances, or another sensitive detail. 2. The collector receives the complete question and response through `log_interaction`. 3. The collector writes the user ID and complete conversation to a predictable plaintext JSONL file. 4. A local user, compromised process, backup service, or synchronization utility ...[truncated 712 chars]
Remediation
## Remediation Suggestions 1. Obtain explicit, informed user consent before storing conversation content. 2. Minimize collection by storing aggregate metrics rather than complete questions and responses. 3. Redact account numbers, security identifiers, holdings, monetary values, personal identifiers, and credentials before persistence. 4. Use pseudonymous, validated user identifiers rather than directly identifying values. 5. Create files atomically with owner-only permissions, such as mode `0600`, and ensure the parent directory is mode `0700`. 6. Encrypt sensitive records at rest using a key held outside the project directory. 7. Isolate each user's records and enforce authorization whenever records are read or exported. 8. Define and enforce a short retention period with secure deletion. 9. Restrict arbitrary metadata to a documented schema and reject unexpected sensitive fields. 10. Prevent conversation logs from being included in cloud synchronization or backups unless the user separately authorizes that transfer.

T02 · Agent Memory Poisoning

Error
Location
scripts/personality_optimizer.py:139
Finding
User-Derived Preferences Overwrite Shared Global Pet Behavior## Vulnerability Details **File Location**: `scripts/personality_optimizer.py`, lines 139-184 **Vulnerability Type**: Cross-user persistent state poisoning **Risk Level**: High ### Vulnerable Code ```python pets_dir = Path(__file__).parent.parent / "pets" pet_file = pets_dir / f"{pet_type}.json" if not pet_file.exists(): return {"status": "error", "reason": "pet configuration does not exist"} with open(pet_file, 'r', encoding='utf-8') as f: pet_config = json.load(f) old_params = pet_config.get("personality_traits", {}).copy() traits = pet_config.get("personality_traits", {}) if user_preferences.get("prefers_data"): traits["verbosity_level"] = min( 100, traits.get("verbosity_level", 50) + 20 ) if user_preferences.get("prefers_direct"): traits["verbosity_level"] = max( 0, traits.get("verbosity_level", 50) - 20 ) if user_preferences.get("morning_person"): traits["proactivity_level"] = min( 100, traits.get("proactivity_level", 50) + 10 ) pet_config["personality_traits"] = traits with open(pet_file, 'w', encoding='utf-8') as f: json.dump(pet_config, f, ensure_ascii=False, indent=2) ``` ### Technical Analysis The optimizer derives preferences from a particular user's interaction history and writes the result into the packaged canonical configuration under `pets/<pet_type>.json`. That file is shared by all users who select the same pet type. This design does not create a user-scoped overlay or distinguish experimental preferences from trusted global configuration. Consequently, behavior influenced by one user's interaction records persists across future runs and affects unrelated users. The affected values include `verbosity_level` and `proactivity_level`. Repeated optimization can progressively change those settings up to their bounds. A user who can influence the interaction history and trigger optimization can therefore shape per ...[truncated 1391 chars]
Remediation
## Remediation Suggestions 1. Treat packaged files under `pets/` as immutable application configuration. 2. Store preferences in a user-scoped database record or directory keyed by a validated opaque UUID. 3. Apply preferences as bounded runtime overlays without changing the canonical pet definition. 4. Validate `pet_type` against an explicit allowlist and verify the resolved path remains inside the expected directory. 5. Separate user personalization from global optimization. Require human review, aggregate analysis, and signed releases for global changes. 6. Add provenance fields recording which data and algorithm produced each preference. 7. Limit adjustment frequency and use fixed absolute bounds rather than repeatedly accumulating changes. 8. Provide rollback and integrity verification for canonical configuration files. 9. Prevent one user's telemetry from affecting another user's state. 10. Add tests proving that optimizing one user does not modify responses or configuration for any other user.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/heartbeat_engine.py:31
Finding
Unauthenticated HTTP Market Data Controls Investment Notifications## Vulnerability Details **File Location**: `scripts/heartbeat_engine.py`, lines 31-36 and 128-143 **Vulnerability Type**: Cleartext external data retrieval without authenticity or integrity validation **Risk Level**: High ### Vulnerable Code ```python return { "heartbeat_interval": 300, "market_check_url": "http://qt.gtimg.cn/q=s_sh000001,s_sz399001", "notification_channels": ["local", "email"], "quiet_hours": {"start": 22, "end": 8} } ``` ```python try: response = requests.get( self.config["market_check_url"], timeout=5 ) data = response.text parts = data.split('~') if len(parts) > 3: current_price = float(parts[3]) change_percent = ( float(parts[32]) if len(parts) > 32 else 0 ) return { "index": "market index", "price": current_price, "change_percent": change_percent, "timestamp": datetime.now() } except Exception as e: print(f"market data retrieval failed: {e}") ``` ### Technical Analysis The heartbeat engine retrieves market information through plaintext HTTP. HTTP provides neither server authentication nor transport integrity. A network-positioned attacker, malicious proxy, compromised router, or altered DNS path can modify the response. The implementation parses the response and trusts numerical fields without authenticating the source, verifying a signature, requiring a successful status code, validating the final redirect host, or corroborating the values with an independent source. The parsed percentage is subsequently used to select market-rise and market-drop notification paths. Although a five-second timeout is configured, a timeout only limits availability impact; it does not protect authenticity or integrity. ### Attack Path 1. A user starts the heartbeat engine. 2. The engine periodically req ...[truncated 1021 chars]
Remediation
## Remediation Suggestions 1. Replace the endpoint with an HTTPS API whose certificate and hostname are validated. 2. Reject redirects, or allow redirects only to an explicit HTTPS hostname allowlist. 3. Call `response.raise_for_status()` before parsing the body. 4. Validate the response's content type, encoding, expected field count, numeric ranges, and freshness. 5. Reject impossible or stale prices and percentage changes rather than silently treating missing values as zero. 6. Corroborate consequential rise or decline triggers with an independent trusted market-data source. 7. Record data-source provenance and retrieval timestamps in each notification. 8. Fail closed when authenticity or integrity cannot be established. 9. Add tests using manipulated responses, redirects, malformed fields, stale timestamps, and extreme values. 10. Do not characterize unauthenticated data as authoritative financial information.

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/master_summon.py:15
Finding
Hard-Coded External Import Path Permits Unreviewed Module Execution## Vulnerability Details **File Location**: `scripts/master_summon.py`, lines 15-28 **Vulnerability Type**: Python module search-path hijacking and unpinned external dependency execution **Risk Level**: High ### Vulnerable Code ```python import argparse import json import subprocess import re import sys from datetime import datetime from typing import List, Dict sys.path.insert(0, '/home/admin/.openclaw/workspace') from data_layer import DataAPI, get_api _api = get_api() ``` ### Technical Analysis The script prepends a hard-coded directory outside the audited project to Python's module search path and imports `data_layer` from that location. Because the external module is not part of the reviewed package, its implementation, version, integrity, and transitive dependencies cannot be verified from the Skill artifact. Placing the directory at index zero gives it precedence over normal package locations. If an attacker or another untrusted component can create or replace `data_layer.py`, or a matching package in that directory, Python will execute that code during import. The immediate `_api = get_api()` call additionally invokes external module behavior at module-load time. The imported component is not version-pinned or integrity-checked. This creates both a local tool-spoofing risk and an insecure supply-chain boundary. The file also imports `subprocess`, but the reviewed evidence does not show an executed subprocess call. The confirmed issue is the external search-path modification and import-time execution, not subprocess command injection. ### Attack Path 1. An attacker first obtains write access to `/home/admin/.openclaw/workspace`, or compromises a component that can write there. 2. The attacker places or replaces `data_layer.py` or the corresponding package. 3. A user invokes or imports `scripts/master_summon.py`. 4. The script places the attacker-controlled directory first in `sys.path`. 5. P ...[truncated 961 chars]
Remediation
## Remediation Suggestions 1. Remove the hard-coded `sys.path.insert` operation. 2. Package `data_layer` as a normal, reviewed project dependency. 3. Pin the dependency to an exact trusted version and verify hashes during installation. 4. Use a locked virtual environment rather than a shared writable workspace. 5. Ensure dependency directories are not writable by untrusted users or unrelated services. 6. Avoid module-level initialization with external side effects; initialize the API explicitly inside the required execution path. 7. Validate the imported module's resolved path and fail if it is outside an approved immutable environment. 8. Include the dependency and its transitive dependencies in static review and software-composition analysis. 9. Run the market-data component with minimum filesystem and network privileges. 10. Add an integration test that confirms imports cannot be shadowed by files in working or user-writable directories.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • 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 (195)

Intent-Code Divergence

High
Confidence
97% confidence
Finding
The file declares raw/ as read-only and says AI does not modify it, but elsewhere directs recording interactions, market events, and feedback into raw/ subdirectories. This contradiction weakens safety guarantees, makes operator expectations unreliable, and creates a path for unintended or unauthorized writes to supposedly immutable source material.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The skill explicitly discusses user directories, file permissions, and database initialization concerns, indicating persistent local storage beyond the simple assistant description. In a finance-adjacent skill, undisclosed storage of user, interaction, or holdings-related data creates privacy and integrity risk even if the intent is operational rather than malicious.

Missing User Warnings

High
Confidence
97% confidence
Finding
Automatic ingestion from conversations into a wiki is explicitly documented without any privacy warning or consent step. This creates a direct risk of durable storage of sensitive financial preferences, emotional disclosures, or other personal content supplied during normal chat.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The skill states it must not recommend specific funds/stocks, yet the example conversation proceeds to discuss whether to buy 贵州茅台 and suggests a 5-10% starter position with phased buying. In a finance context, this contradiction undermines safety controls and can lead agents to produce regulated, product-specific investment advice despite the declared compliance boundary.

Intent-Code Divergence

High
Confidence
97% confidence
Finding
The document states compliance rules forbidding product recommendations and market timing, but other sections explicitly support prompts and responses that recommend position sizing, phased entry, and whether to buy specific securities. This contradiction creates a control-gap vulnerability: implementers may rely on nominal compliance rules while the actual designed behavior violates them.

Missing User Warnings

High
Confidence
98% confidence
Finding
The growth mechanism specifies ongoing collection, analysis of feedback, and preference profiling, yet no privacy disclosure or consent flow is described. This is especially dangerous in an investment-assistant setting because behavioral data about fear, risk tolerance, and response preferences can be sensitive and can shape future persuasive interactions.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The rules escalate severe holding-risk events to '消息 + 弹窗 + 电话', introducing phone-call intervention capability that is disproportionate to the stated pet assistant purpose. This creates a high-risk channel for coercive outreach, privacy intrusion, and off-platform pressure around sensitive financial decisions.

Lp1

High
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The module performs outbound network access via requests.get() to a market data endpoint, but the finding states this capability is not declared in permissions. Undeclared network access is dangerous because it expands the skill's effective privileges, creates a hidden data-flow boundary to external services, and can enable unexpected background communications or future exfiltration if the code is modified.

Intent-Code Divergence

High
Confidence
97% confidence
Finding
`run()` explicitly tells users that dry-run mode will not create pages, yet the execution path still processes files and performs writes before the later `if not dry_run` guard for index/log updates. This inconsistency can lead to accidental data mutation and undermines the safety contract of the tool.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The script advertises `--dry-run` as a non-mutating simulation, but `process_raw_file()` still calls page-creation functions that write Markdown files. This breaks operator expectations and can cause unintended repository or filesystem modification during testing, validation, or CI runs.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
3. 给出具体建议(但必须标注"仅供参考")
4. 结尾提醒"这是你的风格,不一定适合用户"
"""
        return prompt
    
    def _generate_advice_with_data(self, master: dict, question: str, market_data: dict) -> str:
        """基于真实数据生成大师建议(简化版)"""
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Missing User Warnings

High
Confidence
96% confidence
Finding
The restore path blindly overwrites the local database from iCloud with no confirmation, no backup, no integrity/version checks, and no conflict handling. That can cause irreversible loss or rollback of sensitive user and financial records, and if the cloud copy is stale or tampered with, it can replace trusted local data with attacker-controlled or corrupted content.

Static analysis

No suspicious patterns detected.