Back to skill

Security audit

Kid Tutor - 儿童AI家教助手

Security checks for vulnerabilities and agentic risk

Overview

The skill is a plausible children’s tutoring helper, but it stores child profile and learning data and includes an unsafe shell-based logging pattern that users should review before installing.

Install only if you are comfortable with local plaintext storage of a child's profile and learning history. Before use, add an explicit parent consent step, avoid putting real full names in directory or profile data, keep the `data/kid-tutor/` folder protected, do not send reports to Feishu without a separate confirmation, and replace the documented `echo '<session_json>'` command with a safe file-based or non-shell stdin invocation.

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

Error
Location
SKILL.md:68
Finding
Shell Command Injection Through Interpolated Session JSON<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:68` **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code ```bash echo '<session_json>' | python3 scripts/manage_profile.py data/kid-tutor/<name> log-session ``` ### Technical Analysis The documented workflow instructs the agent to embed session JSON directly inside a single-quoted shell command. Session data may contain attacker-controlled values, including questions, answers, notes, interests, or names. JSON escaping does not provide shell escaping. If a value contains a single quote, it can terminate the shell string. Subsequent shell metacharacters can then introduce an arbitrary command. The shell interprets that command before the JSON is passed to `manage_profile.py`. For example, a malicious session field could contain a payload shaped like: ```text '; <attacker-command>; echo ' ``` If substituted directly into `<session_json>`, this closes the quoted argument and causes the shell to execute the inserted command. ### Attack Path 1. An attacker supplies crafted text during a tutoring session, such as a question response or note containing a single quote followed by shell syntax. 2. The attacker-controlled text is included in the session JSON. 3. The agent follows the documented command and substitutes the JSON into the single-quoted `echo` expression. 4. The crafted single quote terminates the intended shell string. 5. The shell executes the injected command before or alongside `manage_profile.py`. 6. The injected process inherits the permissions and environment of the agent executing the skill. ### Impact Assessment Successful exploitation permits arbitrary command execution with the privileges of the agent or user running the skill. Depending on those privileges, an attacker could: - Read or modify files accessible to the agent. - Exfiltrate locally available profile, session, or configuration data. - Corrupt or delete learning records. - Ex ...[truncated 320 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not interpolate JSON or any other user-controlled value into a shell command. 1. Serialize session data using a structured JSON API and write it to a securely created file. 2. Invoke the script using an argument array rather than a shell: ```text ["python3", "scripts/manage_profile.py", "data/kid-tutor/<name>", "log-session", "--file", "<trusted-file>"] ``` 3. If standard input is required, start the Python process without a shell and pass the serialized JSON directly through the subprocess API's stdin facility. 4. Treat the child name used in the data path as untrusted input. Resolve it beneath an approved base directory and reject path separators, traversal components, and control characters. 5. Update `SKILL.md` to explicitly prohibit shell interpolation and provide only the safe invocation pattern. 6. Add regression tests using session values containing single quotes, semicolons, command substitutions, newlines, and shell metacharacters. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/manage_profile.py:103
Finding
Session Records Can Be Silently Overwritten Due to Minute-Level Filenames<![CDATA[ ## Vulnerability Details **File Location**: `scripts/manage_profile.py:103-105` **Vulnerability Type**: Predictable filename collision and data overwrite **Risk Level**: Low ### Vulnerable Code ```python now = datetime.now() fname = now.strftime("%Y-%m-%d_%H%M") + ".json" fpath = os.path.join(sessions_dir, fname) ``` The resulting path is subsequently opened in write mode: ```python with open(fpath, "w", encoding="utf-8") as f: json.dump(session_data, f, ensure_ascii=False, indent=2) ``` ### Technical Analysis Session filenames include the date, hour, and minute but no seconds, microseconds, random identifier, or collision check. Every session logged in the same minute therefore resolves to the same path. The later write uses Python's `"w"` mode, which truncates an existing file without warning. As a result, a second session recorded in the same minute silently destroys the first session's data. The profile statistics are incremented for each logging operation even though only the final session file remains. This can also create inconsistencies between aggregate profile counters and reports generated from the files on disk. ### Attack Path 1. A legitimate session is logged and saved under a filename such as `2026-02-27_1030.json`. 2. A second session is submitted before the clock advances to the next minute. 3. The second invocation computes the same filename. 4. `open(fpath, "w")` truncates the existing session file. 5. The second session replaces the first without an error or warning. 6. Future reports omit the overwritten session, while profile-level totals may still reflect both logging operations. ### Impact Assessment The issue affects the integrity and availability of local learning records. It can cause: - Loss of valid session history. - Inaccurate parent reports. - Mismatches between profile totals and stored session data. - Manipulation or concealment of an earlier session by deliberately submitting another record in the s ...[truncated 201 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate collision-resistant filenames using a UUID or a timestamp containing microseconds: ```python from uuid import uuid4 fname = f"{now:%Y-%m-%d_%H%M%S_%f}_{uuid4().hex}.json" ``` 2. Open new session files in exclusive creation mode (`"x"`) so an unexpected collision raises an error instead of overwriting existing data. 3. If a collision occurs, generate a new identifier and retry. 4. Consider writing to a temporary file and atomically renaming it into the sessions directory after serialization succeeds. 5. Use file locking or another concurrency-control mechanism when updating `profile.json` to prevent lost updates from simultaneous processes. 6. Add tests that log multiple sessions during the same minute and concurrently, verifying that each produces a distinct record and consistent aggregate statistics. ]]>
Vulnerability Patterns
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
声明描述的是一个完整的儿童AI家教助手,核心能力应包括互动教学、主动出题、难度自适应和引导式辅导。实际代码却只实现了“学习报告”子功能:从本地 JSON 学习记录中读取数据,做简单统计分析,并生成 Markdown 报告。代码没有任何对话、教学、出题、难度调节或家教模式激活逻辑。因此,虽然“学习记录和家长报告”这一部分与声明部分吻合,但整体主功能与声明明显不一致,属于能力大幅高估/描述过宽的情况。

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
该代码与描述存在明显范围不一致。描述宣称的是一个完整的儿童AI家教助手,强调教学交互、主动出题、个性化辅导和家长报告;但实际代码只是一个本地命令行脚本,用于维护孩子学习档案和记录会话数据。它确实覆盖了“学习记录”和部分“个性化难度字段”的数据层支持,但没有任何AI教学、题目生成、科学/数学辅导、错误纠正、报告生成或触发逻辑实现。因此,代码只实现了所述系统中的一个辅助子组件,而非描述中的主要能力,构成实质性不匹配。

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill instructs the agent to read and write persistent files under data/kid-tutor/ but does not declare any explicit tool scope or permissions. This creates an authorization ambiguity where file access may occur without clear least-privilege boundaries, which is especially sensitive because the files contain children's profile and session data.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The activation criteria are broad enough to trigger in ordinary conversations about children's learning, reports, or tutoring. In this skill, accidental activation is more dangerous because it can lead to unnecessary collection, storage, or reporting of children's educational data without deliberate user intent.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill persistently stores child profiles and session records but provides no user-facing notice that data will be saved. This is particularly sensitive because the subjects are children, and undisclosed retention of identifiable educational data raises privacy, consent, and compliance risks.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill allows sending parent reports to Feishu without any documented user warning or confirmation about external data sharing. Exporting children's learning data to a third-party messaging platform without explicit notice increases the risk of unintended disclosure beyond the local environment.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The document claims it does not collect sensitive personal information, yet it explicitly stores a child's name, age, grade, interests, and detailed learning history. This is dangerous because it can mislead users and operators about the privacy sensitivity of the data being retained, reducing consent, notice, and handling safeguards for children's information.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The package description is written only in Chinese and presents the skill as a general-purpose AI tutor for children, but it does not state that the skill is China-specific or that users can choose another language. This creates a natural-language locale policy concern because the metadata implicitly fixes the skill's language without documented opt-in or justification.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
The entire guidance is written as prescriptive Chinese-language teaching behavior and does not mention offering the user a language or locale choice. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file’s user-facing description and generated report content are written exclusively in Chinese, and the script provides no option for users to select another language or opt into this locale. Under the policy, forcing a specific language without user choice is a natural-language policy violation unless the locale restriction is clearly documented and justified.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The module docstring, usage text, and command descriptions are all written exclusively in Chinese, with no indication that language choice is optional. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This script stores a child’s profile and session history, including name, age, grade, interests, and learning records, in plaintext JSON files on local disk without any privacy notice, retention controls, access restrictions, or minimization safeguards. In a kid-focused tutoring skill, this increases sensitivity because the data belongs to minors and may be collected or persisted without clear consent or operator awareness.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
技能描述、示例和参数均默认并强约束为中文环境,例如名称参数示例为“--name <中文名>”,整体说明也未提供语言切换或用户选择。对于面向一般用户的技能,这种固定语言设定若无明确地区性限制或用户选择,可能不符合语言/locale 选择政策。

Intent-Code Divergence

Low
Confidence
87% confidence
Finding
L65 的绝对化规则写着“永远不直接给答案”,但 L68 说明引导 2-3 轮后可切换讲解模式,且 L51 也要求“讲清楚,再出类似题巩固”。这说明技能并非绝不提供直接解释,教学意图文档前后不一致。

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
This markdown file consists entirely of Chinese instructions and templates, with no indication that users may choose another language or locale. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Description-Behavior Mismatch

Low
Confidence
83% confidence
Finding
文件头部文档将该脚本描述为读取学习记录并生成报告,重点呈现为数据读取和内容生成;但实际代码在提供 --output 时会直接写入任意文件路径。对于“生成报告”而言,产出文本是合理的,但将其落盘到任意路径属于额外的文件修改行为,未在说明中明确体现。

Static analysis

No suspicious patterns detected.