Back to skill

Security audit

FHIR Questionnaire Designer

Security checks for vulnerabilities and agentic risk

Overview

This healthcare questionnaire helper is mostly purpose-aligned, but it needs review because one lookup script can send clinical terms to arbitrary servers and the dependency install is not pinned.

Review and constrain network use before installing. Keep terminology lookups limited to trusted HTTPS FHIR terminology servers, avoid putting patient-identifying details in search terms, and consider pinning dependencies before running setup.sh. Generated questionnaire and CodeSystem files are user-directed local outputs, not hidden persistence.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/query_valueset.py:46
Finding

Unrestricted terminology server allows sensitive query disclosure and unintended network access

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unpinned dependency installation creates a supply-chain and reproducibility risk

Content
View full analysis
=4.0.0 ``` The setup script installs the unresolved requirement directly: ```bash if command -v uv &> /dev/null; then echo "Using uv..." cd "$SKILL_DIR" if [ ! -d ".venv" ]; then uv venv fi uv pip install -r requirements.txt ``` ```bash elif command -v python3 &> /dev/null; then echo "Using python3 venv..." cd "$SKILL_DIR" if [ ! -d ".venv" ]; then python3 -m venv .venv fi .venv/bin/pip install -r requirements.txt ``` ### Technical Analysis The requirement uses a lower bound without an upper bound or exact version. Each installation may therefore resolve to a different future version of `jsonschema` and its transitive dependencies. The setup process also does not use a lock file, package hashes, or an explicitly trusted package index. This makes installation behavior dependent on the current package index, resolver state, and newly published package versions. This is not evidence that the current `jsonschema` package is malicious. The risk is that future package compromise, dependency compromise, incompatible releases, or use of an attacker-controlled package index could introduce unreviewed code into the environment. ### Attack Path 1. A user or automated agent executes `setup.sh`. 2. `pip` or `uv` resolves `jsonschema>=4.0.0` and its transitive dependencies against the configured package index. 3. The resolver selects whatever compatible versions are available at installation time. 4. If a selected release or configured index is compromised, malicious or unsafe package content is downloaded and installed. 5. The installed code runs when the validator imports `jsonschema`, with the privileges of the user running the Skill. ### Impact Assessment A comp ...[truncated 450 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The description emphasizes questionnaire-definition assistance and terminology lookup from official coding APIs for LOINC and SNOMED CT. The actual script serves a different purpose: generating reusable custom CodeSystem and ValueSet FHIR resources under a proprietary Welshare URL base. This is a materially different primary function from code lookup, and it introduces undeclared behavior of generating and saving local resource files. There is no evidence of API access, official terminology lookup, or processing of requirement ideation docs. Therefore the code chunk does not accurately match the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description emphasizes generation of FHIR questionnaire definitions from plain-text requirement ideation documents and code lookup utilities for LOINC and SNOMED CT via official APIs. This code chunk instead serves a different purpose: post hoc inspection of an existing FHIR Questionnaire to extract and summarize LOINC codings. While optional validation may rely on a separate LOINC search helper, the core behavior is extraction/reporting, not questionnaire creation or broad terminology lookup. The mismatch is material because the primary function and supported terminologies differ from the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The description partially overlaps with the code because both concern FHIR terminology support and questionnaire construction. However, this code chunk specifically handles LOINC answer lists and ValueSet expansion/search, and can emit a Questionnaire item template. It does not process plain requirement ideation documents, and it does not implement SNOMED CT or broader clinical concept lookup for conditions, findings, observations, medications, or procedures. The external resource usage is a generic FHIR terminology server (tx.fhir.org), not obviously the 'official coding APIs' claimed. Therefore the supplied code does not fully and accurately match the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The description emphasizes questionnaire generation support from ideation documents and terminology lookup against LOINC/SNOMED CT APIs. The provided code does something materially different: it validates existing FHIR Questionnaire JSON files using a local schema and extra semantic rules. There is no code for parsing plain requirements, generating questionnaire definitions, calling external coding APIs, or looking up LOINC/SNOMED CT codes. While validation is related to FHIR questionnaires, it is an undeclared primary capability compared with the stated purpose, so this is a clear description-behavior mismatch.

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 · references/fhir_questionnaire_spec.md (reported line 63)May include surrounding context.

md
| prefix | 0..1 | string | Display prefix (e.g., "1.", "a)") |
| text | 0..1 | string | Primary text for the item |
| type | 1..1 | code | Type of item (see Item Types below) |
| enableWhen | 0..* | BackboneElement | Conditional display rules |
| enableBehavior | 0..1 | code | all \| any (default: all) |
| required | 0..1 | boolean | Whether item must be answered |
| repeats | 0..1 | boolean | Whether item can repeat |

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documentation advertises and instructs use of scripts that perform network access and local file reads/writes, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates an execution-governance gap where an agent may invoke broader capabilities than a reviewer or policy engine expects, increasing the risk of unintended file modification or outbound requests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file provides example questionnaires that request personally identifiable information and health data, including name, date of birth, address, depression screening responses, medical history, allergies, surgeries, family history, tobacco use, and alcohol consumption. Under the markdown-specific warning rule, the description should disclose that these patterns involve sensitive personal and medical data and should be used with appropriate privacy and consent safeguards, but no such warning appears in the file.

Content

No source excerpt is available for this finding.

Tainted flow: 'codesystem_file' from input (line 344, user input) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/create_custom_codesystem.py (reported line 347)May include surrounding context.

python
codesystem_file = output_dir / f"CodeSystem-{id}.json"
    valueset_file = output_dir / f"ValueSet-vs-{id}.json"

    with open(codesystem_file, 'w') as f:
        json.dump(codesystem, f, indent=2)

    with open(valueset_file, 'w') as f:

Tainted flow: 'valueset_file' from input (line 345, user input) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/create_custom_codesystem.py (reported line 350)May include surrounding context.

python
with open(codesystem_file, 'w') as f:
        json.dump(codesystem, f, indent=2)

    with open(valueset_file, 'w') as f:
        json.dump(valueset, f, indent=2)

    # Success message

Vague Triggers

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

This is a JSON manifest-type file, so vague-trigger checks apply. The description and purpose describe a generic 'comprehensive questionnaire template' and 'starting point for complex clinical questionnaires' without any explicit scope, invocation conditions, or exclusion criteria, which could make the skill/template applicable in overly broad contexts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This JSON schema includes a natural-language language property described as the base language of the resource, but it does not indicate that language selection should be user-driven or explicitly opted into. Because SQP-3 applies to all file types and covers language/locale policy concerns in natural-language text or config values, this is a mild policy concern in a schema that constrains locale-bearing content.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
83% confidence
Finding

The dependency is specified as a lower-bounded range (jsonschema>=4.0.0) rather than being pinned to an exact version, which makes builds non-reproducible and can silently pull in newly released versions with breaking changes or supply-chain issues. In a skill that may run scripts and process healthcare-related questionnaire definitions, unexpected dependency updates could affect reliability and, in the worst case, introduce vulnerable transitive code into the environment.

Content

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

text
jsonschema>=4.0.0

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script sends the user's search term directly to an external terminology server (tx.fhir.org) without any explicit notice or consent at runtime. In a healthcare context, free-text queries may contain sensitive clinical terms or even patient-related information, so this creates a real data exposure/privacy risk even though the transmission is over HTTPS and appears functionally intended.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.