Back to skill

Security audit

Symptom Checker Triage

Security checks for vulnerabilities and agentic risk

Overview

This medical triage skill is purpose-aligned, but it can under-triage serious symptoms and has avoidable install and disclosure issues users should review before relying on it.

Install only if you treat it as a rough demonstration tool, not a dependable triage system. Review and fix the case-insensitive matching, Chinese-support claim, low-confidence fallback behavior, and default disclaimer display before using it in any real medical workflow; remove the unnecessary requirements entries or pin any future dependencies.

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

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unnecessary and Unpinned Third-Party Dependencies Create Supply-Chain Exposure<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-2` **Vulnerability Type**: Unpinned and unnecessary dependencies **Risk Level**: Medium ### Vulnerable Code ```text dataclasses enum ``` ### Technical Analysis The project declares `dataclasses` and `enum` as third-party dependencies without version constraints or integrity hashes. Both capabilities are already provided by the Python standard library for the documented Python 3.8+ runtime. This contradicts the statement in `SKILL.md` that the project has no third-party dependencies. Installing these packages unnecessarily expands the software supply chain and allows the package manager to resolve mutable releases from its configured package index. Package installation can execute package build logic, and installed packages may shadow or otherwise interfere with standard-library modules. The audit did not establish that the currently published packages are malicious. The vulnerability is the avoidable and uncontrolled dependency-resolution path. ### Attack Path 1. A user or deployment process runs `pip install -r requirements.txt`. 2. The package manager resolves `dataclasses` and `enum` from its configured public or private package index without enforcing an exact version or artifact hash. 3. A compromised package release, malicious index mirror, dependency-confusion package, or incompatible future release is downloaded. 4. Package build or installation code executes with the privileges of the installation process. 5. The installed modules may execute malicious setup logic, alter the environment, or affect later imports. ### Impact Assessment The potential privileges are those of the user, virtual environment, container build, or CI worker performing installation. Depending on that context, a compromised dependency could access source code, environment variables, CI credentials, writable files, and network resources. The affected scope includes development environments, deplo ...[truncated 173 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove both entries because Python 3.8+ already provides `dataclasses` and `enum`. 2. Delete `requirements.txt` if the project has no external dependencies, or leave it empty with an explanatory comment if tooling requires the file. 3. If external dependencies are introduced later: - Pin exact, reviewed versions. - Use a lock file or requirements file containing artifact hashes. - Install only from trusted package indexes. - Scan dependency artifacts and monitor vulnerability advisories. - Use an isolated, least-privileged build environment. 4. Add a CI check that verifies the dependency manifest remains consistent with the dependency claims in `SKILL.md`. ]]>

other

Error
Location
scripts/main.py:148
Finding
Case-Sensitive Symptom Matching Can Miss Emergency Red Flags<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py:148-155` **Vulnerability Type**: Unsafe medical-triage input normalization **Risk Level**: High ### Vulnerable Code ```python def extract_red_flags(text: str) -> List[Tuple[str, TriageLevel, float, str, str]]: """Extract red flags from symptom description""" expanded_text = expand_synonyms(text) found_flags = [] for keyword, (name, level, weight, dept, reason) in RED_FLAGS.items(): if keyword in expanded_text: found_flags.append((name, level, weight, dept, reason)) ``` A related instance occurs in `extract_outpatient_symptoms` at `scripts/main.py:191-223`: ```python text_lower = text.lower() # Check temperature first temperature = calculate_temperature(text) for keyword, (name, level, weight, dept, reason) in OUTPATIENT_SYMPTOMS.items(): if keyword in text: found.append((name, level, weight, dept, reason)) ``` ### Technical Analysis All configured symptom and red-flag keywords are lowercase, but `extract_red_flags` performs substring matching against the original, non-normalized input. Consequently, inputs such as `Chest pain` do not match the configured `chest pain` rule. The outpatient extraction function computes `text_lower` but does not use it, repeating the same case-sensitivity defect. If no rule matches, `triage()` falls through to an outpatient result with a confidence of `0.30`, even when the differently capitalized input describes an emergency. This also conflicts with documented examples that capitalize symptom descriptions. In addition, `SKILL.md` claims support for English and Chinese input, while the reviewed rule tables contain only English terms. Unsupported Chinese input can therefore follow the same unrecognized-symptom fallback. ### Attack Path 1. A user supplies an emergency symptom using capitalization, such as `Chest pain`. 2. `expand_synonyms()` preserves the capitalization because its replacements are als ...[truncated 1061 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Normalize the input exactly once before every textual comparison: ```python normalized_text = text.casefold() expanded_text = expand_synonyms(normalized_text) ``` 2. Use the normalized value consistently in `extract_red_flags`, `extract_outpatient_symptoms`, synonym expansion, and temperature-related keyword matching. 3. Prefer boundary-aware matching rather than unrestricted substring matching to reduce accidental partial matches. 4. Add explicit handling for negation, such as “no chest pain,” so normalization does not introduce additional false positives. 5. Either implement and test Chinese symptom mappings or remove the unsupported Chinese-language claim from `SKILL.md`. 6. Add automated tests covering: - Lowercase, title-case, and uppercase variants. - Every documented CLI example. - Synonyms in mixed case. - Punctuation and surrounding prose. - Negated symptoms. - Unsupported and ambiguous inputs. 7. For unrecognized symptoms, avoid presenting outpatient care as an affirmative triage conclusion. Clearly state that the tool could not classify the input and recommend prompt professional assessment, particularly when confidence is low. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Missing User Warnings

High
Confidence
97% confidence
Finding
This tool provides concrete medical triage advice such as 'Proceed to emergency immediately' or 'Schedule an outpatient appointment,' but the user-facing disclaimer is only shown in verbose mode and omitted from normal and JSON output. In a medical decision-support context, inconsistent warnings can cause users to over-trust the output as diagnostic or authoritative guidance, increasing the risk of delayed care or inappropriate self-triage.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The markdown states that the skill accepts natural language symptom descriptions only in English or Chinese. This imposes a language constraint as a policy choice, but the file does not present it as an optional preference or justify it as a documented region-specific limitation.

Unpinned Dependencies

Low
Category
Supply Chain
Content
dataclasses
enum
Confidence
60% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
dataclasses
enum
Confidence
60% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Static analysis

No suspicious patterns detected.