Back to skill

Security audit

ECG-AI-Diagnosis

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed cloud ECG-analysis connector, but users should understand that ECG data is sent to HeartVoice's external API.

Install only if you are comfortable sending ECG signal data to HeartVoice's cloud API and storing a HEARTVOICE_API_KEY in the runtime environment. Use it for user-directed ECG file analysis, confirm before uploading real medical data, avoid including identifying metadata in JSON files, and consider pinning dependencies in an isolated environment.

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

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unpinned Third-Party Dependency Permits Supply-Chain Drift

Content
View full analysis
=2.20.0 ``` `README.md:47-49`: ```bash pip install -r requirements.txt ``` `SKILL.md:27-28`: ```bash pip install requests ``` ### Technical Analysis The dependency specification accepts any `requests` release newer than or equal to version 2.20.0. No lock file or cryptographic package hashes are provided. The direct installation command in `SKILL.md` is even less restrictive. Consequently, installations are not reproducible and depend on the package index, resolver state, and available package versions at installation time. A compromised package repository, maliciously configured index, compromised eligible release, or future incompatible release could introduce unintended code into the Skill's environment. This is a supply-chain hardening weakness rather than evidence that the current `requests` package is malicious. ### Attack Path 1. A user follows the documented installation instructions. 2. `pip` contacts the configured package index or mirror. 3. The resolver selects any eligible version because the dependency is not pinned. 4. If the index, mirror, eligible artifact, or dependency chain has been compromised, the malicious package is downloaded and installed. 5. Package installation or imported runtime code executes with the privileges of the user running `pip` or the Skill. 6. When the Skill subsequently runs, compromised dependency code could access the HeartVoice API token, ECG payloads, API responses, and other resources available to that process. Successful exploitation requires compromise or malicious control of a configured package source or eligible dependency artifact; the repository itself does not contain such a payload. ### Impact Assessment M ...[truncated 527 chars]
Remediation
View remediation
``` 2. Pin all transitive dependencies using a lock-generation tool such as `pip-tools`. 3. Generate and verify cryptographic hashes: ```bash pip-compile --generate-hashes requirements.in pip install --require-hashes -r requirements.txt ``` 4. Replace the unrestricted command in `SKILL.md` with installation from the reviewed, hash-locked requirements file. 5. Document that dependencies must be downloaded from the official PyPI index or an approved internal mirror. 6. Use automated dependency scanning and periodically update pinned versions after security review. 7. Install and run the Skill as a non-privileged user in an isolated virtual environment or container to limit the impact of a compromised dependency. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (13)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · .gitignore (reported line 2)May include surrounding context.

text
# Environment & secrets
.env
.env.*

# Python

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill uses sensitive capabilities—environment variable access, local file reads, and outbound network transmission—but does not declare an explicit tool/permission scope. That omission weakens least-privilege controls and makes it harder for the host system or reviewer to constrain what the skill is allowed to access, especially given it handles sensitive medical data and an API key.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The top-level description advertises many common keywords as triggers without clear boundaries, increasing the chance that the skill is selected in contexts where the user did not intend cloud analysis. In this case, unintended activation is more serious because the skill processes sensitive medical information and sends it off-device to an external service.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The activation guidance uses broad medical and ECG-related phrases that can cause the skill to run on loosely related conversations or files without sufficient confirmation. Because this skill reads local files and transmits ECG data to a third-party cloud API, accidental invocation could expose sensitive health data or trigger unintended external requests.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
78% confidence
Finding

The skill transmits ECG data to an external API endpoint, which is an external data transfer of sensitive medical information. Although this appears to be the intended function and the documentation discloses the data flow, it still creates privacy and compliance risk if users are not clearly informed and consent is not obtained before transmission.

Content

Scanner excerpt · SKILL.md (reported line 299)May include surrounding context.

md
data = load_json("data/example_1lead.json")
payload = build_1lead_payload(data)
raw_result = call_api(
    "https://api.heartvoice.com.cn/api/v1/basic/ecg/1-lead/analyze",
    payload, api_key
)
output = format_1lead_result(raw_result)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · README.md (reported line 121)May include surrounding context.

md
# ── API Endpoints ─────────────────────────────────────────────────────────────

API_1LEAD  = "https://api.heartvoice.com.cn/api/v1/basic/ecg/1-lead/analyze"
API_12LEAD = "https://api.heartvoice.com.cn/api/v1/basic/ecg/12-lead/analyze"

REQUIRED_1LEAD = {"ecgData", "ecgSampleRate", "adcGain", "adcZero"}

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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/call_api.py (reported line 24)May include surrounding context.

python
# ── API Endpoints ─────────────────────────────────────────────────────────────

API_1LEAD  = "https://api.heartvoice.com.cn/api/v1/basic/ecg/1-lead/analyze"
API_12LEAD = "https://api.heartvoice.com.cn/api/v1/basic/ecg/12-lead/analyze"

REQUIRED_1LEAD = {"ecgData", "ecgSampleRate", "adcGain", "adcZero"}

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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/call_api.py (reported line 25)May include surrounding context.

python
# ── API Endpoints ─────────────────────────────────────────────────────────────

API_1LEAD  = "https://api.heartvoice.com.cn/api/v1/basic/ecg/1-lead/analyze"
API_12LEAD = "https://api.heartvoice.com.cn/api/v1/basic/ecg/12-lead/analyze"

REQUIRED_1LEAD = {"ecgData", "ecgSampleRate", "adcGain", "adcZero"}

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

This code performs an outbound HTTPS POST containing ECG data to an external domain. In the context of a medical-analysis skill, that transmission is security-relevant because it exports sensitive health information and depends on a third-party processor, increasing privacy, compliance, and data-handling risk if done without strong disclosure and controls.

Content

Scanner excerpt · scripts/call_api.py (reported line 69)May include surrounding context.

python
"Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    }
    response = requests.post(endpoint, headers=headers, json=payload, timeout=60)
    response.raise_for_status()
    result = response.json()
    error_code = str(result.get("errorCode", result.get("code", "0")))

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script sends raw ECG payloads to a third-party cloud API, which involves highly sensitive health data and may also include identifying metadata if present in the input JSON. There is no explicit user-facing consent, privacy notice, destination disclosure at runtime, or minimization/redaction step before transmission, so users or higher-level agents could unknowingly exfiltrate medical data off-system.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency is specified as requests>=2.20.0, which allows any newer version to be installed without a tested upper bound or exact pin. This weakens build reproducibility and can unintentionally pull in vulnerable or behavior-changing releases, especially in a network-facing skill that likely sends ECG data to an external API.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.20.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding

Because the manifest does not pin the requests version, it is impossible to verify whether deployment will use a release affected by known advisories. In a skill that likely performs outbound HTTP requests and may handle sensitive medical ECG-related data, uncertainty around the exact HTTP client version increases supply-chain and data-handling risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The CLI hard-codes Chinese as the default output language via default="zh". This is a natural-language policy concern because it forces a specific language choice unless the user overrides it, rather than prompting or detecting preference.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.