Back to skill

Security audit

AI-Cardiac-Rehab

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent cardiac rehab web app, but it handles sensitive medical data and gives exercise guidance with safety and privacy gaps that warrant careful review.

Review this before installing or using with real patient data. It should be treated as experimental decision support only, not medical authority. Use a clinician-reviewed symptom vocabulary, fix the emergency matching issue, self-host frontend assets or disclose third-party requests, pin dependencies, and add strong local data protections before deployment with sensitive health records.

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)

T09 · Insecure Skill Coding Practices

Warning
Location
app.py:217
Finding

Sensitive Medical Records Stored in Plaintext

Content
View full analysis
Remediation
View remediation

other

Error
Location
app.py:88
Finding

Emergency Symptom Detection Does Not Match the Documented User Input

Content
View full analysis
症状(可多选,用逗号分隔) ``` ### Technical Analysis The input form explicitly suggests the value `呼吸困难` (“shortness of breath”), but the red-alert detector only recognizes the more specific substring `呼吸困难静息` (“shortness of breath at rest”). Because the suggested value is not a substring of the detector's longer expected phrase, a user who follows the UI guidance can report shortness of breath without triggering the emergency path. Symptoms are accepted as unrestricted text and evaluated through exact substring matching. There is no canonicalization layer, structured symptom identifier, synonym mapping, or fallback review for unrecognized symptom text. This makes the safety behavior dependent on users entering the precise phrases embedded in the source code. This conflicts with the Skill's declared behavior that high-risk symptoms automatically block exercise. ### Attack Path 1. A patient experiences shortness of breath. 2. The patient enters `呼吸困难`, exactly as suggested by the form placeholder. 3. `check_symptom_alerts()` checks for `呼吸困难静息`, which does not match the submitted text. 4. No red flag is added for that symptom. 5. `ai_safe_cardiac_rehab()` does not activate its symptom-based contraindication branch. 6. If no ot ...[truncated 768 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unbounded and Non-Reproducible Third-Party Dependencies

Content
View full analysis
=2.0 ``` The same broad constraint is present in `package.json`: ```json "dependencies": { "flask": ">=2.0" } ``` The installation documentation also resolves packages without a lock file or hash verification: ```bash pip install flask python app.py ``` ```bash pip install gunicorn gunicorn -w 2 -b 127.0.0.1:5000 app:app ``` ### Technical Analysis The lower-bound-only constraint permits any future Flask version. The Gunicorn installation instructions do not specify a version at all. The project contains no lock file and no cryptographic hashes for downloaded Python distributions. The named packages and default package source are not inherently suspicious, and no dependency-confusion or typosquatting package was identified. The risk arises because installations are not reproducible: package behavior can change after the Skill has been reviewed, and a future compromised, incompatible, or maliciously modified allowed release could be installed automatically. ### Attack Path 1. A user follows the documented installation process. 2. The package manager resolves the newest release satisfying `flask>=2.0`, or the newest available Gunicorn release. 3. A future allowed release contains a security regression, incompatible behavior, or compromised code. 4. The affected package is downloaded and installed without lock-file or hash verification. 5. Package code executes during installation or when the application starts. 6. The compromised dependency receives the permissions of the user running the installation or service. This is a supply-chain exposure rather than evidence that the currently named dependencies are malicious. ### Impact Assessment The maximum privilege scope is the privilege of the account performing installation or running the web service. In a least- ...[truncated 306 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (10)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The API spec describes an AI system that ingests sensitive cardiac health data and produces automated risk stratification, exercise prescriptions, medication reminders, and safety warnings, but it provides no warning about the sensitivity of patient data, the limits of automated medical recommendations, or the need for clinician oversight. In a cardiac rehabilitation context, omitted cautions can lead users or integrators to over-trust the system, increasing the chance of unsafe exercise guidance, missed urgent care escalation, or privacy mishandling of health information.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest description and the full user-facing SKILL.md content are written in Chinese, and the file does not indicate that the skill is region-specific or that users may choose another language. This can violate a language/locale policy when skills are expected to avoid forcing a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The entire user-facing guide is written only in Chinese, with no indication that language selection is optional or that the skill is intentionally limited to a Chinese-speaking audience. This creates a natural-language locale policy issue because it imposes a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documented privacy assurance is materially inconsistent with actual behavior: external CDN-hosted assets cause outbound requests despite the statement that data is not uploaded to the cloud. In a healthcare-facing app, this mismatch can create privacy, compliance, and trust risks because users may rely on the promise of fully local operation when entering sensitive health information.

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 UI, warnings, and instructions are entirely in Chinese, beginning with the module description and continuing throughout the application. There is no indication that users may choose another language, nor is there a documented justification that this skill is intended only for a Chinese-language or region-specific audience.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code claims that data stays local and is not uploaded to the cloud, but the HTML template loads Bootstrap and Chart.js from jsDelivr CDNs. Even if patient data is not explicitly sent in requests, browser visits to a third-party CDN disclose metadata such as client IP address, user agent, access timing, and referrer, which is especially sensitive in a medical context because it can reveal use of a cardiac rehab application.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The package description is written entirely in Chinese, which indicates a language-specific presentation in the skill metadata. There is no accompanying indication that the skill is region-specific or that users can opt into this locale, so it may conflict with a language-choice policy.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency is specified as flask>=2.0, which allows any future major or minor release to be installed and makes builds non-reproducible. This increases supply-chain risk and can unexpectedly pull in vulnerable or breaking versions of Flask, which is especially concerning for a healthcare-oriented web application that may process sensitive patient data.

Content

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

text
flask>=2.0

Unverifiable Dependency: flask has 10 known advisory(ies) (CVE-2025-47278 (Flask uses fallback key instead of current signing key); CVE-2018-1000656 (Flask is vulnerable to Denial of Service via incorrect encoding of JSON data); CVE-2019-1010083 (Pallets Project Flask is vulnerable to Denial of Service via Unexpected memory u) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding

Because the manifest does not pin Flask to a specific version, it is impossible to verify whether the deployed package includes fixes for known Flask advisories. In practice, this means the application may install a release affected by denial-of-service or signing-key related issues, creating avoidable uncertainty in a medical web application's security posture.

Content

No source excerpt is available for this finding.