Back to skill

Security audit

Mxyj Heartplus Ecg

Security checks for vulnerabilities and agentic risk

Overview

The skill’s Heart+ ECG workflow is coherent, but it needs Review because it downloads and runs an opaque native helper while handling sensitive phone and health-report data with weak local scoping.

Review before installing. Use this only if you trust the Heart+ publisher and are comfortable with a downloaded native helper running locally, mobile-number-linked requests to the Heart+ service, and plaintext local session/report caches. Avoid using it on shared machines or shared agent workspaces, and treat ECG output as informational rather than medical diagnosis.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/gateway_manager.py:148
Finding

Automatic Download and Execution of an Opaque Native Binary

Content
View full analysis
Path: if not spec.url: raise SkillError( "Security program download URL is missing.", {"platform": spec.platform_key, "url": spec.url}, ) BIN_DIR.mkdir(parents=True, exist_ok=True) target = BIN_DIR / spec.filename try: with urllib.request.urlopen(spec.url, timeout=30) as resp: data = resp.read() target.write_bytes(data) except (urllib.error.URLError, TimeoutError, OSError) as e: raise SkillError( "Security program download failed.", {"url": spec.url, "reason": str(e)}, ) if spec.sha256: actual = self._sha256(target) if actual != spec.sha256.lower(): raise SkillError( "Downloaded file verification failed.", { "expected": spec.sha256, "actual": actual, "file": str(target), }, ) if platform.system().lower() != "windows": mode = target.stat().st_mode target.chmod(mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) return target ``` ```python def run(self, subcommand: str, args: list[str], timeout: int = 20) -> dict: bin_path = self.ensure_binary(auto_download=True) cmd = [str(bin_path), subcommand, *args] result = subprocess.run( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=timeout, env=self._build_subprocess_env(), ) ``` The configured executable sources include URLs such as: ```json { "arch": "linux-amd64", "url": "https://aigc-online.oss- ...[truncated 2778 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/config_manager.py:74
Finding

Caller-Controlled Session Keys Select Other Sessions' Sensitive State

Content
View full analysis
str: resolved_session_key = self.resolve_session_key(session_key) config = self.load_json() phones_by_session_key = config.get("phones_by_session_key") if not isinstance(phones_by_session_key, dict): phones_by_session_key = {} return str( phones_by_session_key.get(resolved_session_key, "") ).strip() ``` ```python def is_session_authorized(self, session_key: Any = None) -> bool: resolved_session_key = self.resolve_session_key(session_key) config = self.load_json() session_auth_by_session_key = config.get( "session_auth_by_session_key" ) if not isinstance(session_auth_by_session_key, dict): return False return bool( session_auth_by_session_key.get(resolved_session_key, False) ) ``` The session-key validation only enforces superficial formatting before returning the caller-provided value: ```python normalized = str(session_key).strip() if not normalized: raise SkillError(...) if " " in normalized or "\t" in normalized or "\n" in normalized: raise SkillError(...) if ":" not in normalized: raise SkillError(...) return SESSION_KEY_ALIASES.get(normalized, normalized) ``` ### Technical Analysis The session key is used as the lookup key for mobile numbers, authorization flags, authorization metadata, and recent report-number mappings. However, the code does not cryptographically or operationally bind the supplied key to the currently authenticated Agent session. Any string containing a colon and no whitespace can pass validation. The documentation also permits a user to provide a session key explicitly, while examples such as ...[truncated 1789 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config_manager.py:44
Finding

Sensitive Account and Health Metadata Is Stored and Printed in Plaintext

Content
View full analysis
bool: temp_file = self.config_file.with_suffix( f"{self.config_file.suffix}.tmp" ) try: self.config_file.parent.mkdir(parents=True, exist_ok=True) with temp_file.open("w", encoding="utf-8") as f: json.dump(data, f, indent=4, ensure_ascii=False) temp_file.replace(self.config_file) return True except Exception as e: raise SkillError(...) ``` ```python normalized_phone = str(phone).strip() previous_phone = str( phones_by_session_key.get(resolved_session_key, "") ).strip() phones_by_session_key[resolved_session_key] = normalized_phone config["phones_by_session_key"] = phones_by_session_key ``` ```python session_auth_by_session_key[resolved_session_key] = bool(authorized) config["session_auth_by_session_key"] = session_auth_by_session_key ``` ```python sessions[self.session_key] = { "updated_at": now_str, "report_nos": report_nos, } ``` The command-line interface prints the complete stored mobile number: ```python if args.action == 'get': phone = manager.get_phone() print(f"{phone}") elif args.action == 'save': if not args.phone: raise SkillError(...) phone = manager.save_phone(args.phone) print(f"{phone}") ``` ### Technical Analysis The Skill stores mobile numbers, session identifiers, local authorization status, authorization timestamps, and recent report numbers in project-local JSON files. The files are created with normal Python file operations and inherit permissions from the process umask. The code does not explicitly enforce owner-only permissions, encrypt sensitive fields, define re ...[truncated 1438 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/template_renderer.py:191
Finding

Untrusted Report Data Is Forwarded as Unsanitized Markdown and Unsafe Links

Content
View full analysis
str: text = TemplateRenderer._clean_text(value) if not text: return "--" return text ``` Remote values are inserted into the rendering context: ```python context = { "ecg_result": self._to_display(detail.ecgResult), "abnor_analysis": self._to_display(detail.abnorAnalysis), "result_tz": self._to_display(detail.ecgResultTz), "suggestion": self._to_display(detail.suggestion, ""), "health_care_advice": self._to_display( detail.healthCareAdvice, "", ), "report_pdf_url": self._clean_url(detail.reportPdf), } ``` The URL is rendered directly as a clickable Markdown link: ```markdown ### Report Download [Download the complete PDF report]({{ report_pdf_url }}) ``` The Skill instructions require report output to be reproduced verbatim and prohibit modification, omission, or security filtering. ### Technical Analysis Repor ...[truncated 2586 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (43)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is presented as a health-management assistant but also directs downloading and executing local binaries, performing authorization-code verification, and running security-check flows. Those privileged execution and trust-establishment behaviors materially increase risk, and the mismatch makes them harder for users and reviewers to anticipate or scrutinize.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is presented as a health-management assistant but also directs downloading and executing local binaries, performing authorization-code verification, and running security-check flows. Those privileged execution and trust-establishment behaviors materially increase risk, and the mismatch makes them harder for users and reviewers to anticipate or scrutinize.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill is presented as a health-management assistant but also directs downloading and executing local binaries, performing authorization-code verification, and running security-check flows. Those privileged execution and trust-establishment behaviors materially increase risk, and the mismatch makes them harder for users and reviewers to anticipate or scrutinize.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is presented as a health-management assistant but also directs downloading and executing local binaries, performing authorization-code verification, and running security-check flows. Those privileged execution and trust-establishment behaviors materially increase risk, and the mismatch makes them harder for users and reviewers to anticipate or scrutinize.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is presented as a health-management assistant but also directs downloading and executing local binaries, performing authorization-code verification, and running security-check flows. Those privileged execution and trust-establishment behaviors materially increase risk, and the mismatch makes them harder for users and reviewers to anticipate or scrutinize.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/gateway_manager.py (reported line 73)May include surrounding context.

python
@staticmethod
    def _build_subprocess_env() -> dict[str, str]:
        env = dict(os.environ)
        base_path = env.get("PATH", "")
        system = platform.system().lower()
        if system == "darwin":

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README states that the skill only supports users in Mainland China and users with Mainland China mobile numbers. This is a locale/access restriction expressed in natural language, and the file does not present it as an optional user-selected locale or provide a compliance or region-specific justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The prerequisite section repeats that only users with Mainland China phone numbers are supported. Under the policy, forcing a locale or regional constraint without user opt-in or clear documented justification is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares no explicit tool permissions while the document clearly instructs use of shell execution, network access, local file reads/writes, and handling of environment-dependent installers. That combination creates excessive, implicit capability exposure and weakens reviewability, especially because the skill also processes sensitive medical-adjacent and identity data such as phone numbers and session keys.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The description and declaration state that the skill only supports users with Mainland China phone numbers, which is a locale/region restriction expressed in natural language. Under the policy, forcing a specific locale or user region without opt-in or a clearly documented justification is a policy concern.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill can auto-trigger on broad symptom phrases like chest discomfort or palpitations and default into operational actions such as sending measurement notifications. In a health context, broad triggers are riskier because they may collect or act on sensitive health-related intent without sufficiently explicit user confirmation, even though the file does include some high-risk escalation language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The file mandates the statement “当前仅支持中国大陆手机号用户使用本服务”, which imposes a locale/population restriction as a fixed policy. Because the restriction is presented as a blanket requirement rather than a user choice or clearly justified compliance constraint, it matches the language/locale policy concern.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger list includes vague everyday phrases such as '最近不舒服' and '帮我看下心电图', which can cause the skill to enter a medical workflow without clear user intent. In a health context, accidental activation is risky because it can steer users toward ECG measurement or interpretation flows based on weak signals, potentially creating confusion, overcollection of health data, or inappropriate reliance on an automated assistant.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The welcome copy states that the service only supports users with mainland-China phone numbers and immediately asks for confirmation, leaving no user choice or explanation for the restriction. This is a natural-language locale/population policy constraint that is not clearly justified within the 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 text states that users not using a mainland-China phone number cannot continue the service, but does not explain whether this is due to compliance, infrastructure, or product-scope reasons. This is a user-population restriction expressed in natural language without opt-in or clear justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The markdown states that the service only supports users with Mainland China mobile phone numbers. This is a natural-language locale/access restriction, and the file does not provide an opt-in choice or clearly document a compliance or region-specific justification for the constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Line L03 states that the service is only supported for users with mainland China phone numbers. This is a natural-language locale/access restriction, and the file does not present it as an optional user choice or explain a compliance or regulatory justification for the constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The statement "当前仅支持中国大陆手机号用户使用本服务" imposes a locale/region-specific access restriction in natural language. Under the policy, forcing a specific locale or regional constraint without user opt-in or a clearly documented justification is a reportable policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

SQP-3 适用于所有文件类型。L009 明确写明“当前仅支持中国大陆手机号用户使用本服务”,这是语言/locale/地域层面的硬性限制,但文中未向用户提供可选方案,也未说明该限制的合规或系统性必要性。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document states that phone numbers are stored per session and that report list data is written to a local cache file, but it does not define explicit consent, retention, protection, or minimization requirements for this sensitive health-related data. Because the skill handles phone numbers, authorization state, and ECG report references, undocumented local persistence increases the risk of privacy leakage, cross-session exposure, or insecure operator handling.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger list for ECG measurement includes broad symptom and conversational phrases such as palpitations, chest tightness, chest discomfort, and fast heartbeat, which can cause the skill to automatically send measurement notifications on ambiguous input. In a medical context, overly broad routing is risky because it may mis-handle urgent situations, suppress clearer triage, or initiate device workflows without sufficient confirmation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code contains user-facing text stating that the service only supports mainland China mobile users, and the surrounding messages route users to a China App Store download URL. That is a locale/region restriction expressed in natural language, but the file does not indicate user choice, opt-in, or a clearly documented compliance justification for the constraint.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/api_manager.py (reported line 70)May include surrounding context.

python
headers.pop("x-version", None)

        try:
            response = requests.post(
                f"{self.base_url}/mini/api/appleplus/sendCodeOpenclaw",
                headers=headers,
                json=payload,

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/api_manager.py (reported line 179)May include surrounding context.

python
headers = self.get_api_headers()

        try:
            resp = requests.post(
                f"{self.base_url}/mini/h5api/",
                headers=headers,
                json=payload,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This Python file contains natural-language comments and multiple user-facing error strings exclusively in Chinese, such as the configuration and sessionKey validation messages. For a general-purpose skill file, forcing a specific language without offering user choice or documenting a justified locale restriction is a language policy violation under SQP-3.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.