Back to skill

Security audit

Health Assistant

Security checks for vulnerabilities and agentic risk

Overview

This health assistant is purpose-aligned but handles sensitive health data with inconsistent privacy claims and broad setup behavior, so users should review it carefully before installing.

Install only if you are comfortable linking Garmin and Google/NotebookLM, sending detailed wearable health metrics and health concerns to an external AI service, and retaining local health history/log files. Review the dependency installation path, disable or adjust the daily cron if undesired, and do not rely on the current reset command to remove all local health data.

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 (5)

T08 · Insecure Dependencies

Error
Location
requirements.txt:1
Finding

Automatic Installation of Unpinned Third-Party Dependencies

Content
View full analysis
=0.1.0 notebooklm-py>=0.3.0 ``` `install.sh:22-36`: ```bash pip install --upgrade pip if [ -f "requirements.txt" ]; then pip install -r requirements.txt else # 至少安装 garth pip install garth fi # 3. 检查并安装 notebooklm-py 及其依赖 echo "📦 安装 notebooklm-py 及浏览器驱动..." pip install "notebooklm-py[browser]" # 4. 自动下载 Playwright 所需的 Chromium 浏览器 echo "🌐 正在下载 Chromium 浏览器内核 (用于 AI 登录)..." python3 -m playwright install chromium ``` `src/env_checker.py:35-43`: ```python @staticmethod def run_install(): """执行安装脚本并返回结果""" try: # 使用 sys.executable 确保在同一个 python 环境下安装 print("Installing dependencies...") subprocess.check_call([sys.executable, "-m", "pip", "install", "notebooklm-py[browser]"]) print("Downloading browser core...") subprocess.check_call([sys.executable, "-m", "playwright", "install", "chromium"]) ``` ### Technical Analysis The application installs packages using lower-bound version constraints rather than exact, verified versions. It also downloads the current Playwright Chromium build without an application-controlled checksum or artifact lock. Python package installation can execute package build and installation logic. Consequently, the effective code installed by this Skill may differ from the code reviewed during the audit. The runtime setup flow makes this especially significant because a user can trigger package installation by replying affirmatively to the interactive setup prompt. This finding does not establish that the named packages are malicious. The vulnerability is that the Skill has no reproducible dependency lock, hash verification, or upper version boundary to protect it from a compromise ...[truncated 1207 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/main.py:22
Finding

Sensitive Health History and Full Reports May Be Created with Permissive File Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/setup_handler.py:111
Finding

Persistent User-Controlled Health Concerns Can Inject Instructions into the AI Prompt

Content
View full analysis
str: """处理用户对健康关切的回应""" mapping = { 'A': 'Improve Sleep', 'B': 'Weight Management', 'C': 'Stress Relief', 'D': 'Boost Energy', 'E': 'Specific Condition' } selected = [] msg_upper = message.upper() for key, value in mapping.items(): if key in msg_upper: selected.append(value) # 如果没有字母匹配,且长度大于1,尝试当作自定义描述 if not selected: if 'F' in msg_upper or len(message) > 2: selected.append(message.replace('F', '').replace('f', '').strip()) if not selected: return "Sorry, I didn't quite get that. Please select an option (A-F) or explicitly tell me your primary wellness goal." # 更新配置 self.config.health_concerns = list(set(self.config.health_concerns + selected)) ``` `src/report_generator.py:17-22`: ```python def _format_concerns(self) -> str: """格式化健康关切""" concerns = self.user_config.health_concerns conditions = [c['condition'] for c in self.user_config.specific_conditions] all_concerns = list(set(concerns + conditions)) return "\n".join([f"- {c}" for c in all_concerns]) ``` `src/report_generator.py:64-65`: ```python prompt = format_base_prompt( USER_CONCERNS=self._format_concerns(), ``` `src/prompts/base.py:8-12`: ```python BASE_PROMPT = """【Role & Objective】 You are a Health Advisor with a strong background in Functional Medicine. Your task is to provide personalized, science-backed daily health recommendations based on the user's authentic wearable device data. ## User Health Concerns {USER_CONCERNS} ``` ### Technical Analysis Custom co ...[truncated 1989 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/report_generator.py:64
Finding

Privacy Documentation Conflicts with External Transmission and Identifier Retention

Content
View full analysis
Optional[str]: """调用 NotebookLM CLI 获取建议""" import tempfile ...[truncated 4200 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/config.py:102
Finding

Reset Operation Leaves Health History and Report Logs Behind

Content
View full analysis
bool: """重置配置(删除配置文件)""" try: if CONFIG_FILE.exists(): CONFIG_FILE.unlink() return True except Exception as e: print(f"重置配置失败: {e}") return False ``` The separate retained files are defined in `src/main.py:22-32`: ```python LOG_DIR = Path.home() / ".openclaw" / "logs" LOG_DIR.mkdir(parents=True, exist_ok=True) logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(LOG_DIR / "health-assistant.log"), logging.StreamHandler(sys.stdout) ] ) logger = logging.getLogger("HealthAssistant") HISTORY_FILE = CONFIG_DIR / "history.json" ``` ### Technical Analysis The reset command calls `reset_config()`, which deletes only `config.json`. It does not delete `history.json` or the log containing full generated reports. This behavior conflicts with the documented claim that reset clears local histories and preferences. Following reset, a user may reasonably believe that sensitive health information has been removed even though historical biometric data and report content remain on disk. ### Attack Path 1. The application generates daily reports and stores health records in `history.json` and report content in the log. 2. The user sends the documented `reset` command to clear local information. 3. `reset_config()` deletes only `config.json`. 4. The history and log files remain in their original locations. 5. A later local reader, backup process, subsequent installation, or compromised process accesses the retained health information. ### Impact Assessment The vulnerability causes unintended retention of sensitive health hist ...[truncated 231 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (40)

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The PRD claims that personal identity information such as email is not stored, but the onboarding flow requires collecting a Garmin account email and indicates local storage of device credentials. This inconsistency can lead to undeclared storage of personal identifiers and authentication-related data, increasing privacy risk and exposing the system to compliance failures if users rely on the false statement.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The PRD asserts that all health data remains local and is not uploaded to the cloud, yet the design explicitly sends health data and user health concerns to NotebookLM, an external service. This creates a serious privacy and trust issue because sensitive biometric and health-related data leaves the local environment despite the product's stated guarantees, potentially triggering regulatory and consent problems.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

Prompting for Google and Garmin authentication, installing NotebookLM/Playwright, and collecting account email and preferences locally are significant behaviors not adequately reflected by the declared purpose of daily health insight generation. This undermines informed consent and creates combined privacy and account-security risk through credential handling, third-party dependencies, and local storage of sensitive setup data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

Prompting for Google and Garmin authentication, installing NotebookLM/Playwright, and collecting account email and preferences locally are significant behaviors not adequately reflected by the declared purpose of daily health insight generation. This undermines informed consent and creates combined privacy and account-security risk through credential handling, third-party dependencies, and local storage of sensitive setup data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Prompting for Google and Garmin authentication, installing NotebookLM/Playwright, and collecting account email and preferences locally are significant behaviors not adequately reflected by the declared purpose of daily health insight generation. This undermines informed consent and creates combined privacy and account-security risk through credential handling, third-party dependencies, and local storage of sensitive setup data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Prompting for Google and Garmin authentication, installing NotebookLM/Playwright, and collecting account email and preferences locally are significant behaviors not adequately reflected by the declared purpose of daily health insight generation. This undermines informed consent and creates combined privacy and account-security risk through credential handling, third-party dependencies, and local storage of sensitive setup data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

Prompting for Google and Garmin authentication, installing NotebookLM/Playwright, and collecting account email and preferences locally are significant behaviors not adequately reflected by the declared purpose of daily health insight generation. This undermines informed consent and creates combined privacy and account-security risk through credential handling, third-party dependencies, and local storage of sensitive setup data.

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 · src/prompts/base.py (reported line 54)May include surrounding context.

python
- Vigorous: {INTENSITY_VIGOROUS} mins
- Weekly Goal: {INTENSITY_GOAL} mins

## Research & Output Directives

Please analyze the data above and output today's health suggestions.
**CRITICAL INSTRUCTION: You MUST write the entire analysis and response in English.**

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 · PRD.md (reported line 276)May include surrounding context.

md
ANALYSIS_MODULES=analysis_modules
        )
        
        return prompt

    def call_notebooklm(self, prompt: str) -> Optional[str]:
        """调用 NotebookLM CLI 获取建议"""

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 · src/report_generator.py (reported line 91)May include surrounding context.

python
ANALYSIS_MODULES=analysis_modules
        )
        
        return prompt

    def call_notebooklm(self, prompt: str) -> Optional[str]:
        """调用 NotebookLM CLI 获取建议"""

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file presents all user-facing instructions, prompts, and examples exclusively in Chinese, including onboarding dialogue and review instructions. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly justified, which is not stated here.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

At L043 the documentation states the assistant 'only requests read permissions,' which conveys a read-only posture. However, L135 explicitly says users can say reset to clear local histories and preferences, which is a write/delete side effect and contradicts the earlier claim rather than merely omitting detail.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README makes strong privacy assurances about no third-party data transfer, but the skill explicitly relies on Google NotebookLM for analysis. In a health-data context, this can mislead users about where sensitive biometric information is sent and processed, undermining informed consent and increasing privacy/compliance risk if users share data assuming it stays local.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill declares executable behavior via cron and command usage, and its documented dependencies imply shell execution, local credential storage, and filesystem interaction, yet it defines no explicit tool scope or permissions boundary. That creates unnecessary ambiguity around what the skill may access and makes review, sandboxing, and user consent weaker, especially for a health-focused skill handling sensitive data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill description does not clearly warn that sensitive health and biometric data may be synced automatically on a daily schedule. For a health assistant, missing notice around automated collection and processing weakens informed consent and increases the likelihood of unintended privacy exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill notes use of a messaging plugin for Telegram, Discord, WeChat, or Feishu, but the description omits a clear warning that generated health reports may be transmitted to third-party platforms. In this context, that omission is especially dangerous because medical-adjacent summaries and biometric insights may leave the local environment and be subject to weaker privacy controls on external services.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The final user-facing instruction tells the user to send the Chinese phrase '生成健康报告' to use the feature. This imposes a specific language for invocation and there is no indication elsewhere in the file that alternative languages are supported or that the user can opt in to this locale constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The default preference sets the timezone to "Asia/Shanghai", which embeds a specific locale choice directly into the skill behavior. Under the policy, forcing a language or locale without user opt-in is a natural-language policy concern unless the constraint is clearly documented and justified as region-specific.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file's core behavior is not health-data analysis but setup for NotebookLM, Playwright, and local session detection, which is materially inconsistent with the skill description. This context makes the code more dangerous because users expecting a benign health coach may unknowingly run software that prepares unrelated automation and leverages existing local authentication state.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code probes for a NotebookLM session file in the user's home directory, indicating awareness of and interest in an unrelated authenticated session. In the context of a health assistant, checking for a separate service's login state is suspicious because it can facilitate unauthorized use of an existing session or silent access to data outside the skill's stated scope.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The environment checker installs Playwright and Chromium even though the skill is presented as a Garmin and health-data analysis assistant. This mismatch between declared purpose and implementation is dangerous because it introduces unnecessary browser automation capability, which increases system risk and may support unrelated data access or automation.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
88% confidence
Finding

This code executes package installation at runtime via pip, which causes the skill to modify the host environment and fetch code from external package sources. Even though the command arguments are hardcoded and not shell-injected, it still creates a supply-chain and unexpected-code-execution risk, especially in an agent skill that users may invoke without expecting system changes.

Content

Scanner excerpt · src/env_checker.py (reported line 40)May include surrounding context.

python
try:
            # 使用 sys.executable 确保在同一个 python 环境下安装
            print("Installing dependencies...")
            subprocess.check_call([sys.executable, "-m", "pip", "install", "notebooklm-py[browser]"])
            
            print("Downloading browser core...")
            subprocess.check_call([sys.executable, "-m", "playwright", "install", "chromium"])

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
84% confidence
Finding

This subprocess downloads and installs a Chromium browser runtime onto the host system. Installing browser automation components at runtime expands attack surface, changes the local environment, and can enable later automated browsing actions not obviously related to the advertised health-coaching purpose.

Content

Scanner excerpt · src/env_checker.py (reported line 43)May include surrounding context.

python
subprocess.check_call([sys.executable, "-m", "pip", "install", "notebooklm-py[browser]"])
            
            print("Downloading browser core...")
            subprocess.check_call([sys.executable, "-m", "playwright", "install", "chromium"])
            
            return True, "Installation successful"
        except Exception as e:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This client retrieves highly sensitive biometric and sleep data from Garmin over the network, but the code provides no user-facing notice, consent flow, or explanation of how that data will be accessed, processed, or stored. In a health-assistant context, silent collection of personal health data increases privacy and compliance risk because users may not understand the scope of access or the sensitivity of the information being handled.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file’s natural-language strings and descriptions indicate the skill is intended to operate in Chinese, including command phrases and user-facing help text, but there is no opt-in or documented language selection. This can violate language/locale policy when users are not given a choice or the locale restriction is not justified.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.