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

Content
View full analysis

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
View 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

Content
View full analysis

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
View 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

Content
View full analysis

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
View 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

Content
View full analysis

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
View 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
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/master_summon.py (reported line 303)May include surrounding context.

python
3. 给出具体建议(但必须标注"仅供参考")
4. 结尾提醒"这是你的风格,不一定适合用户"
"""
        return prompt
    
    def _generate_advice_with_data(self, master: dict, question: str, market_data: dict) -> str:
        """基于真实数据生成大师建议(简化版)"""

Missing User Warnings

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.