Back to skill

Security audit

med-initial-record-genenration

Security checks for vulnerabilities and agentic risk

Overview

This medical-record skill has a coherent purpose, but it sends full medical dialogue to an external API without the de-identification promised in its documentation.

Review this carefully before installing. Use it only if you are authorized to send raw medical dialogue and diag_id values to the documented external service, and avoid real patient-identifying information unless your privacy, legal, and compliance requirements allow that processing. Do not enable --save-prepared for sensitive cases unless you intentionally want a plaintext intermediate file retained on disk, and run document/OCR preprocessing in an isolated environment for untrusted files.

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

Error
Location
scripts/gen_initial_record.py:19
Finding

Medical Data Is Transmitted to a Third-Party API Without Implemented De-identification

Content
View full analysis
str: """ 调用公司接口,生成初诊门诊病历(最终记录)。 """ payload = { "diag_id": diag_id, "dep_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "diag": dialogue, } try: data_bytes = json.dumps(payload, ensure_ascii=False).encode("utf-8") req = urllib.request.Request( url=RECORD_API_URL, data=data_bytes, method="POST", headers={"Content-Type": "application/json"}, ) if timeout and timeout > 0: resp_ctx = urllib.request.urlopen(req, timeout=timeout) else: resp_ctx = urllib.request.urlopen(req) with resp_ctx as resp: body = resp.read().decode("utf-8", errors="replace") ``` ```python with open(input_path, "r", encoding="utf-8") as f: dialogue_text = f.read() print(f"Generating initial visit record from dialogue: {input_path}") # 直接调用生成病历接口 record_text = call_record_api(diag_id=diag_id, dialogue=dialogue_text, timeout=timeout) ``` ### Technical Analysis The complete contents of the supplied dialogue are read from disk and assigned to `dialogue_text`. That value is passed directly to `call_record_api`, inserted into the JSON `diag` field, and transmitted to the external service at: ```text https://shangbao.yunzhisheng.cn/skills/record-gen/gen_record_by_diag_v1 ``` No implementation removes or masks names, telephone numbers, government identifiers, addresses, or other personally identifiable or protected health information before transmission. The preprocessing in `scripts/run.py` normalizes speakers and extracts text but does not perform de-identification. This behavior conflicts wi ...[truncated 1639 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run.py:432
Finding

Optional Debug Mode Persists Plaintext Medical Dialogue Contrary to the Privacy Documentation

Content
View full analysis
.prepared`. 5. The file remains after the process terminates. 6. Another local user, backup process, synchronization service, or later application may obtain the retained plaintext file. ### Impact Assessment This issue does not provide privilege escalation. It exposes the confidentiality of the full normalized medical dialogue to entities that can read the output directory, filesystem backups, snapshots, ...[truncated 330 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:103
Finding

Dependency Installation Instructions Use Unpinned Package Versions

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
也支持通过统一入口 `scripts/run.py` 直接输入 `pdf/doc/docx/xls/xlsx/csv/txt/json`。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
也支持通过统一入口 `scripts/run.py` 直接输入 `pdf/doc/docx/xls/xlsx/csv/txt/json`。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
也支持通过统一入口 `scripts/run.py` 直接输入 `pdf/doc/docx/xls/xlsx/csv/txt/json`。

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The function transmits full medical dialogue content to an external network endpoint for processing, which constitutes exfiltration of highly sensitive health data. Even if intended for legitimate functionality, this creates substantial privacy and compliance risk because the capability exceeds a narrowly described text-generation purpose and exposes PHI to third-party infrastructure.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill advertises capabilities including file read/write, shell, environment access, and outbound network calls, but does not declare any explicit tool scope or permission boundaries. In a medical-record workflow handling sensitive patient data, missing least-privilege constraints increases the risk of unintended file access, data exfiltration to external services, or unsafe command execution if the implementation is broader than users expect.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The description and overview specify that the skill generates records from Chinese doctor-patient dialogue text and outputs Chinese medical-record text, but do not present this as an optional or user-selected locale. Under the policy, constraining language without opt-in is a natural-language locale violation unless clearly justified as region-specific compliance tooling.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The document claims 'no local persistent storage' and 'destroy after this call,' but later describes writing outputs and optionally prepared data to local files. For medical dialogues, this mismatch is dangerous because operators may rely on the privacy statement while protected health information is actually retained on disk, creating compliance, confidentiality, and data-retention risk.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
| `pdftotext`(poppler-utils) | 提取 PDF 文本 | 输入为 pdf 且未安装 pypdf 时必须 |
| `tesseract`(含 chi_sim+eng 语言包) | 图片 OCR | 输入为 png/jpg/bmp/tif 等图片时必须 |

安装(Ubuntu/Debian):`sudo apt-get install libreoffice poppler-utils tesseract-ocr tesseract-ocr-chi-sim`

> 仅使用 TXT/JSON 输入时,无需安装任何第三方包或外部工具。

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code reads sensitive doctor-patient dialogue from a local file and sends it to a remote backend API, despite the skill description implying local text generation behavior. In a medical context, this is dangerous because it transfers protected health information off-host without clear disclosure, local-only guarantees, or visible safeguards around consent, minimization, and data handling.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill prints only that it is generating a record from the dialogue file and gives no explicit warning that the dialogue contents will be sent over the network to a remote backend. In the context of medical conversations, lack of a user-facing notice materially increases the risk of unintentional disclosure of PHI and undermines informed use of the tool.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code normalizes all detected speakers to Chinese labels such as "患者" and "医生", and later emits dialogue in that locale-specific format. It also prefers the OCR language setting "chi_sim+eng" when available, but there is no user opt-in or documented justification for enforcing Chinese localization behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Supporting many file formats, including images, PDFs, office files, spreadsheets, and JSON, is a substantial scope expansion from the described Chinese dialogue text input. In security terms, this matters because every additional parser increases complexity, opportunities for parser bugs, and unexpected data-handling paths.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill's behavior exceeds its described scope by executing external binaries for office conversion, PDF extraction, and OCR. This is dangerous because each extra parser/tool expands the attack surface and introduces document-driven exploitation risk not implied by a simple dialogue-to-record generator.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
84% confidence
Finding

The skill executes LibreOffice/soffice on untrusted user-supplied office documents. While the Python code avoids shell injection, handing attacker-controlled documents to complex external parsers has a real history of parser/RCE and sandbox-escape risk, so this creates a dangerous trust boundary in a skill whose stated purpose is text-to-record generation.

Content

Scanner excerpt · scripts/run.py (reported line 169)May include surrounding context.

python
if not office_bin:
        raise PreprocessError("libreoffice/soffice not found for office document conversion.")
    with tempfile.TemporaryDirectory(prefix="med-initial-record-") as tmp_dir:
        proc = subprocess.run(
            [
                office_bin,
                "--headless",

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
78% confidence
Finding

This code sends untrusted PDFs to pdftotext, another complex external parser. There is no shell injection here, but malformed PDFs have historically triggered vulnerabilities in parsing tools, so processing arbitrary PDFs broadens the attack surface beyond the skill's core function.

Content

Scanner excerpt · scripts/run.py (reported line 203)May include surrounding context.

python
pdf_to_text = shutil_which("pdftotext")
    if pdf_to_text:
        proc = subprocess.run(
            [pdf_to_text, "-layout", str(path), "-"],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run.py (reported line 224)May include surrounding context.

python
cmd = [tesseract_bin, str(path), "stdout"]
    if lang_arg:
        cmd.extend(["-l", lang_arg])
    proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=False)
    if proc.returncode != 0 or not proc.stdout.strip():
        raise PreprocessError(f"Image OCR failed: {proc.stderr.strip() or 'no text returned'}")
    return proc.stdout

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run.py (reported line 231)May include surrounding context.

python
def detect_tesseract_langs(tesseract_bin: str) -> Sequence[str]:
    proc = subprocess.run(
        [tesseract_bin, "--list-langs"],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

L017 将技能描述为处理“中文医患对话文本”,而 L046-L047、L075-L082、L110-L112 又说明可直接接收 pdf/doc/docx/xls/xlsx/csv/txt/json,甚至通过 tesseract 处理图片。这不是单纯补充实现细节,而是将技能输入能力扩展到文档解析与 OCR,和前述狭义文本输入表述不一致。

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.