T09 · Insecure Skill Coding Practices
- Location
scripts/ocr/paddleocr.py:7- Finding
Cloud OCR Is Enabled by Default and Uploads User Documents to a Hard-Coded External Endpoint
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a real document converter, but normal use can upload user documents to a hard-coded cloud OCR endpoint and modify the local environment without clear opt-in.
Install only if you are comfortable with document contents potentially leaving your machine during OCR and with the skill changing the Python/system environment. Before using it on private files, remove the hard-coded PaddleOCR defaults, require explicit cloud-OCR opt-in, and preinstall reviewed dependencies in a dedicated environment.
scripts/ocr/paddleocr.py:7Cloud OCR Is Enabled by Default and Uploads User Documents to a Hard-Coded External Endpoint
scripts/utils/deps.py:24Missing Dependencies Are Installed Automatically Without Version or Integrity Pinning
scripts/backends/pandoc.py:60Pandoc Executable Is Downloaded and Used Without Cryptographic Integrity Verification
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
---
name: markitdown-file-converter
description: |
将 PDF、Word (docx/doc)、Excel (xlsx/xls)、PPT (pptx/ppt)、图片等文件一键转换为 Markdown 或 JSON。
The skill advertises OCR features without clearly warning that cloud OCR mode may transmit document or image contents to a remote service. Because users may process sensitive files, the missing disclosure materially increases confidentiality risk and undermines informed consent.
The skill file contains what appears to be a concrete PaddleOCR access token example rather than a clear placeholder. Publishing real or realistic credentials in documentation risks accidental reuse, unauthorized service access, and normalizes unsafe secret-handling practices for users and downstream agents.
set PADDLEOCR_DOC_PARSING_API_URL=https://c474r929pea0qa6c.aistudio-app.com/layout-parsing
set PADDLEOCR_ACCESS_TOKEN=86b3f40ddd719dad76e496472d341f1ba89085e3
The Linux path invokes 'sudo apt-get install -y pandoc' programmatically, causing privileged system modification without prior confirmation. In an automated skill environment, this can unexpectedly escalate into privileged package operations, alter the host state, and create a larger attack surface if the skill is triggered on systems where sudo is available.
A hardcoded default access token is embedded in the source via the environment-variable fallback, which risks credential leakage through source control, package distribution, logs, or reuse by unauthorized parties. Even though an environment variable can override it, the shipped secret remains recoverable and may grant access to the remote OCR service.
def get_config() -> Tuple[str, str]:
"""Get API URL and access token."""
return PADDLEOCR_API_URL, PADDLEOCR_ACCESS_TOKEN
The skill promotes automatic dependency installation without clearly warning that it will install Python packages and system tools into the local environment. In practice, this changes the host state and may introduce supply-chain or stability risk, especially when triggered through an agent workflow.
The trigger keywords are broad and generic, increasing the chance the skill activates on loosely related prompts and performs file-conversion or install guidance unexpectedly. In a skill that also recommends package and system-tool installation, accidental invocation raises the chance of unintended environment changes or document handling.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
# poppler(PDF OCR 必需)
# Windows: winget install poppler
# Mac: brew install poppler
# Linux: sudo apt-get install poppler-utils
# pandoc(如未安装)
winget install pandoc
The table claims markitdown requires no network download, but elsewhere the skill documents optional PaddleOCR Cloud usage. This inconsistency can mislead users into believing processing is entirely local, weakening informed consent around remote handling of document or image data.
The documentation says user-provided error details will be automatically recorded into a learning system, but the skill otherwise presents itself as a local conversion tool and provides no implementation details, consent flow, retention policy, or data-boundary explanation. That creates a credible risk of undisclosed collection or onward sharing of sensitive document content when users report conversion errors.
Instructing the system to automatically record user-reported error details into a learning system creates a natural-language data leakage path. Error reports often contain excerpts from converted documents, filenames, formulas, or business data, so silent logging could expose sensitive content beyond the local conversion boundary.
Suspicious Unicode normalization or mixed-script content
The function automatically installs the mammoth package at runtime if it is missing, without explicit user consent or a warning. This creates a supply-chain and trust-boundary risk because processing an untrusted document can trigger network access and code installation in the local environment.
The code creates an images directory and later writes extracted image files into it, but the function only generally states that it converts DOCX to Markdown. There is no explicit warning, confirmation, or comment disclosing that the conversion process will create additional files on disk beyond the main output.
The code explicitly relies on sudo-based execution for package installation, meaning the skill may attempt root-level actions as part of normal processing. Even though there is no shell injection here, invoking privileged commands from a content-processing backend is dangerous because it normalizes elevated execution and can lead to unauthorized system changes or abuse in permissive environments.
subprocess.run(["sudo", "apt-get", "install", "-y", "pandoc"],
check=True, capture_output=True)
except Exception:
print("[install] Run: sudo apt-get install pandoc")
sys.exit(1)
The backend automatically attempts to install pandoc if it is missing, which can trigger system-changing package installation without explicit user consent. In an agent/skill context, this is risky because merely processing an untrusted document can cause unexpected software installation, package-manager invocation, and network access on the host.
This function sends the provided image file to a third-party cloud OCR endpoint, which can expose sensitive document contents outside the local environment. The code does not provide any explicit user consent flow, warning, or data-classification guardrails, so users may unknowingly upload confidential images.
The module-level documentation frames this as a local OCR engine, which implies operating on local inputs with local components. However, when dependencies are absent, the code calls pip_install for rapidocr and pix2tex, which likely performs external package download and installation rather than purely local OCR processing.
The function automatically installs a Python package at runtime without user consent, which introduces network retrieval and modifies the execution environment unexpectedly. In a security-sensitive or reproducible environment, this can enable supply-chain exposure, violate deployment policy, and create nondeterministic behavior if package sources are compromised or unpinned.
This code path silently installs the pix2tex package when missing, creating the same supply-chain and environment-modification risks as the RapidOCR path. Because the skill is presented as OCR functionality, implicit package installation makes the skill more dangerous by exceeding expected local-only behavior and potentially reaching external package repositories.
This code embeds language-specific routing logic by explicitly classifying inputs as Chinese or English and using those classifications to drive OCR engine selection. That natural-language policy choice is not presented as user-configurable or justified as a region-specific constraint, which can violate language/locale choice expectations.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
print(f"[install] Installing {name} ...")
try:
subprocess.run(
[str(python), "-m", "pip", "install"] + install_cmd.split()[1:],
check=True, capture_output=True, timeout=120
)
The statement says the script '强制使用 UTF-8 输出', which imposes a specific encoding behavior unconditionally. While UTF-8 is often reasonable, this is still a fixed locale/encoding policy presented without user opt-in or explanation of how users can override it if needed.
The function writes the generated Markdown to output_path, which is a file-modifying operation. While there is a completion print after the write, there is no prior disclosure or explicit warning in the function's documentation that running this backend will overwrite or create output files.
The function docstring says it will 'Convert scanned PDF to Markdown using OCR', implying a Markdown-oriented conversion. In practice, the function performs OCR on rendered page images and concatenates raw recognized text with simple headings like '## Page N', without any actual Markdown conversion logic beyond basic labeling.
No suspicious patterns detected.