Back to skill

Security audit

睡前故事精靈

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a bedtime-story tool, but its documented cron setup creates lasting daily execution without enough lifecycle controls.

Review the cron instructions carefully before installing. Use the story features normally, but do not run the crontab one-liner unless you intentionally want a persistent daily reminder and know how you will remove it. Also consider that favorites, playback history, and routine settings are stored locally under ~/.qclaw/kids.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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 (1)

T06 · System Persistence

Warning
Location
README.md:84
Finding

Persistent Daily Execution Through User Crontab

Content
View full analysis

Vulnerability Details

File Location: README.md, lines 84-88
Vulnerability Type: Persistent scheduled-task installation
Risk Level: Medium

Vulnerable Code

bash
# Install crontab
(crontab -l 2>/dev/null; echo "0 20 * * * cd ~/.qclaw/skills/bedtime-story-teller && python3 scripts/sleep_routine.py --mode cron >> /tmp/sleep_routine.log 2>&1") | crontab -

# View crontab
crontab -l

Technical Analysis

The documented command modifies the invoking user's crontab and registers the Skill for automatic execution every day at 20:00. This execution persists across terminal sessions and system restarts supported by the cron service.

Scheduling is related to the optional bedtime-reminder feature, but it is not required for the Skill's primary story-generation and playback functionality. It therefore exceeds the minimum execution scope needed by the core feature.

The installation command also has several security and reliability weaknesses:

  • It suppresses errors from crontab -l. If the existing crontab cannot be read, the pipeline may install only the new entry and unintentionally discard existing jobs.
  • It is not idempotent. Running it repeatedly appends duplicate scheduled tasks.
  • It executes code from a user-writable, fixed project path. If files at that path are subsequently replaced or modified, cron will execute the changed code automatically.
  • It writes to a predictable shared path, /tmp/sleep_routine.log, rather than a private per-user state or log directory.
  • No corresponding removal command or lifecycle management procedure is documented.

The Python script itself does not install the cron job, elevate privileges, access the network, or retrieve remote payloads. Installation occurs only if a user copies and executes the README command.

Attack Path

  1. A user follows the cron setup instructions in README.md.
  2. The shell pipeline reads the current ...[truncated 1526 chars]
Remediation
View remediation

Remediation Suggestions

  1. Keep scheduling strictly optional and require explicit, informed user confirmation. Clearly distinguish the reminder feature from the core story-generation functionality.
  2. Replace the raw pipeline with a dedicated installer that aborts if the existing crontab cannot be read:
    bash
    current_crontab="$(crontab -l 2>/dev/null)" || {
      status=$?
      if [ "$status" -ne 1 ]; then
        echo "Unable to read the existing crontab; no changes were made." >&2
        exit "$status"
      fi
      current_crontab=""
    }
    
  3. Add uniquely marked begin/end comments and check for an existing entry before installation so setup is idempotent and does not create duplicate jobs.
  4. Preserve the original crontab and offer a preview or backup before applying changes.
  5. Document an uninstall command that removes only this Skill's marked entry without affecting unrelated scheduled tasks.
  6. Use an absolute, validated interpreter and script path. Ensure the Skill directory and executable files are writable only by the intended user.
  7. Write logs to a private directory such as ~/.qclaw/kids/logs/, create it with restrictive permissions, and implement log rotation or avoid persistent logging when it is unnecessary.
  8. Consider a user-visible scheduling facility that provides clear enable, disable, and status controls instead of instructing users to rewrite their crontab directly.
  9. Document how users can verify the installed entry and disable reminders immediately.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (20)

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · README.md (reported line 84)May include surrounding context.

-----| | 友誼冒險 | 認識新朋友、一起解決問題 | 🌈 | | 認識情緒 | 害怕、分享、勇氣、不生氣 | 💤 | | 成語改編 | 龜兔賽跑、守株待兔新版 | 🏠 | | 格林童話 | 童話改編,適合幼兒版本 | 📖 | | 原創互動 | 小烏龜、小蝴蝶、小龍貓 | ✨ |

🌙 睡前作息 Cron 設定

建議每天 20:00 自動提醒:

bash
# 安裝 crontab
(crontab -l 2>/dev/null; echo "0 20 * * * cd ~/.qclaw/skills/bedtime-story-teller && python3 scripts/sleep_routine.py --mode cron >> /tmp/sleep_routine.log 2>&1") | crontab -

# 查看 crontab
crontab -l

📖 故事生成參數

text
--protagonist, -p  主角名稱(小兔子、小熊、小狐狸…)
--pet              寵物角色(小狗狗、小貓咪、小烏龜…)
--age, -a          toddler(2-3歲)/ preschool(4-6歲)
--length, -l       short(短)/ medium(中)/ long(長)
--theme, -t        friendship / emotion / idiom / fairytale / original
--seque

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared purpose focuses on storytelling, but the documented behavior extends into scheduling, persistent local state, reminder management, and emitting an external skill trigger hint. This mismatch can mislead users and reviewers about the operational reach of the skill, increasing the chance of unintended persistence, background-like behavior, or cross-skill invocation without informed consent.

Content

No source excerpt is available for this finding.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · scripts/story_generator.py (reported line 316)May include surrounding context.

python
��來吧……」",
        "solution": "可是,小雞的心裡一直不安。他走到評審面前說:「對不起,我用了不該用的糖,對不起。」評審點點頭:「誠實比帽子更珍貴!」",
        "ending": "小雞沒有得到帽子,可是他覺得心裡暖暖的,比戴上帽子更快樂。晚安,小雞,晚安,小朋友!🌙🐥",
        "emoji": "🐥👨‍🍳⭐",
        "lesson": "勇於承認錯誤,是最勇敢的表現 🌟"
    },

    "squirrel_store": {
        "title": "🐿️ 小松鼠的愛心商店",
        "theme": "friendship",
        "setup": "秋天到了,小松鼠收集了好多好多的橡果,他把家裡的房間都堆滿了,還是放不下。",
        "problem": "這時候,小兔子走過來說:「小松鼠,我家裡沒有食物了,可以跟你買一些嗎?」小松鼠說:「可是我也要吃呀……」",
        "attempt": "小松鼠想了想:「如果我把橡果分給大家,冬天我怎麼

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README presents the invocation as simply saying 「講個睡前故事」, which is a common natural phrase a parent might use in ordinary conversation. It does not provide trigger boundaries, alternative exact phrases, or negative examples clarifying when the skill should and should not activate.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README provides a one-liner that installs a persistent cron job into the user's crontab, causing scheduled execution beyond the current session, yet does not prominently warn that this modifies system scheduling state. Persistence is security-relevant because users may not realize the skill will continue running automatically and writing logs after setup.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
95% confidence
Finding

The documented crontab installation creates persistence by scheduling periodic execution from the user's account. In this skill context, the command appears aligned with the advertised sleep reminder feature rather than a covert backdoor, but it still introduces lasting execution and log writing that users should explicitly consent to.

Content

Scanner excerpt · README.md (reported line 84)May include surrounding context.

建議每天 20:00 自動提醒:

bash
# 安裝 crontab
(crontab -l 2>/dev/null; echo "0 20 * * * cd ~/.qclaw/skills/bedtime-story-teller && python3 scripts/sleep_routine.py --mode cron >> /tmp/sleep_routine.log 2>&1") | crontab -

# 查看 crontab

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 88)May include surrounding context.

(crontab -l 2>/dev/null; echo "0 20 * * * cd ~/.qclaw/skills/bedtime-story-teller && python3 scripts/sleep_routine.py --mode cron >> /tmp/sleep_routine.log 2>&1") | crontab -

查看 crontab

crontab -l

text

## 📖 故事生成參數

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README explicitly documents persistent storage of favorites, playback history, and sleep routine settings under the user's home directory, but gives no notice about retention, sensitivity, or deletion. For a child-focused skill, storing behavioral/history data without transparency increases privacy risk and may lead users to retain more personal data than they realize.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill advertises no explicit tool scope or permissions, yet its documented/code-detected capabilities include file read and file write. That creates an authorization transparency gap: users and the hosting agent may invoke a seemingly harmless story skill without clear notice that it can persist data or access local files.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Broad trigger phrases like common requests for stories overlap with ordinary conversation, which can cause accidental activation. In a skill that can read/write files and manage routines, inadvertent invocation is more than a UX issue because it may lead to persistence or other side effects the user did not intend.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The rule '全繁體中文' mandates a specific language/locale behavior, but the document does not offer users a choice or state that this is an explicitly region-specific skill. Under the policy, forcing a language without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

User-facing descriptions, prompts, and outputs throughout the script are in Chinese, which imposes a specific language experience by default. The file does not provide any option to select another language or indicate that Chinese-only behavior is intentional and user-approved.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The module docstring presents the skill exclusively in Traditional Chinese and describes its purpose without indicating that language is optional or configurable. Under the policy rule for natural-language violations, forcing a specific language without user opt-in is a reportable locale/language constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

All user-facing CLI descriptions, examples, and argument help strings are in Chinese, and there is no flag or documented opt-in for language choice. This creates a natural-language policy concern because the skill enforces a specific language for user interaction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

User-facing strings throughout the file, including the module description and interactive prompts, are fixed in Chinese with no opt-in or alternative locale path. This can violate language/locale policy when a skill forces a specific language without giving the user a choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code performs a destructive operation by wiping the stored playback history and immediately writing the empty list to disk. Although a success message is printed afterward, there is no confirmation step or advance warning before user data is deleted.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code file contains user-facing descriptions and prompts in Chinese only, beginning with the module docstring and continuing throughout the interactive flow. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale limitation is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README states 「全程繁體中文」, indicating the skill always uses Traditional Chinese. Under the policy, forcing a specific language without user opt-in or a documented regional justification is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The description says the skill activates whenever parents say「講故事 / 睡前故事 / 床邊故事」, but it does not clarify whether activation requires a direct request, a child context, or bedtime context. This leaves unclear boundaries between intended bedtime use and incidental mentions of those phrases.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code persists routine settings to ~/.qclaw/kids/sleep_routine.json, which is a user-data write operation. Although the setup flow later says the settings were saved, the file-writing behavior itself is not clearly disclosed in the module docstring or command help, so users are not warned up front that data will be stored on disk.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.