Back to skill

Security audit

doc-holmes

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed PDF translation helper that sends PDF content to a user-configured translation endpoint and uses local PDF/OCR tools for that purpose.

Install only if you are comfortable sending PDF text to the OpenAI-compatible endpoint you configure and with a locally installed pdf2zh-next engine receiving your API key. Avoid confidential medical, legal, unpublished, or regulated documents unless that endpoint and engine are approved for that data.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (31)

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The entire skill description and operational notes are written only in Chinese, including packaging guidance that points to a separate English artifact rather than offering a user-facing language choice here. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The manifest description embeds a long trigger list including broad phrases like "translate document," "translate paper," and "full-text translation." In a markdown/manifest context, these are not narrowly constrained and could match many ordinary user requests beyond this specific PDF-layout-preserving skill.

External Transmission

Medium
Category
Data Exfiltration
Content
export DOC_HOLMES_OPENAI_API_KEY=<your key>                              # created by you on that platform
```

SiliconFlow (`https://api.siliconflow.cn/v1`) or any OpenAI-compatible endpoint works the same way.

> ⚠️ About GLM **Coding Plan** subscription endpoints (`/api/coding/paas/v4`): per the official FAQ, the plan only covers designated coding tools. Calls from other tools do NOT consume the plan quota - they are billed per-token against your account balance, and accounts shared across multiple people may face subscription restrictions. If you still want to connect your subscription, set `DOC_HOLMES_ALLOW_CODING_ENDPOINT=1` (one-time confirmation).
Confidence
89% confidence
Finding
The skill is explicitly designed to send document contents to a user-configured external OpenAI-compatible endpoint for translation. That means potentially sensitive PDF text is transmitted off-host to third-party services, creating confidentiality, compliance, and data-handling risk, especially for medical, legal, or unpublished documents. The context makes this more significant because the skill targets large papers, guidelines, and reports, which often contain sensitive or proprietary content.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The entire skill document is written in Chinese and does not indicate that users may choose another language or locale. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The entire troubleshooting document is written in Chinese, and there is no indication that users may choose another language or that the skill is intentionally restricted to a Chinese-speaking context. Under the language/locale policy rule, forcing a specific language without opt-in is a natural-language policy concern.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The module docstring is entirely in Chinese and describes the skill behavior only in that language. This can violate a language/locale policy when the skill does not indicate that users may choose another language or that the Chinese-only presentation is intentional and justified.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The module docstring explicitly states '全部中文帮助', indicating the skill presents all help text in Chinese only. This is a natural-language locale policy issue because the file enforces a specific language for user-facing interaction without offering a language choice or opt-in.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
gpu = "未检测到"
    try:
        import subprocess as sp
        r = sp.run(["nvidia-smi", "-L"], capture_output=True, text=True, timeout=10)
        if r.returncode == 0 and r.stdout.strip():
            gpu = r.stdout.strip().splitlines()[0]
    except Exception:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

External Transmission

Medium
Category
Data Exfiltration
Content
"OpenAI 兼容端点 + key(三选一):\n"
    "  A) 智谱开放平台官方 API(推荐):https://open.bigmodel.cn/api/paas/v4\n"
    "     glm-4.5-flash 免费档;在 open.bigmodel.cn 注册并创建你自己的 key\n"
    "  B) SiliconFlow 等聚合平台免费档(https://api.siliconflow.cn/v1)\n"
    "  C) 任意 OpenAI 兼容端点\n"
    "设置方式(二选一):\n"
    "  1) 环境变量:\n"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
"  1) 环境变量:export DOC_HOLMES_OPENAI_API_KEY=<你的key>\n"
            "  2) 配置文件:%s\n"
            "     写入一行:DOC_HOLMES_OPENAI_API_KEY=<你的key>\n"
            "     (建议 chmod 600,key 明文仅本人可读)" % (cfg.base_url, env_file)
        )
    return cfg
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code forwards both the PDF path and the OpenAI API key to an external CLI process, expanding the trust boundary to another executable that may log, crash-dump, or otherwise expose sensitive material. In this skill context, the wrapper is explicitly designed to invoke a separately installed third-party tool, so users may not realize that local document data and credentials are being handed to another program unless that disclosure happens elsewhere.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
timed_out = False
    window = t0 - 1  # 产物发现窗口:只认本次运行开始后的文件
    try:
        proc = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout_s)
        rc = proc.returncode
        err_tail = ((proc.stderr or "") + (proc.stdout or ""))[-2000:]
    except subprocess.TimeoutExpired as exc:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
return info
    info["binary"] = binary
    try:
        out = subprocess.run([binary, "--version"], capture_output=True, text=True,
                             timeout=15)
        info["version"] = (out.stdout or out.stderr).splitlines()[0].strip()
    except Exception as exc:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Tainted flow: 'binary' from os.environ.get (line 43, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
return info
    info["binary"] = binary
    try:
        out = subprocess.run([binary, "--version"], capture_output=True, text=True,
                             timeout=15)
        info["version"] = (out.stdout or out.stderr).splitlines()[0].strip()
    except Exception as exc:
Confidence
87% confidence
Finding
The code allows the executable path to come from DOC_HOLMES_TESSERACT_BIN and then executes it directly. If an attacker can influence the environment of the running process, they can point this variable to an arbitrary executable and achieve code execution under the service account; the OCR adapter context makes this realistic in shared, misconfigured, or plugin-driven deployments.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
info["reason"] = "tesseract 无法执行:%s" % exc
        return info
    try:
        langs = subprocess.run([binary, "--list-langs"], capture_output=True,
                               text=True, timeout=15).stdout
        info["langs"] = [x.strip() for x in langs.splitlines()[1:] if x.strip()]
    except Exception:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Tainted flow: 'binary' from os.environ.get (line 43, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
info["reason"] = "tesseract 无法执行:%s" % exc
        return info
    try:
        langs = subprocess.run([binary, "--list-langs"], capture_output=True,
                               text=True, timeout=15).stdout
        info["langs"] = [x.strip() for x in langs.splitlines()[1:] if x.strip()]
    except Exception:
Confidence
87% confidence
Finding
This is the same tainted executable-path issue manifested in the language-listing probe. Because the binary originates from an environment variable, merely checking capabilities can already execute attacker-controlled code, making the probe itself a code-execution sink.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
page_pdf = base + ".pdf"
            try:
                # 单次调用同时产出 pdf + txt(tesseract 支持多输出配置,省一半 OCR 时间)
                subprocess.run(
                    [info["binary"], img_path, base, "-l", lang, "--psm", psm,
                     "pdf", "txt"],
                    capture_output=True, timeout=page_timeout, check=True)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The module docstring and multiple user-facing strings are written only in Chinese, including operational summaries and error guidance. This imposes a specific language/locale on users without opt-in or documented justification, which matches the language-policy violation criteria.

Missing User Warnings

Medium
Confidence
83% confidence
Finding
The batch runner takes an api_key and passes it to translate_pdf, implying outbound network/API use for document translation. In this file there is no confirmation, logging, or explanatory warning to users that PDFs and credentials may be sent to an external service.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The file’s natural-language documentation is entirely in Chinese, including the main module docstring and operational descriptions. Under the stated policy, forcing a specific language without user opt-in or an explicit justified locale constraint is a policy issue, and no opt-in or justification appears in this file.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The module-level docstring and user-visible reason strings are written in Chinese throughout, with no indication that language is configurable or chosen by the user. This can violate a language/locale policy when a skill implicitly forces one language without opt-in or documented justification.

Intent-Code Divergence

Low
Confidence
79% confidence
Finding
The charter text says '不内置任何端点/密钥,用户自带' ('do not embed any endpoint/key; user provides their own'), but in the same sentence discusses a 'Coding Plan 订阅端点' being distribution-blocked by default and unlockable for developer use. That wording suggests the existence of a developer-controlled endpoint capability, which conflicts with the blanket claim that no endpoint is built in.

Vague Triggers

Low
Confidence
88% confidence
Finding
The usage guidance lists example phrases like "translate this paper" and "document translation" without clearly stating when the skill should not activate, such as for non-PDF files or cases where layout preservation is irrelevant. This increases the chance of unintended invocation from generic translation requests.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
This line establishes a fixed language constraint for user-facing help text based on the author's audience rather than user preference. That can violate language/locale policy expectations when no opt-in or alternative language path is offered.

Natural-Language Policy Violations

Low
Confidence
96% confidence
Finding
This file contains all user-facing explanatory text and error guidance in Chinese, including the module docstring and later exception/help strings. The policy allows locale constraints only when users are given a choice or the restriction is clearly documented as justified; neither appears here.

Static analysis

No suspicious patterns detected.