Back to skill

Security audit

大学生效率管家

Security checks for vulnerabilities and agentic risk

Overview

This student planner skill stores schedule and study-planning data locally for its stated purpose, with no evidence of hidden execution, exfiltration, or destructive behavior.

Install only if you are comfortable storing class schedules, exam details, and generated plans in local memory/student JSON files. Use clear fixed commands for write actions, and manually remove the stored files if you no longer want this data retained.

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
scripts/review_planner.py:115
Finding
Unbounded Review-Plan Horizon Can Cause Resource Exhaustion<![CDATA[ ## Vulnerability Details **File Location**: `scripts/review_planner.py`, lines 115-155 **Vulnerability Type**: Uncontrolled resource consumption **Risk Level**: Medium ### Vulnerable Code ```python # Calculate remaining days exam = datetime.strptime(exam_date, "%Y-%m-%d") today = datetime.now() days_remaining = (exam - today).days if days_remaining <= 0: return {"success": False, "error": "考试日期已过或为今天"} # Determine daily study duration daily_hours = daily_hours or DEFAULT_DAILY_STUDY_HOURS # Read the schedule to obtain free slots free_slots_by_day = {} if SCHEDULE_FILE.exists(): with open(SCHEDULE_FILE, "r", encoding="utf-8") as f: schedule_data = json.load(f) free_slots_by_day = schedule_data.get("freeSlots", {}) # Calculate total available time total_available_hours = 0 day_plans = [] day_names = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"] for i in range(days_remaining): target_date = today + timedelta(days=i) day_name = day_names[target_date.weekday()] # Obtain free slots for the day free_slots = free_slots_by_day.get(day_name, []) study_slots = get_available_study_time(free_slots, daily_hours) if study_slots: day_plan = { "date": target_date.strftime("%Y-%m-%d"), "day": day_name, "slots": study_slots, "totalMinutes": sum(s["duration"] for s in study_slots) } total_available_hours += day_plan["totalMinutes"] / 60 day_plans.append(day_plan) ``` ### Technical Analysis The `exam_date` argument determines `days_remaining`, but the function imposes no upper limit on the permitted planning horizon. A syntactically valid date far in the future can therefore cause the loop to execute once for every intervening day. For each iteration, the function performs date arithmetic, weekday calculation, schedule lookup, study-slot processing, and potentially appends another object to `day_plans`. If recurring free slots exist, ...[truncated 1472 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce a strict maximum planning horizon before entering the loop. A limit of 365 days, or a smaller value appropriate for an academic term, is sufficient for this use case. 2. Validate that `exam_date` is a string in the required format and return a controlled error for invalid input. 3. Place explicit bounds on `daily_hours`, chapter counts, and chapter-name lengths to prevent related resource-abuse conditions. 4. Avoid retaining all intermediate daily plans when they are not needed. Generate and process entries incrementally where practical. 5. Add tests for boundary dates, invalid dates, leap years, past dates, and dates beyond the supported horizon. Example hardening: ```python MAX_PLANNING_DAYS = 365 try: exam = datetime.strptime(exam_date, "%Y-%m-%d") except (TypeError, ValueError): return {"success": False, "error": "Invalid exam date"} days_remaining = (exam.date() - datetime.now().date()).days if days_remaining <= 0: return {"success": False, "error": "Exam date must be in the future"} if days_remaining > MAX_PLANNING_DAYS: return { "success": False, "error": f"Planning horizon cannot exceed {MAX_PLANNING_DAYS} days" } ``` ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/sport_planner.py:185
Finding
Unbounded Sport-Plan Iteration Can Cause Denial of Service<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sport_planner.py`, lines 185-234 **Vulnerability Type**: Uncontrolled resource consumption **Risk Level**: Low ### Vulnerable Code ```python def generate_sport_plan( days_ahead: int = 7, target_intensity: str = "medium", frequency: int = None ) -> Dict: """ Generate a sport plan. Args: days_ahead: Number of future days to plan target_intensity: Target intensity frequency: Weekly exercise frequency """ ensure_memory_dir() # Determine exercise frequency is_exam = is_exam_week() if frequency is None: frequency = 2 if is_exam else 3 # Obtain weather weather = get_weather() # Read schedule free_slots_by_day = {} if SCHEDULE_FILE.exists(): with open(SCHEDULE_FILE, "r", encoding="utf-8") as f: schedule_data = json.load(f) free_slots_by_day = schedule_data.get("freeSlots", {}) # Generate plan day_names = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"] plan = [] sport_days = 0 today = datetime.now() week_num = today.isocalendar()[1] for i in range(days_ahead): if sport_days >= frequency: break target_date = today + timedelta(days=i) day_name = day_names[target_date.weekday()] # Obtain free slots for the day free_slots = free_slots_by_day.get(day_name, []) # Find an appropriate exercise period sport_slot = find_sport_slot(free_slots) ``` ### Technical Analysis The function accepts `days_ahead` and `frequency` without validating their types or permitted ranges. The main planning loop is directly controlled by `days_ahead`. The early termination condition only helps after the requested number of sport days has been generated. If the schedule is absent, contains no qualifying free slots, or otherwise prevents `sport_days` from increasing, the function traverses the entire attacker ...[truncated 1324 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Restrict `days_ahead` to a small positive range appropriate for the feature, such as 1 through 31 days. 2. Restrict `frequency` to a positive value that cannot exceed the selected horizon. 3. Reject booleans, non-integers, negative values, and excessively large integers before performing date arithmetic. 4. Return early when no schedule data or no potentially usable free slots exist. 5. Catch date-overflow errors and return a controlled validation response. 6. Add tests for zero, negative, non-integer, extremely large, and schedule-less inputs. Example hardening: ```python MAX_SPORT_PLAN_DAYS = 31 MAX_FREQUENCY = 7 if ( isinstance(days_ahead, bool) or not isinstance(days_ahead, int) or not 1 <= days_ahead <= MAX_SPORT_PLAN_DAYS ): return { "success": False, "error": f"days_ahead must be between 1 and {MAX_SPORT_PLAN_DAYS}" } if frequency is not None: if ( isinstance(frequency, bool) or not isinstance(frequency, int) or not 1 <= frequency <= min(MAX_FREQUENCY, days_ahead) ): return {"success": False, "error": "Invalid exercise frequency"} if not free_slots_by_day or not any(free_slots_by_day.values()): return { "success": False, "error": "No schedule slots are available for sport planning" } ``` ]]>
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding
声明描述的是一个包含四大核心功能的综合学生效率管家,但给出的代码块实际只覆盖其中一部分,而且主要集中在“智能复习规划”。代码会读取本地 schedule.json 中的 freeSlots 作为可用学习时段,生成并保存 review-plan.json,还提供读取当前复习计划和新增考试到 exams.json 的功能。它没有实现课表导入/管理、空教室查询、运动计划或今日日程汇总等声明中的核心能力。因此,若将该代码块视为该技能的行为代表,声明明显宽于实际实现,存在实质性描述不准确。另外,add_exam 属于未在声明中明确写出的考试信息管理能力,虽然与复习规划相关,但仍是轻微的未声明扩展能力。

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
代码行为与声明存在明显不一致。实际代码只处理课程表导入解析、保存到本地 memory/student/schedule.json、计算自由时间段,并提供今日课表和指定日期空闲时段查询。这与声明中的“课表管理”和“今日日程汇总”部分基本一致,也可部分支撑“自习时间段”类能力。但声明的另外三大核心能力——空教室查询、复习计划生成、运动计划生成——在代码中完全没有实现,也没有看到相关数据源、算法、接口或外部查询逻辑。因此,声明将技能描述为四大核心功能的综合效率管家,属于对实际能力的实质性夸大。未发现额外的敏感或越权能力;问题主要是声明范围明显大于代码实际功能。

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
描述将技能定位为覆盖四大核心功能的综合学生效率管家,但该代码片段的实际主功能明显更窄,只是一个运动计划生成脚本。它会读取 memory/student/schedule.json 和 review-plan.json,基于空闲时段、默认天气、考试周状态生成运动安排并写入 sport-plan.json,还可读取今日运动计划。虽然这些行为与“运动计划”子功能一致,但与整体声明相比,缺少对课表管理、空教室查询、复习规划和今日日程等核心能力的实现。因此该代码片段无法支撑声明中的综合用途,构成描述与行为不匹配。

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill explicitly instructs reading and writing multiple files under `memory/student/`, but it declares no `permissions` or `allowed-tools` scope. That mismatch weakens least-privilege controls and creates ambiguity about what filesystem access the skill expects, which can lead to over-broad runtime access or unsafe deployment assumptions.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger logic activates on broad everyday keywords like `课表`, `复习`, `自习`, `运动`, and `空教室`, which makes accidental invocation likely during normal student conversations. In a skill that can persist personal schedule and planning data, unintended activation can lead to unsolicited data capture, file writes, or context-switching into the skill without clear user intent.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill stores sensitive personal routine data including class schedule, exams, review plans, sport plans, and preferences, but it provides no user-facing notice, consent flow, retention policy, or deletion guidance. For a student-focused assistant, this context increases risk because the stored data reveals habits, locations, availability windows, and academic timelines that could be privacy-sensitive if accessed or retained unexpectedly.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The module description and all user-facing strings are written only in Chinese, indicating the skill is designed to present its output in a fixed language. There is no visible user opt-in, language selection, or documentation justifying a mandatory Chinese locale, which matches the language/locale policy violation criteria.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
Natural-language descriptions and user-facing strings in this file are exclusively Chinese, with no indication that the user can choose another language. That can violate a language/locale policy requiring user choice or documented justification for a fixed locale.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This code persists generated review plans and exam details to files under a student memory directory, which affects user data on disk. Although the functions have internal docstrings, there is no confirmation prompt, visible logging/print disclosure at write time, or explicit warning to the user that personal study data will be stored.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The add_exam function writes subject, date, time, location, and timestamp data to persistent storage. This is user-related information, and the code does not provide any visible disclosure, confirmation, or warning at the point of write beyond an internal docstring.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code saves parsed course information to a persistent file under a student memory directory, which affects user data retention. Although the operation is part of the feature, there is no confirmation prompt, visible user-facing log, or warning in this file indicating that the provided schedule text will be stored on disk.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file's natural-language descriptions, comments, and user-relevant content such as sport names, notes, and day labels are fixed to Chinese. This imposes a specific language/locale without any visible opt-in or fallback, which matches the language-policy violation criteria.

Natural-Language Policy Violations

Low
Confidence
85% confidence
Finding
该文件从标题到全部说明均固定为中文,没有声明这是面向特定中文用户群体的区域性文档,也没有给出可选语言或用户自选机制。按规则,未经用户选择而强制单一语言属于自然语言层面的潜在政策问题。

Natural-Language Policy Violations

Low
Confidence
79% confidence
Finding
The file’s natural-language strings, day-name constants, and parsing logic are all specific to Chinese-language inputs and Chinese weekday labels. There is no indication in the file that this locale restriction is optional, user-selected, or explicitly documented as a justified region-specific limitation.

Missing User Warnings

Low
Confidence
86% confidence
Finding
This code writes a new JSON file under the user's memory directory, which affects stored user data. Although the code comment says it saves the file, there is no user-facing disclosure, prompt, or visible warning in this code path that persistence will occur.

Static analysis

No suspicious patterns detected.