Back to skill

Security audit

本地模型PDF翻译(Ubuntu/Linux)

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed local document-translation tool, but users should be careful with remote API settings and stored API keys.

Install only if you are comfortable preparing llama.cpp, PyMuPDF, and requests yourself. Keep the API URL on localhost for private documents unless you intentionally trust a remote translation service, avoid using the default API key for anything exposed beyond loopback, and prefer environment variables or restricted permissions for real API keys.

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)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:68
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:68-71; equivalent instruction in README.md:68-72
Vulnerability Type: Supply-chain exposure through unpinned dependencies
Risk Level: Medium

Complete Code Snippet:

bash
# Python dependencies (manually executed by the user, official PyPI source)
pip3 install pymupdf requests

Technical Analysis

The installation instructions request the latest available versions of pymupdf and requests without version constraints, a lock file, or cryptographic hashes. Consequently, the code installed and executed can change after the Skill has been reviewed.

Although the documented source is the official Python Package Index and no malicious package is currently embedded in this project, an upstream account compromise, malicious future release, or incompatible dependency update could cause unreviewed code to execute during installation or import. Both dependencies are subsequently imported by the translation scripts and operate on user documents or network traffic.

Attack Path

  1. An attacker compromises an upstream dependency maintainer account or causes a malicious release to be published under an expected dependency name.
  2. A user follows the documented pip3 install pymupdf requests instruction.
  3. Pip resolves and downloads the newly published, unreviewed release.
  4. Package installation hooks or imported package code executes with the privileges of the user running pip or the translation scripts.
  5. The compromised dependency can access documents being translated, API credentials available to the process, translation output, and other resources accessible to that user.

Impact Assessment

Successful exploitation can result in arbitrary code execution with the installing or translating user's privileges. The affected scope can include input PDF, Markdown, and text files; generated translations; configured API credentials; environment variable ...[truncated 244 chars]

Remediation
View remediation

Remediation Suggestions

  1. Define reviewed dependency versions in a dedicated requirements file, for example:
    text
    PyMuPDF==<reviewed-version>
    requests==<reviewed-version>
    
  2. Generate and publish SHA-256 hashes for every package and transitive dependency.
  3. Install with hash enforcement:
    bash
    python3 -m pip install --require-hashes -r requirements.txt
    
  4. Review dependency updates before changing pinned versions.
  5. Use an isolated virtual environment rather than installing packages globally or with elevated privileges.
  6. Consider generating the lock file with a dependency-locking tool so transitive dependencies are also pinned.
  7. Keep the documented requirement to obtain user approval before an Agent installs any package.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/config.py:195
Finding

API Credentials Stored Without Enforced Restrictive Permissions

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py:195-203
Vulnerability Type: Plaintext credential storage with permissions controlled only by the process umask
Risk Level: Low

Complete Code Snippet:

python
def save_config(config, is_user=True):
    """
    Save configuration

    Args:
        config: Configuration dictionary
        is_user: Save to user.json when True, otherwise default.json
    """
    target_file = USER_CONFIG_FILE if is_user else DEFAULT_CONFIG_FILE

    os.makedirs(CONFIG_DIR, exist_ok=True)

    with open(target_file, 'w', encoding='utf-8') as f:
        json.dump(config, f, ensure_ascii=False, indent=2)

    print(f"Config saved to: {target_file}")

Technical Analysis

save_config() serializes the complete configuration dictionary to config/user.json. The dictionary can contain the api_key field, including a credential for a user-configured remote translation service.

The file is created using the default behavior of open() and no explicit owner-only mode is applied. Its effective permissions therefore depend on the process umask. Under a common 022 umask, a newly created file is typically readable by other local users. Existing files with overly broad permissions also remain broad because the function does not correct their mode.

The default credential, llama2025, only protects a loopback-bound local service and is not treated as a high-value secret. The security impact arises when a user replaces the default endpoint and key with credentials for an external service.

Additionally, config.py set begins with the result of load_config() and then persists that complete dictionary. As a result, a credential sourced from configuration expansion may be copied into the plaintext user configuration when another setting is changed.

Attack Path

  1. A user configures a remote API endpoint and a sensitive API key.
  2. The user runs a co ...[truncated 1084 chars]
Remediation
View remediation

Remediation Suggestions

  1. Prefer the existing PDF_TRANSLATE_API_KEY environment variable for sensitive credentials and avoid persisting its resolved value.
  2. If file-based storage is necessary, create the file atomically with owner-only permissions:
    python
    fd = os.open(
        target_file,
        os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
        0o600,
    )
    with os.fdopen(fd, "w", encoding="utf-8") as f:
        json.dump(config, f, ensure_ascii=False, indent=2)
    
  3. Apply os.chmod(target_file, 0o600) to existing configuration files after validating ownership and symbolic-link behavior.
  4. Write through a temporary file in the same directory and atomically replace the destination to avoid partial configuration files.
  5. Exclude api_key from persisted configuration when it originated from an environment variable.
  6. Consider integrating an operating-system credential store for remote-service credentials.
  7. Document that config/user.json can contain sensitive plaintext and must not be committed to source control or shared.
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
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

代码的核心行为只是 PDF 处理辅助模块:用 PyMuPDF 打开 PDF,解析页码范围,提取每页文本,读取 metadata,并检测前几页文本量以判断是否可能是扫描件。这可以视为“逐页提取”的一个子步骤,但与声明的主要能力——基于本地 llama.cpp 模型进行批量翻译、多语言互译、三步学术翻译、输出 Markdown——相比,缺失了关键主体功能。没有任何翻译调用、语言处理、模型推理、批处理编排或 .md 输出逻辑。因此描述与该代码块的实际行为存在明显不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

声明描述的是一个面向 PDF 的批量翻译工具,核心能力包括 PDF 逐页提取、批量处理、基于本地 llama.cpp 模型翻译,以及输出 Markdown 文件。实际代码仅是独立的翻译模块/CLI,处理纯文本输入,向配置的 API 端点发起 requests 请求获取翻译结果,并支持 basic 的方向、深度和连接检查。代码没有任何 PDF 读取、页面遍历、批处理、Markdown 生成或特定 llama.cpp 本地进程交互逻辑。因此,实际行为只覆盖了“翻译文本”这一子集,且主要实现方式与声明的整体用途存在实质差异,应判定为描述与代码不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个完整的 PDF 文档翻译工具,包含文档解析、逐页处理、多语言翻译策略和结果输出。但提供的代码片段只是一个 Ubuntu/Linux 启动脚本,用于运行 llama-server 并加载本地模型。它没有任何与 PDF 处理、文本提取、翻译编排、语言检测/转换、批处理或 Markdown 写出相关的代码。虽然启动本地模型服务可能是实现该技能的支撑步骤之一,但就当前代码片段本身而言,其实际行为与声明的主要功能存在明显差异,因此应判定为不匹配。

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 · scripts/translate_api.py (reported line 138)May include surrounding context.

python
if context:
            prompt += f"Context:\n{context[:500]}\n\n---\n\n"
        prompt += f"Translate the following into {tgt_name}:\n\n{text}"
        return prompt
    
    def translate_segment(self, text: str, direction: str = "en2zh",
                         depth: str = "standard", context: str = "") -> Dict:

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 · README.md (reported line 88)May include surrounding context.

md
| 缺失项 | 推荐安装方式 |
   |--------|-------------|
   | `llama-server`(核心,llama.cpp) | 备选按序:① `sudo apt install llama.cpp`(发行源/官方 PPA 含包时);② 官方 GitHub Releases 下载 Linux 预编译包并加入 PATH;③ 源码构建(`cmake -B build -DLLAMA_CURL=ON && cmake --build build --target llama-server`) |
   | `pymupdf` / `requests` | `pip3 install pymupdf requests`(PyPI 官方源) |
   | GGUF 翻译模型(**可选**,通常数 GB) | 用户自备放入 `models/`;默认**不自动下载**,仅在用户明确指定来源并要求时 Agent 方可代下载 |

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 92)May include surrounding context.

md
| 缺失项 | 推荐安装方式 |
   |--------|-------------|
   | `llama-server`(核心,llama.cpp) | 备选按序:① `sudo apt install llama.cpp`(发行源/官方 PPA 含包时);② 官方 GitHub Releases 下载 Linux 预编译包并加入 PATH;③ 源码构建(`cmake -B build -DLLAMA_CURL=ON && cmake --build build --target llama-server`) |
   | `pymupdf` / `requests` | `pip3 install pymupdf requests`(PyPI 官方源) |
   | GGUF 翻译模型(**可选**,通常数 GB) | 用户自备放入 `models/`;默认**不自动下载**,仅在用户明确指定来源并要求时 Agent 方可代下载 |

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill declares capabilities that involve reading files, writing outputs, accessing environment variables, and making HTTP requests, but it does not define an explicit tool scope or permissions boundary. In an agent ecosystem, missing scope declarations can cause overbroad execution authority, making accidental or unauthorized file/network actions more likely if the agent interprets the instructions liberally.

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 61)May include surrounding context.

Agent 安全约束(必读):运行环境(llama-server 程序、GGUF 模型、Python 依赖)默认由用户准备;如检测到缺失,Agent 可走下方「环境自动安装(可选)」流程协助安装,但必须先征求用户明确同意(Y/N),禁止静默下载或安装任何程序/文件。

  1. llama-server 程序:由用户从 llama.cpp 官方发布渠道手动安装 Linux 版 llama-server 并加入 PATH(Ubuntu 可用 sudo apt install 或官方 release)
  2. 模型文件:由用户将 GGUF 翻译模型放入本 skill 根目录下的 models/ 文件夹(模型文件不随 skill 发布)
  3. 启动 llama-server(用户手动执行;相对路径引用模型,不依赖任何机器绝对目录):
    bash

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The natural-language setting "direction": "en2zh" hard-codes English-to-Chinese output behavior. This creates a language/locale policy concern because the file does not indicate user opt-in, alternatives, or a region-specific justification for enforcing that translation direction.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The translator is initialized with an API URL and key, and later sends document content for translation without any explicit warning, consent flow, or trust boundary disclosure. Even if the endpoint is intended to be local, the configuration can point to a remote service, creating confidentiality risk for potentially sensitive document contents.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest describes a skill for translating PDF documents with page-by-page extraction and Markdown output. This code also discovers and processes .md/.txt files directly, which is broader than the declared PDF-only behavior and changes the effective scope of the skill.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest emphasizes PDF extraction plus translation workflow, but this branch translates standalone .md and .txt content without any PDF handling. That is a meaningful behavior expansion beyond the documented purpose, not just an implementation detail.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script sends extracted PDF text to a translator backend via LocalTranslator without presenting any explicit warning, consent gate, or clear indication of data-handling risk in this file. Because PDFs may contain sensitive academic, business, or personal information, users could unintentionally exfiltrate content to a remote API endpoint, especially since --api-url is configurable and not constrained to localhost.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code sets the default translation direction to "en2zh", which hardcodes Chinese as the default target language. It also reinforces that choice later with a fallback to "zh", creating a language policy constraint without offering a user choice or documenting a justified region-specific limitation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

When parse_direction raises a ValueError, get_target_lang silently returns "zh". This imposes a specific locale choice on error rather than preserving user choice, surfacing an error, or prompting for clarification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

This code file contains natural-language documentation in Chinese ('PDF文本提取模块 - 独立的PDF处理功能') while the CLI interface and other strings are otherwise English, with no indication that the skill is intentionally region-specific or that users can choose locale. That creates a language/locale policy concern because the skill presents a fixed language without opt-in or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This Python file contains prominent natural-language text in Chinese for the module docstring and many user-facing comments, while the policy requires avoiding forced language/locale choices unless the user opts in or the constraint is justified. There is no indication that Chinese is optional or that this is a region-specific tool, so the file effectively enforces a language choice for maintainers and potentially users.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes a skill for batch translating PDF documents with page-by-page extraction and markdown output. This script explicitly discovers .md and .txt inputs and has a separate translation path for them, which broadens the behavior beyond the stated PDF-focused scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This script sends full document contents to a translation API via LocalTranslator.translate_segment without any in-file privacy notice, consent prompt, or data-handling warning. Even if the API is nominally local, the endpoint is configuration-driven (api_url/api_key/model), so sensitive document contents could be disclosed to an unintended local or remote service if misconfigured or shared across trust boundaries.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill is described as using a local llama.cpp model, but this module clearly sends full translation prompts and document content to an HTTP API using requests. That mismatch is security-relevant because users may provide sensitive PDF text under the assumption it never leaves the host, leading to unintended data exfiltration and trust-boundary violation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The module performs outbound API communication as part of translating document text, which expands the capability of the skill beyond simple local PDF processing. In the context of a tool advertised for local academic translation, this creates an unexpected data exposure path and increases risk if users process confidential manuscripts, contracts, or research documents.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

The requests.post call is the concrete sink that transmits the assembled prompt, including source text and optional context, to an external endpoint. In this skill's context, where users would reasonably expect local processing, that outbound transmission is dangerous because it can leak full document contents and metadata to a remote service or attacker-controlled URL if configuration is altered.

Content

Scanner excerpt · scripts/translate_api.py (reported line 81)May include surrounding context.

python
payload["model"] = self.model
        
        try:
            resp = requests.post(
                self.api_url,
                headers=self.headers,
                json=payload,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code sends user-provided text and optional context directly to the configured API endpoint without any explicit warning, consent, or disclosure in the CLI flow. Because the skill handles PDF-derived content that may be sensitive, silent transmission can expose proprietary or personal information to a remote service unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script launches an API-authenticated server but hard-codes a predictable default API key (llama2025). Any local user or local process that can reach 127.0.0.1:8001 can authenticate with the known default, which weakens the protection to effectively no secret at all; the absence of warning or forced override increases the chance operators leave the default in place.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The script calls get_language_name with "en" for output labels, and does so again when generating translated file headers. This enforces an English display locale for metadata/UI text without user opt-in, which is a natural-language policy concern under locale-choice requirements.

Content

No source excerpt is available for this finding.