Back to skill

Security audit

AI运动健康助手

Security checks for vulnerabilities and agentic risk

Overview

This fitness skill is mostly coherent, but it stores health data locally in plaintext and generates HTML reports with unsafe scripting risks users should review before installing.

Install only if you are comfortable with the skill saving profile and workout history as plaintext files in the workspace. Treat generated reports as sensitive, avoid opening reports built from untrusted or edited diary files, and prefer a version that escapes HTML fields, bundles or pins Chart.js with integrity checks, and provides clear delete/export/opt-out controls.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Warning
Location
scripts/html_report.py:194
Finding

Mutable Remote JavaScript Is Executed in Weekly Reports

Content
View full analysis
``` ### Technical Analysis Generated weekly reports retrieve and execute Chart.js from a public CDN whenever the report is opened. The dependency uses the broad `@4` version selector rather than an immutable, exact version, and the script tag does not provide a Subresource Integrity (`integrity`) hash. Consequently, the JavaScript executed by an already-generated report can change after the skill has been audited. A compromised CDN, compromised upstream package release, or unexpected dependency update could cause attacker-controlled JavaScript to execute in the report viewer. The generated page also lacks a restrictive Content Security Policy, so a compromised dependency would be able to initiate outbound requests and manipulate all content in the report. ### Attack Path 1. A user generates a weekly exercise report. 2. The user opens the generated HTML document in a browser or preview component. 3. The report requests `https://cdn.jsdelivr.net/npm/chart.js@4`. 4. The CDN resolves the mutable version selector and returns JavaScript. 5. If the CDN response or selected upstream release has been compromised, the browser executes the malicious JavaScript. 6. The script can read and modify report content and transmit information accessible within the report's browser context to an external server. ### Impact Assessment Successful exploitation provides arbitrary JavaScript execution in the security context of the generated report. An attacker could: - Read exercise and health information rendered in the report. - Alter report statistics or safety advice. - Display phishing or deceptive user-interface elements. - Make outbound network requests and exfiltrat ...[truncated 252 chars]
Remediation
View remediation
``` 4. Verify the hash against the exact reviewed artifact before release. 5. Add a restrictive Content Security Policy. If the dependency is bundled locally, a suitable baseline is: ```html ``` 6. Maintain an inventory of bundled third-party components and periodically review them for known vulnerabilities. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/html_report.py:34
Finding

Stored HTML Injection in Daily Exercise Reports

Content
View full analysis
{_category_icon(ex.get('category', ''))} {ex['type']} {ex.get('time', '')}
时长{ex['duration_min']}分钟
Remediation
View remediation
`, quotes, event handlers, and closing tags to verify that generated reports contain encoded text rather than active markup. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/calorie_calc.py:19
Finding

Sensitive Health and Exercise Data Is Stored in Plaintext

Content
View full analysis
Optional[dict]: if PROFILE_PATH.exists(): with open(PROFILE_PATH, "r", encoding="utf-8") as f: return json.load(f) return None def save_profile(self, profile: dict): DATA_DIR.mkdir(parents=True, exist_ok=True) with open(PROFILE_PATH, "w", encoding="utf-8") as f: json.dump(profile, f, ensure_ascii=False, indent=2) ``` Exercise history is also written as plaintext JSON: ```python entries.append({ "time": datetime.now().strftime("%H:%M"), "exercise": exercise, "calories": cal_result, "note": note, "timestamp": datetime.now().isoformat(), }) with open(day_file, "w", encoding="utf-8") as f: json.dump(entries, f, ensure_ascii=False, indent=2) ``` ### Technical Analysis The skill is designed to collect and retain age, sex, height, weight, fitness goals, and exercise history. These fields constitute sensitive personal and health-related data. The implementation stores this information in unencrypted JSON files under the project directory. It does not explicitly set owner-only file or directory permissions, so effective access depends on the operating system's default permissions and process umask. The implementation also provides no retention period, deletion mechanism, or explicit consent control in the reviewed scripts. Using a project-relative location increases the likelihood that sensitive records may be included in workspace syn ...[truncated 1094 chars]
Remediation
View remediation
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明描述的是一个覆盖“记录运动 + 计算消耗 + 生成计划 + 输出HTML报告”的完整运动健康助手;而提供的代码块只清晰实现了其中一部分,且主要聚焦于“个性化运动计划生成”。它确实包含基于目标、水平、器材和《中国居民运动指南》的计划编排,以及对周卡路里消耗的估算,这与声明部分一致。但关键声明能力——自然语言记录运动、处理跑步/力量/游泳等具体运动记录、生成可视化HTML日报/周报——在此代码中没有实现。输出仅为字典结构和纯文本格式化,不是HTML报告。因此,代码行为仅部分覆盖声明,且主用途明显更窄,构成描述与实际行为不一致。

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/plan_gen.py (reported line 320)May include surrounding context.

python
def _get_goal_guidelines(self, goal: str) -> dict:
        guidelines = CHINESE_EXERCISE_GUIDELINES.copy()
        if goal in guidelines:
            return guidelines[goal]
        return guidelines["adult"]

    def _get_progression(self, level: str) -> list:

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/plan_gen.py (reported line 321)May include surrounding context.

python
def _get_goal_guidelines(self, goal: str) -> dict:
        guidelines = CHINESE_EXERCISE_GUIDELINES.copy()
        if goal in guidelines:
            return guidelines[goal]
        return guidelines["adult"]

    def _get_progression(self, level: str) -> list:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The README presents the skill name, description, examples, and standards entirely in Chinese, including invocation examples, with no indication that users may interact in other languages. Under the policy for natural-language violations, a skill that effectively requires a specific language without user opt-in can be a locale-policy issue unless the regional constraint is clearly documented and justified.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Overly broad trigger phrases like generic fitness terms can cause the skill to activate during ordinary conversation without clear user intent. In a skill that can read, write, fetch web content, and invoke Bash-backed scripts, accidental activation increases the chance of unintended data collection, file writes, or execution of actions the user did not explicitly request.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The instructions define the assistant as a Chinese sports-health advisor and the examples, standards, and interaction model are all fixed to Chinese-language operation. There is no indication that users may choose another language or explicitly opt into this locale-specific behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code persists a user profile containing body weight and related health data to a local JSON file with no visible consent flow, retention controls, or disclosure in this component. For a sports-health skill, this is privacy-relevant personal data, and silent storage increases the risk of unintended exposure on shared devices or through backup/sync mechanisms.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Exercise entries, notes, timestamps, and calorie results are written to per-day JSON files without any explicit warning or opt-in. In this skill context, workout history and timestamps can reveal sensitive health patterns and daily routines, making undisclosed persistence a genuine privacy weakness.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module docstring and generated HTML content are entirely in Chinese, and the HTML documents explicitly set lang="zh-CN". Under the policy rule, forcing a specific language or locale without user opt-in is a natural-language policy violation unless the constraint is clearly justified or the user is offered a choice.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

Exercise fields such as type, time, and category are interpolated directly into HTML without escaping, and weekly report data is also embedded into active HTML/JavaScript output. If user-controlled values contain HTML or script payloads, opening the generated report can trigger stored XSS in the browser or WebView used to view the report.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The daily report template sets the HTML language to zh-CN, which enforces a specific locale in user-facing output. No language-selection mechanism or documented regional justification is present in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The weekly report HTML also fixes the document language to zh-CN and all visible content is Chinese. This appears to impose a locale on users without opt-in or a stated limitation to a region-specific use case.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The weekly report loads Chart.js from a public CDN, which introduces third-party script execution into an otherwise local reporting feature. If the CDN is unavailable, compromised, or intercepted, the generated report can execute attacker-controlled JavaScript when opened, creating a supply-chain and privacy risk beyond the skill's stated purpose.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring and all user-facing content are written in Chinese, and the skill embeds China-specific exercise guidance as the default knowledge source. Because there is no indication that users can opt into another language or locale, this creates a natural-language locale constraint that may violate organizational language-choice policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring presents the skill exclusively in Chinese and explicitly anchors it to Chinese exercise guidance, while the rest of the file also generates only Chinese user-facing content. For a generally applicable fitness-plan generator, this imposes a specific language/locale without any user opt-in or documented locale constraint.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The no-equipment branch calls re.sub(...) even though the module imported re as _re, so a NameError will occur whenever that path is taken. In this skill, that means certain common profiles may crash plan generation instead of producing a workout, creating a denial-of-service style reliability issue rather than a confidentiality/integrity breach.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

All formatted output strings returned to the user are hardcoded in Chinese, and the code provides no mechanism to select another language or to confirm that Chinese is desired. This is a natural-language policy concern because it forces a specific language in user-visible responses without opt-in.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

Granting Bash to a fitness logging and planning skill expands its attack surface beyond what is reasonably required for its stated purpose. If the skill or downstream scripts process untrusted user input, Bash access could enable arbitrary command execution, file manipulation, or abuse of the local environment, especially since the skill also has Read, Write, WebFetch, and WebSearch permissions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The module docstring is entirely in Chinese and presents the skill as a Chinese-language assistant without indicating any language choice or opt-in. This can violate language/locale policy when a skill implicitly forces a specific language for users in a broader environment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

Natural-language descriptions and user-oriented comments/docstrings are presented exclusively in Chinese, with no indication that users can choose another language. Under the policy, forcing a specific language without opt-in can be a locale/language policy issue unless clearly justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

This code writes generated report content to a local HTML file via Path.write_text, which is a file-modifying operation covered by the warning requirement for code files. While there is a print statement afterward, the write occurs before the disclosure and there is no confirmation prompt or broader comment/docstring warning around the side effect itself.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.