Back to skill

Security audit

Medical Record Translator

Security checks for vulnerabilities and agentic risk

Overview

This medical translation skill is mostly coherent, but its PDF renderer can process unsanitized embedded HTML in sensitive documents without clear resource-fetching controls.

Install only if you need Chinese-first medical-record translation and are comfortable sending the document content to the configured AI service. Treat the PDF export path as requiring review: avoid rendering untrusted Markdown or embedded HTML unless the environment blocks network access and local-file reads, and prefer updated/sandboxed rendering dependencies.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/render_translation.py:42
Finding

Unsanitized HTML Allows Local and Remote Resource Resolution During PDF Rendering

Content
View full analysis

Vulnerability Details

File Location: scripts/render_translation.py:42-47, 55-61, 94-95
Vulnerability Type: Unsanitized active HTML and unrestricted resource resolution
Risk Level: Medium

Vulnerable Code

python
def render_markdown_fragment(markdown_text: str) -> str:
    markdown_renderer = load_markdown_renderer()
    return markdown_renderer(
        markdown_text,
        extensions=["extra", "sane_lists", "tables"],
        output_format="html5",
    )
python
def build_html_document(markdown_text: str, document_title: str, source_name: str) -> str:
    template = Template(TEMPLATE_PATH.read_text(encoding="utf-8"))
    css_text = CSS_PATH.read_text(encoding="utf-8")
    body_html = render_markdown_fragment(markdown_text)
    return template.substitute(
        document_title=escape(document_title),
        source_name=escape(source_name),
        css_text=css_text,
        body_html=body_html,
    )
python
html_class = load_weasyprint_html()
html = html_class(string=html_document, base_url=str(SKILL_ROOT))
html.write_pdf(target=str(target_path))

The output contract also expressly permits embedded HTML in references/output-contract.md:19-20:

markdown
- `table`: Table structure preserved. Markdown tables are allowed when they faithfully represent the grid.
- `table`: Embedded HTML is allowed when Markdown tables cannot preserve merged cells, multi-line cells, or clinically important alignment.

Technical Analysis

The renderer accepts Markdown content and converts it to HTML with the Python Markdown package. Embedded HTML is permitted and is inserted into the fixed document template through the unescaped body_html substitution.

WeasyPrint subsequently processes this attacker-influenced HTML to generate a PDF. Resource-bearing HTML or CSS can cause WeasyPrint to resolve absolute local or remote URLs. The configured base_url ...[truncated 2124 chars]

Remediation
View remediation

Remediation Suggestions

  1. Sanitize generated HTML with a strict allowlist before passing it to WeasyPrint. Permit only the elements required for document structure, such as headings, paragraphs, lists, tables, and limited inline formatting.
  2. Remove or reject resource-loading elements and constructs unless explicitly required, including img, link, iframe, SVG, embedded objects, and CSS declarations containing URLs.
  3. Strip dangerous or unnecessary attributes, including src, href, srcset, style, and event-handler attributes. If links are required, validate their schemes and prevent resource fetching.
  4. Provide WeasyPrint with a custom url_fetcher that denies HTTP, HTTPS, FTP, and other network schemes by default.
  5. If local assets are necessary, permit file: access only for canonical paths beneath a dedicated immutable asset directory. Reject traversal and symbolic-link escapes after resolving the path.
  6. Run PDF rendering in a sandboxed process with no network access, a read-only filesystem, a minimal allowlisted asset mount, resource limits, and a dedicated unprivileged account.
  7. Add regression tests using malicious Markdown containing remote URLs, loopback and link-local addresses, local-file references, CSS url(...), SVG references, and path traversal attempts.
  8. Update the output contract so that embedded HTML is restricted to an explicitly documented safe subset rather than being generally allowed.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented purpose is medical-record translation, but the referenced behavior includes Markdown-to-PDF rendering and writing files to disk, which is materially different from the declared function. This mismatch is dangerous because it can conceal data-flow and output behaviors from reviewers and users, especially when handling sensitive medical information that may be rendered, stored, or transformed in undeclared ways.

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/output-contract.md (reported line 5)May include surrounding context.

md
The primary artifact is a structure-preserving, doctor-readable translation. It is not a summary report and it does not require a document-level metadata table.

## Core Output Rules

- Emit blocks in source reading order.
- Emit one translated block per source block and preserve the source anchor, such as `P2-B4`.

Known Vulnerable Dependency: pypdf==5.4.0 — 16 advisory(ies): CVE-2026-84310 (pypdf: Possible long runtimes/large memory usage when retrieving outlines); CVE-2026-48156 (pypdf: Possible long runtimes for zero-only width values in cross-reference stre); CVE-2026-24688 (pypdf has possible Infinite Loop when processing outlines/bookmarks) +13 more

High
Category
Supply Chain
Confidence
98% confidence
Finding

The file pins pypdf to version 5.4.0, and the supplied advisories indicate multiple known denial-of-service issues such as infinite loops and excessive memory or runtime consumption during PDF parsing. In a medical-record translation skill, PDFs are likely to be attacker-controlled uploads, which makes parser-level vulnerabilities especially relevant because malformed records can reliably trigger service disruption during ingestion or outline extraction.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: weasyprint==62.3 — 6 advisory(ies): CVE-2025-68616 (WeasyPrint has a Server-Side Request Forgery (SSRF) Protection Bypass via HTTP R); CVE-2026-55073 (weasyprint Has Server-Side Request Forgery (SSRF)); CVE-2026-49452 (WeasyPrint has CSS Injection via Presentational Hints) +3 more

High
Category
Supply Chain
Confidence
97% confidence
Finding

The file pins weasyprint to version 62.3, which the finding associates with multiple known issues including SSRF and CSS/presentational-hint injection weaknesses. This skill handles medical documents and likely renders user-supplied content into output formats, so an attacker could abuse crafted HTML/CSS or embedded references to induce server-side network access or unsafe rendering behavior, increasing exposure in a sensitive healthcare workflow.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill references local files and scripts but does not declare any explicit tool scope or permissions boundary. In a skill handling medical records, undeclared file-read capability increases the chance of overbroad access to sensitive files or unexpected file ingestion beyond what users intended.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description mandates that the main artifact be "Chinese-first," which forces a specific language/locale behavior. The file does not offer user opt-in or alternative language selection, and no region-specific compliance justification is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

This instruction requires all outputs to be Chinese-first, which is a natural-language locale policy constraint. Because the skill does not provide a user choice or clearly justify the restriction as region-specific, it violates the language/locale policy criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Forcing Chinese-first output in the skill description and default prompt without indicating user choice can cause unsafe mismatches between user needs, clinician expectations, and the source document's operational context. In medical records, locale/output constraints may lead to misunderstanding, workflow errors, or accidental disclosure when the recipient expected a different language or format.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The default prompt triggers the skill for any 'provided medical record' and directs automatic translation/export without expressing tighter invocation constraints, confirmation requirements, or scope limits. In a medical-document context, overly broad triggering increases the chance of processing sensitive health information inappropriately, on the wrong content, or without sufficient user intent verification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The HTML template hard-codes lang="zh-CN", which imposes a specific language/locale on all rendered documents. Under the policy rules, this is a natural-language locale constraint violation because the file does not offer user opt-in or document why the Chinese locale is required.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file is dominated by instructions and labels requiring Chinese output (for example, repeated '中文:' sections and Chinese-only review guidance) without any indication that the user can choose another language. Under the policy, forcing a specific language or locale without opt-in is a natural-language policy violation unless the restriction is clearly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Line L09 explicitly requires that Chinese appear first for all output blocks. This is a natural-language locale policy constraint, and the file does not indicate that users may opt into another language order or that the restriction is justified by a region-specific requirement.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Line L20 states that Chinese text must appear first, which imposes a specific language/locale requirement in natural-language instructions. The file does not offer user opt-in or explain a region-specific justification, so this appears to violate the language/locale policy constraint.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The file is entirely structured as English-to-Chinese terminology mappings for translation use, which imposes a specific output language/locale without offering alternatives or stating that Chinese is optional. Under the policy, language constraints should either be user-selectable or clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.