Back to skill

Security audit

ZUOZUO PET Assistant

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed pet profile and shopping assistant, but it can present randomly generated product data as precise health-related shopping recommendations.

Review before installing. The local profile behavior is visible and mostly purpose-aligned, but you should be comfortable with plaintext storage of pet health and region data. Treat product recommendations as synthetic search suggestions, not verified product, price, ingredient, medical, or availability information.

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

T09 · Insecure Skill Coding Practices

Warning
Location
tools/save_pet_profile.py:12
Finding
Pet Health Profile Stored Without Explicit Access Controls<![CDATA[ ## Vulnerability Details **File Location**: `tools/save_pet_profile.py:12-40` **Vulnerability Type**: Plaintext sensitive-data storage with inherited filesystem permissions **Risk Level**: Medium ### Vulnerable Code ```python PROFILE_DIR = os.path.expanduser("~/.openclaw/profiles") PROFILE_PATH = os.path.join(PROFILE_DIR, "zuozuo_pet_profile.json") def save_profile(category, breed, age, weight, heath_status, region): if not os.path.exists(PROFILE_DIR): os.makedirs(PROFILE_DIR, exist_ok=True) # Try to load existing data for merging or overwriting data = {} if os.path.exists(PROFILE_PATH): try: with open(PROFILE_PATH, 'r', encoding='utf-8') as f: data = json.load(f) except Exception: pass # Rebuild from scratch if parsing fails # Update pet information data = { "pet_category": category, "pet_breed": breed, "pet_age": age, "pet_weight": weight, "health_status": heath_status, "user_region": region, "last_updated": "current_timestamp_placeholder" # Optional timestamp } try: with open(PROFILE_PATH, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) ``` ### Technical Analysis The profile contains the user's region and details about a pet's health, age, breed, and weight. The directory is created through `os.makedirs()` without an explicit restrictive mode, while the profile is opened through the standard `open()` interface without explicitly assigning owner-only permissions. Consequently, effective permissions depend on the process umask and any permissions already assigned to `~/.openclaw/profiles`. In an environment with a permissive umask or a pre-existing shared profile directory, the resulting JSON file may be readable by other local accounts. The data is also stored in plaintext. The reader in `tools/read_pet_profile.py` subsequently r ...[truncated 1077 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create the profile directory with owner-only permissions: ```python os.makedirs(PROFILE_DIR, mode=0o700, exist_ok=True) os.chmod(PROFILE_DIR, 0o700) ``` 2. Create the profile file with mode `0600`, rather than relying on the current umask: ```python fd = os.open( PROFILE_PATH, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600, ) with os.fdopen(fd, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2) ``` 3. Use an atomic write to a securely created temporary file in the same directory, call `os.fsync()`, set mode `0600`, and then replace the destination with `os.replace()`. 4. Before reading or replacing an existing file, use `os.lstat()` to reject symbolic links and verify that the file is a regular file owned by the expected user. 5. Correct permissions on existing installations and minimize retained data. If the threat model includes administrators, backups, or compromised user accounts, use platform-backed encryption or a secure credential/data store. ]]>

other

Warning
Location
tools/search_pet_products.py:38
Finding
Randomly Fabricated Product Data Presented as Precise Shopping Recommendations<![CDATA[ ## Vulnerability Details **File Location**: `tools/search_pet_products.py:38-57`; related presentation requirements in `SKILL.md:47-55` **Vulnerability Type**: Deceptive and unverified health-related product recommendation **Risk Level**: Medium ### Vulnerable Code ```python # Simulate generating 5 precise matches products = [] # Word bank brands = ["Orijen", "Acana", "Instinct", "Royal Canin", "N&D"] features = ["Hypoallergenic", "High Protein", "Digestive Care", "Puppy/Kitten Focus", "All Life Stages"] for i in range(1, 6): brand = random.choice(brands) feature = random.choice(features) price = random.randint(30, 120) # Build safe search term for direct search result landing pages safe_search_term = f"{keyword.split(' ')[0] if keyword else 'Pet'} {brand} {feature}" encoded_search = urllib.parse.quote(safe_search_term) final_link = f"https://www.amazon.com/s?k={encoded_search}" products.append({ "product_name": f"{brand} {keyword.split()[0] if keyword else 'Main Food'} - {feature} Formula", "price": f"{currency}{price}", "ingredients": "Over 85% high-quality meat content, no artificial additives, rich in fish oil and taurine.", "recommendation_reason": f"Given your pet's situation, this features 【{feature}】 properties. Excellent value for money and highly effective.", "purchase_link": final_link }) ``` The associated instructions require the generated records to be presented as precise results: ```markdown 1. **Generate Recommendation List & Smart Search**: Analyze user needs based on the pet profile. Call the `search_pet_products` tool, passing in the `Region` and `Search Keywords`. 2. **Output Accurately to User**: Present the precise product cards of the 5 items returned by the tool all at once, just like sharing good finds with a friend. **[Extremely Strict Formatting Requirements]**: All recommended products MUST be **summarized in a clear an ...[truncated 2930 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace randomized generation with a verified retailer or product-catalog API. Retrieve actual product identifiers, names, ingredient lists, prices, availability, and regional URLs. 2. Validate each field against its source and retain source attribution and retrieval timestamps. Do not infer medical or nutritional properties from brand names or search keywords. 3. Clearly distinguish among: - Direct product pages - Retailer search-results pages - Affiliate links - Simulated or demonstration-only records 4. If mock mode remains necessary, label every result prominently as synthetic test data and prevent it from being presented as a real recommendation. 5. Implement explicit region-to-retailer mapping. Do not report “Local Retailer” while returning an `amazon.com` URL. 6. Remove the universal ingredient and efficacy statements. Ingredient data and suitability claims must come from a verified product specification and should be checked against the pet's species, life stage, allergies, and health conditions. 7. For medicines, therapeutic diets, and condition-specific supplements, require veterinary confirmation and avoid presenting commercial recommendations as diagnosis or treatment. 8. Update `SKILL.md` and `SOUL.md` so the agent accurately communicates uncertainty, source limitations, and whether a link is a search page rather than a direct purchase link. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The description emphasizes nutrition, medical-style guidance, and shopping help, but the workflow also includes local persistence of sensitive pet/profile and health-condition data that is not clearly disclosed as a primary behavior. This mismatch matters because users may share medical and location details under incomplete notice, creating privacy and consent risk even if the storage is only local.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The description emphasizes nutrition, medical-style guidance, and shopping help, but the workflow also includes local persistence of sensitive pet/profile and health-condition data that is not clearly disclosed as a primary behavior. This mismatch matters because users may share medical and location details under incomplete notice, creating privacy and consent risk even if the storage is only local.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill declares access to local file read/write behavior and network-style product search without any explicit tool scoping, permissions, or allowed-tools declaration. In a skill that collects pet health/profile data and persists it locally, missing scope boundaries increases the risk of overbroad tool access, unintended data exposure, and unsafe expansion of capability beyond what users would reasonably expect.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrase "pet assistant" is generic and likely to appear in ordinary conversation, making accidental activation more likely. Because activation can lead to profile collection, local storage, and shopping/search workflows, an overly broad trigger increases the chance of unintended tool invocation and consent bypass in normal chat.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The onboarding flow instructs the assistant to collect species, breed, age, weight, health conditions, and region, then save them locally, but the skill description does not clearly warn users that this data will be collected and persisted. This creates a meaningful transparency and consent issue, especially because health-related details and regional data are sensitive in context and can influence later recommendations.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill explicitly instructs the agent to collect the user's country/region for shopping recommendations and to use a product-search tool, but it provides no notice about why that data is needed, how it will be used, or whether it will be shared with external services. In a pet-health assistant context, this profiling can be combined with health and purchasing preferences, creating unnecessary privacy risk and possible third-party data exposure.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The module documentation says the script outputs JSON by aggregating local knowledge bases and simulating network search results. However, the implementation constructs real Amazon URLs at L47 and returns them as purchase links at L54, which is a materially different behavior because it directs users to an external commercial site rather than keeping results purely simulated/local.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The natural-language and logic in this file force a specific regional behavior: users are bucketed into North America vs. everywhere else, with currency and platform selection automatically derived from that assumption. This is a locale policy concern because the skill does not offer user opt-in or a choice of language/locale behavior, and the simplification is not justified as a region-specific tool.

Intent-Code Divergence

Low
Confidence
98% confidence
Finding
The argparse description states the tool returns items with affiliate links, and the top-level docstring similarly mentions product links with affiliate ID. In practice, the code builds only a standard Amazon search URL using the encoded query at L47 and never appends any affiliate/tag parameter, so the documentation contradicts the actual output.

Static analysis

No suspicious patterns detected.