Back to skill

Security audit

绿灵·Blooming Elf-v4

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent plant-care reminder skill that uses local files and optional reminders as disclosed, with some limited implementation and consent-boundary issues to review before use.

Install only if you want a Chinese-language plant assistant that stores ongoing plant, location, schedule, and pet-safety details in local files. Review the configured paths before first use, confirm any reminder automation deliberately, avoid passing sensitive context to web searches, and be careful with the migration and real-data e2e tools because their safeguards are imperfect.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
tests/e2e_check.py:68
Finding

Authorization Record Is Not Bound to the Requested Data File

Content
View full analysis

Vulnerability Details

File Location: tests/e2e_check.py:68-79
Vulnerability Type: T05: Unauthorized Access and Privilege Escalation
Risk Level: Medium

Vulnerable Code

python
if args.data:
    data_path = os.path.abspath(args.data)
    # Prevent unauthorized use: real data must not reside inside the skill directory
    if os.path.commonpath([data_path, SKILL_DIR]) == SKILL_DIR:
        print("Security block: the data path is inside the skill directory")
        sys.exit(1)
    auth_path = os.path.abspath(args.auth) if args.auth else data_path + ".auth"
    if not os.path.exists(auth_path):
        print(f"Authorization record not found: {auth_path}")
        sys.exit(1)
    with open(auth_path, encoding="utf-8") as f:
        auth = json.load(f)
    print(f"Authorization loaded: owner={auth.get('owner')} granted_by={auth.get('granted_by')}")

Technical Analysis

The authorization check verifies only that the supplied authorization file exists and contains valid JSON. It does not verify that:

  • The authorization record's data_path matches the file supplied through --data.
  • granted_by indicates explicit user consent.
  • The authorization applies to schema version 4.
  • The authorization owner is associated with the selected data file.
  • The authorization is current or unrevoked.
  • The authorized file has not been replaced since consent was granted.

The optional --auth argument makes the weakness directly exploitable because an authorization record created for one data file can be supplied while requesting access to a different file. This contradicts the documented design that treats the authorization record as the sole permission to read a specific real-data file.

Although the selected source file is copied rather than modified, copying and processing it still constitutes access. Temporary-copy isolation does not correct the missing authorization binding.

At

...[truncated 1188 chars]

Remediation
View remediation

Remediation Suggestions

  • Resolve both the requested and authorized data paths with os.path.realpath.
  • Require the authorization record to follow a strict schema.
  • Verify that the canonical auth["data_path"] exactly equals the canonical --data path.
  • Require granted_by to equal explicit-user-consent.
  • Require schema_version to equal the supported version.
  • Reject missing, malformed, unknown, or incorrectly typed authorization fields.
  • Consider recording the authorized file's SHA-256 digest so consent cannot silently transfer to a replacement file at the same path.
  • Add an expiration or revocation identifier where authorization is intended to be temporary.
  • Restrict custom authorization files to an explicitly approved directory or remove --auth if cross-path authorization is unnecessary.
  • Add negative tests proving that an authorization record for file A cannot authorize file B, including symlink and relative-path cases.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/migrate_v3_to_v4.py:193
Finding

Migration Injects Unverified User, Environment, and Pet Defaults

Content
View full analysis

Vulnerability Details

File Location: scripts/migrate_v3_to_v4.py:193-199
Vulnerability Type: T09: Insecure Skill Coding Practices
Risk Level: Low

Vulnerable Code

python
elf = "绿灵" if loc == "家里" else "小森林"
inst = {
    "elf": elf, "user": user, "remind_time": "19:00" if loc == "家里" else "10:00",
    "city": "武汉", "climate": "亚热带季风气候", "env": "室内",
    "location": loc,
    "pets": ({"cats": False, "dogs": False, "birds": ["牡丹鹦鹉"]} if loc == "家里" else {}),
    "plants": plants,
}

Technical Analysis

The migration tool inserts specific values for the city, climate, environment, reminder schedule, assistant name, and household pets even when those values were not extracted from the source archive or explicitly supplied by the user.

These fields are operational rather than cosmetic. Other Skill logic uses them to determine weather-aware watering behavior, reminder timing, microclimate assumptions, and pet-toxicity warnings. Treating developer-specific example data as authoritative migrated state can therefore produce incorrect safety and care decisions.

In particular, setting pet flags to false or inserting a specific bird creates false confidence about the actual household. The generated file does not mark these values as placeholders or require confirmation before they become active state.

Attack Path

  1. A user supplies a legacy Markdown plant archive that does not contain complete city, climate, environment, pet, or reminder information.
  2. The user runs the migration tool.
  3. The tool silently writes fixed values into the generated plants.json.
  4. The Skill subsequently treats those values as real user state.
  5. Weather decisions, schedules, or toxicity warnings are generated using inaccurate data.

Impact Assessment

This issue does not provide an attacker with additional system privileges. Its impact is integrity loss in persistent user state and potentially uns ...[truncated 320 chars]

Remediation
View remediation

Remediation Suggestions

  • Do not populate operational fields with person-specific example values.
  • Represent unknown values as null, an empty value permitted by the migration schema, or an explicit needs_confirmation state.
  • Add command-line options for city, climate, environment, reminder time, assistant name, and pets.
  • Require explicit confirmation before enabling weather-aware reminders or pet-safety decisions based on migrated values.
  • Never infer pet ownership from a generic location such as home or office.
  • Distinguish migration provenance from verified user data, for example:
    json
    {
      "migration": {
        "source": "v3-markdown",
        "unverified_fields": ["city", "climate", "env", "pets", "remind_time"]
      }
    }
    
  • Add tests confirming that missing source values do not become unrelated personal defaults.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/migrate_v3_to_v4.py:218
Finding

Migration Can Truncate Existing State Through Non-Atomic Output

Content
View full analysis

Vulnerability Details

File Location: scripts/migrate_v3_to_v4.py:218-219
Vulnerability Type: T09: Insecure Skill Coding Practices
Risk Level: Low

Vulnerable Code

python
with open(args.out, "w", encoding="utf-8") as f:
    json.dump(out, f, ensure_ascii=False, indent=2)

Technical Analysis

The migration tool opens the user-selected output path in write mode, immediately truncating any existing file. It does not:

  • Check whether the destination already exists.
  • Ask for overwrite confirmation.
  • Create a backup.
  • Write through a same-directory temporary file.
  • Validate the generated state before replacing the destination.
  • Invoke the project's documented atomic state commit mechanism.

If serialization is interrupted by process termination, storage failure, or another exception after truncation, the destination can be left empty or partially written. Supplying an existing plants.json as --out can therefore destroy the prior authoritative state.

Attack Path

  1. Select an existing state file as the migration output:
    bash
    python3 scripts/migrate_v3_to_v4.py legacy.md \
      --out /path/to/existing/plants.json
    
  2. The script opens the destination using write mode and truncates it.
  3. A process interruption, disk error, invalid generated state, or migration defect occurs.
  4. The original state is no longer available from the destination, and the resulting file may be incomplete or semantically invalid.

Impact Assessment

The issue can cause loss or corruption of the user's persistent plant-care state. It does not grant additional privileges; the script can overwrite only paths writable by the invoking process. The practical scope nevertheless includes any writable file selected through --out, not only a file named plants.json.

Loss of authoritative state can also affect later reminders, care history, and safety decisions.

Remediation
View remediation

Remediation Suggestions

  • Refuse to overwrite an existing destination unless the user explicitly supplies --force.
  • Create a backup before replacing an existing file.
  • Write the generated JSON to a uniquely named temporary file in the destination directory.
  • Flush and synchronize the temporary file before replacement where durability is required.
  • Validate the generated document with validate_data or validate_state.py.
  • Replace the destination atomically with os.replace only after validation succeeds.
  • Preserve the original file if generation or validation fails.
  • Reject output paths that resolve to directories, symlinks outside an approved data directory, or unrelated sensitive files where the execution environment permits such restrictions.
  • Add tests for interrupted writes, existing destinations, invalid generated state, and backup restoration.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (32)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/state-schema.md (reported line 45)May include surrounding context.

md
| instances[].remind_time | string(HH:MM) | ✅ | 该实例提醒时间 |
| instances[].city | string | 推荐 | 城市(用于气候/季节系数) |
| instances[].climate | string | 推荐 | 气候类型 |
| instances[].env | string | 推荐 | 室内/室外/阳台 |
| instances[].location | string | 推荐 | 摆放地点(家里/公司…),驱动「微气候提醒」与就近提醒时间 |
| instances[].microclimate | object | 可选 | **该 location 实测环境档案**(见下);浇水/喷雾判断**优先用实测**,城市天气仅降级兜底 |
| instances[].pets | object | 可选 | 宠物:`{"cats": bool, "dogs": bool, "birds": [种名]}`;任一为真则触发对应毒性告警 |

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill clearly instructs the agent to read and write persistent files and execute shell commands (cp, python3 scripts/commit_state.py), but the manifest does not declare an explicit tool scope or user-visible permission boundary. That creates a capability mismatch: a user invoking a plant-care assistant would not be adequately warned that it can mutate local state and run shell-based workflows, increasing the risk of unintended file modification or over-broad tool access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill's description emphasizes reminders and care advice but does not explicitly warn that it will persist data to MEMORY.md, plants.json, logs, and create automations. This weakens informed consent and makes the persistence and local state modification behavior more dangerous because users may provide information without understanding it will be stored across sessions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file mandates an exact Chinese opening script with wording that must be copied verbatim, and the overall skill content is presented in Chinese without offering a language choice. This can violate language/locale policy because it imposes a specific language on users without opt-in or an explicit region-specific justification.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

This duplicated finding reflects the same underlying issue: the skill mandates durable state changes and backup rotation through local file writes and shell execution. In the context of a seemingly simple care assistant, that persistence layer increases risk because behavioral data, home/work locations, reminder schedules, and pet details are retained and may be updated automatically.

Content

Scanner excerpt · SKILL.md (reported line 98)May include surrounding context.

  1. 每次状态变更流程(原子提交钩子,强制执行):
    text
    ① 改前确保备份:若 <状态文件>.bak 不存在,先 `cp plants.json plants.json.bak`
    ② Edit/Write 变更 plants.json
    ③ 跑 `scripts/commit_state.py <状态文件>`(一次完成:校验 + **原子写盘** + **备份轮转(保留3份)** / 失败自动回滚)
    ④ 退出码非 0 = 校验失败,文件已自动回滚 → 修正数据后重跑 ③,禁止带着错误回复"已记"
    

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

This duplicated finding reflects the same underlying issue: the skill mandates durable state changes and backup rotation through local file writes and shell execution. In the context of a seemingly simple care assistant, that persistence layer increases risk because behavioral data, home/work locations, reminder schedules, and pet details are retained and may be updated automatically.

Content

Scanner excerpt · SKILL.md (reported line 98)May include surrounding context.

  1. 每次状态变更流程(原子提交钩子,强制执行):
    text
    1 改前确保备份:若 <状态文件>.bak 不存在,先 `cp plants.json plants.json.bak`
    2 Edit/Write 变更 plants.json
    3 跑 `scripts/commit_state.py <状态文件>`(一次完成:校验 + **原子写盘** + **备份轮转(保留3份)** / 失败自动回滚)
    4 退出码非 0 = 校验失败,文件已自动回滚 → 修正数据后重跑 3,禁止带着错误回复"已记"
    

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The skill directs the agent to use WebSearch against external sites when a plant is not in the built-in library, even though the skill is framed primarily as a local reminder/state-management assistant. This expands the data-flow surface to third parties and may leak user queries, plant ownership details, or contextual information to external services without an explicit consent model.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger list includes broad phrases such as “帮我看看花”, “记一下”, “蔫了”, and activation on any mention of plant-related topics. These phrases are common in ordinary conversation and the file does not provide exclusion conditions or negative examples to clearly bound when the skill should activate.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file contains user-facing natural-language instructions only in Chinese, and nowhere indicates that the skill is region-specific or that users may choose another language. Under the language/locale policy, forcing a specific language without user opt-in can be a policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file presents all user-facing instructions, triggers, and outputs exclusively in Chinese, and no opt-in or locale justification is provided. Under the policy, forcing a specific language without user choice can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest describes a plant watering reminder and care assistant centered on structured local state and care guidance. This file adds behavior for retrieving documentation links via platform APIs or exposing local file paths, which is a distinct document-access capability not mentioned as part of the skill's stated purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This section adds recurring automation creation and persistent log modification beyond the core watering reminder/state-tracking scope. Expanding into autonomous scheduling and file writes without tightly scoped consent increases the chance of unintended state changes, surprise reminders, and persistence abuse in environments where skills have access to automations and stored user data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Appending monthly review results to a user log file without an explicit user-facing warning or confirmation is a persistence-integrity issue. Silent writes can surprise users, pollute records, and normalize unauthorized modification of stored data, especially in a skill that maintains long-lived state.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Line L38 uses the trigger 用户说"想买" to activate a temperature/humidity meter recommendation. This phrase is generic everyday speech and the file does not constrain it to plant-care or device-purchase contexts, which could cause unintended invocation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the agent to create and update persistent local files (plants.json, log files, and MEMORY.md paths) as the default behavior, but the onboarding text shown to the user does not clearly disclose that personal data will be stored locally and retained across sessions. This creates a privacy and consent issue: users may provide household, location, schedule, and plant-care data without understanding it is being persisted.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file title and all natural-language instructions are written in Chinese, and there is no indication that users may choose another language or locale. Under the policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file presents all operational guidance, triggers, and user-facing quoted output solely in Chinese. Under the policy rule for natural-language violations, forcing a specific language without opt-in or documented regional justification is reportable.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

SQP-3 applies to all file types and covers language or locale policy violations. This reference file presents all operational guidance in Chinese only, with no indication that users may choose another language and no stated region-specific justification for the restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module docstring, usage text, and operational messages are written exclusively in Chinese, which imposes a specific language on users. The file does not provide an opt-in, alternate locale, or explanation that this skill is intentionally limited to a Chinese-speaking environment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The generated output embeds fixed locale-specific values such as city '武汉' and climate '亚热带季风气候', and the script’s interface/messages are entirely in Chinese. Because there is no opt-in or configurable locale/language selection, this imposes a specific language/locale on all users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code file contains natural-language instructions, usage notes, and descriptions exclusively in Chinese, and the CLI help strings are likewise Chinese-only. Under the policy for natural-language violations, forcing a specific language without offering the user a choice or documenting a justified locale constraint is a reportable issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This Python file contains its module docstring, usage text, validation descriptions, and CLI output entirely in Chinese, which imposes a specific language on users. The file does not indicate that Chinese is optional, configurable, or required for a region-specific compliance reason, so it conflicts with the language/locale policy rule.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/e2e_check.py (reported line 32)May include surrounding context.

python
def run_commit(target):
    """调用 commit_state.py,返回 (exit_code, stdout)。"""
    r = subprocess.run(
        [PY, os.path.join(SCRIPTS, "commit_state.py"), target],
        capture_output=True, text=True,
    )

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This markdown file describes writing real user data to plants.json and creating plants.json.auth, and later deleting that auth file to revoke access. While it explains privacy boundaries, it does not explicitly warn users that these actions modify files on disk or recommend backing up or reviewing the target path before proceeding.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This markdown file contains natural-language instructions and descriptions exclusively in Chinese, and there is no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking context. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.