Back to skill

Security audit

云上驱动打印

Security checks for vulnerabilities and agentic risk

Overview

This is a real cloud-backed network printing skill, but it needs review because it uploads documents, sends live print jobs, and may leak its API token through an unvalidated cloud-returned URL.

Review before installing. Use only with non-sensitive documents and trusted printers until the publisher adds explicit upload/print confirmation, validates fileUrl scheme and host before sending Authorization headers, bounds downloads, and uses a private temporary directory for conversions.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
cdf/ai/skillPrint.py:82
Finding

Bearer Token Forwarded to an Unvalidated Cloud-Provided URL

Content
View full analysis
bytes: """Download binary print data returned by the cloud service.""" if not url.strip(): raise RuntimeError("Download failed: fileUrl is empty.") req = request.Request( url.strip(), headers=build_common_headers(), method="GET", ) try: with request.urlopen(req, timeout=timeout) as resp: return resp.read() except error.HTTPError as exc: detail = exc.read().decode("utf-8", errors="replace") raise RuntimeError(f"Download returned HTTP {exc.code}: {detail}") from exc except error.URLError as exc: raise RuntimeError(f"Download failed: {exc}") from exc ``` The downloaded URL is obtained directly from the cloud response: ```python file_url = _extract_string(response, "fileUrl") response["fileUrl"] = file_url or response.get("fileUrl") response["cloudSuccess"] = bool(response.get("success")) if not response["cloudSuccess"]: return response if not file_url: response["success"] = False response["reason"] = response["reason"] or "_pfs succeeded but did not return fileUrl." return response data = _download_binary(file_url, timeout=DEFAULT_TIMEOUT) bytes_sent = _send_to_printer(port_addr, raw_port, data) ``` The common headers include the configured bearer token: ```python def read_api_key() -> str: """Read the optional Bearer token.""" return os.environ.get(API_KEY_ENV, "").strip() def build_common_headers(content_type: str | None = None) -> dict[str, str]: """Build common request headers.""" headers = { "Accept": "application/json", "tid": SKILL_TERMINAL_ID, "ttp": SKI ...[truncated 2960 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
print_file_for_skill.py:170
Finding

Predictable Shared Temporary PDF Can Cause Unintended File Upload

Content
View full analysis
Path: """Convert a file locally to PDF through LibreOffice and return its path.""" outdir = Path(tempfile.gettempdir()) try: result = subprocess.run( [ "libreoffice", "--headless", "--convert-to", "pdf", str(file_path.resolve()), "--outdir", str(outdir), ], capture_output=True, text=True, timeout=60, ) except FileNotFoundError: raise RuntimeError( "LibreOffice is not installed, so the document cannot be converted locally." ) except subprocess.TimeoutExpired: raise RuntimeError("Local LibreOffice conversion timed out after 60 seconds.") pdf_path = outdir / f"{file_path.stem}.pdf" if not pdf_path.exists(): raise RuntimeError(f"LibreOffice conversion failed: {result.stderr.strip()}") return pdf_path ``` The returned path is subsequently uploaded: ```python pdf_path = _local_convert_to_pdf(file_path) pdf_upload = upload_file_mcp(pdf_path) return pdf_upload["url"], {"converted": "true", "method": "libreoffice"} ``` ### Technical Analysis The conversion output is written to the global operating-system temporary directory using a predictable filename derived only from the source file stem: ```text /tmp/.pdf ``` The function does not: - Create a private per-operation temporary directory. - Remove or reject a pre-existing output file. - Check `result.returncode`. - Confirm that the output was created or modified by the current process. - Confirm that the path is a regular file rather than a symbolic link. - Clean up the converted document after upload. If ...[truncated 2590 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (32)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个功能完整的网络打印客户端技能,核心用途应是将多种文件类型处理后发送到网络打印机,并包含发现、驱动搜索和云端处理能力。而实际代码只是在指定主机和端口上做一次 TCP 建连测试,属于网络可达性/端口探测辅助工具。虽然连接 9100 端口与打印机场景相关,但这只是支持性诊断能力,不能代表所声明的主要功能。因此代码实际行为与声明用途存在明显且实质性的不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

声明描述的是一个完整的网络打印客户端,核心能力应包括文件格式处理、打印数据生成/转换、网络通信到打印机,以及可能的发现和云端流程。但该代码片段只是在本地 skills 目录下以 Markdown 形式维护打印机配置清单。它没有任何打印、网络连接、9100 端口通信、云端交互、文件转换或设备发现逻辑。因此该代码的实际行为与声明用途存在明显且实质性的不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

代码的主要功能是搜索打印机驱动候选项,并在提供 IP 时为已保存的打印机记录解析并回写驱动。这与声明中强调的“客户端打印工具”主用途明显不一致。虽然声明里提到“支持驱动搜索”,与本代码部分吻合,但该片段缺少声明中的大部分核心行为:文件打印、9100 端口发送打印数据、云端上传与转换、以及设备发现。因此该描述不能准确代表此代码片段的实际行为,应判定为不匹配。

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

_cvturl 和 _pfs 用 form-encoded(application/x-www-form-urlencoded)会返回 HTTP 404,但换 JSON body 后正常。这是路由不匹配,不是接口未部署。代码中这两个函数已使用 _post_json()。

curl 调试

bash
# _pfs(JSON body,含 fileName 原始文件名)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

_cvturl 和 _pfs 用 form-encoded(application/x-www-form-urlencoded)会返回 HTTP 404,但换 JSON body 后正常。这是路由不匹配,不是接口未部署。代码中这两个函数已使用 _post_json()。

curl 调试

bash
# _pfs(JSON body,含 fileName 原始文件名)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · references/pfs-empty-fileurl-debug.md (reported line 77)May include surrounding context.

bash
# 1. 直接调 _pfs 获取原始响应
curl -s -X POST "https://any.webprinter.cn/openapi/cdf/_pfs" \
  -H "Content-Type: application/json" -H "tid:cdf_ai_terminal" -H "ttp:AI" \
  -d '{"printer":{"driver":"EPSON L6270 Series","name":"EPSON L6270 Series","portType":"NET","portAddr":"192.168.66.139"},"url":"...PDF_URL...","config":{},"fileName":"test.pdf"}' \
  | python3 -m json.tool

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill describes capabilities spanning shell, filesystem, environment variables, network access, and cloud APIs, but it declares no explicit tool scope or permission boundaries. In an agent environment, that omission increases the chance the skill is invoked with broader-than-necessary privileges, enabling unintended local file access, network scanning, cloud upload of user documents, or shell execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill prominently describes uploading user files to a cloud service and transmitting rendered print data, but it does not provide a clear user-facing privacy warning or consent requirement. In a printing workflow, files may contain highly sensitive business or personal content, so silent or implicit cloud transfer materially increases confidentiality risk.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger guidance is overly broad and matches ordinary user language such as 'print this file', which can cause unintended invocation of a high-impact workflow. Because this skill can upload documents to a remote service and send data to LAN devices, accidental activation can expose sensitive files or cause unauthorized printing without sufficient confirmation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

A decision tree that activates on the generic word 'print' is unsafe in an agent setting because it overlaps heavily with common conversation. In this context, accidental routing is more dangerous than usual because the skill may inspect local files, contact remote cloud infrastructure, and interact with internal network printers.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

The skill instructs users to transmit document URLs, filenames, printer identifiers, and print configuration to an external domain. External transmission is expected for the feature, but it is still security-relevant because it can disclose document metadata and content to a third-party service and creates a dependency on remote service trustworthiness and transport security.

Content

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

_cvturl 和 _pfs 用 form-encoded(application/x-www-form-urlencoded)会返回 HTTP 404,但换 JSON body 后正常。这是路由不匹配,不是接口未部署。代码中这两个函数已使用 _post_json()。

curl 调试

bash
# _pfs(JSON body,含 fileName 原始文件名)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function sends user-derived printer model data to a cloud endpoint via HTTP request, which creates a privacy and data-governance risk because device identifiers and user-entered environment details leave the local network without any consent, minimization, or visibility in this code path. In a LAN printing skill, users may reasonably expect local-only handling, so undisclosed cloud transmission is more sensitive than in a clearly cloud-native search feature.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code uploads a local file to a cloud endpoint and later downloads generated print data before sending it to a network printer, but the file contains no user-facing print/log message, confirmation prompt, or explanatory comment warning that user file contents will be transmitted off-host. Because these operations affect user data and involve network transfer, they meet the missing-warning criteria for code files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

After cloud processing succeeds, the function automatically downloads binary print data and transmits it directly to the printer via a raw TCP socket. The file provides no user-facing notice, confirmation, or explicit disclosure that a real print job will be sent to the device, which is a safety-relevant external action.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This Python file contains natural-language comments, docstrings, CLI help text, and runtime messages entirely in Chinese, which imposes a specific language on users and maintainers. Under the policy, a forced language without opt-in or documented justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code performs a state-changing write by updating the printer's stored driver selection, but the function that executes the write provides no explicit warning, confirmation, or user-facing disclosure that printer configuration will be modified. Although driver selection may be expected in a workflow like this, the actual write operation is silent at the point of execution.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file contains multiple natural-language strings presented to users in Chinese, starting with the error at L31 and continuing throughout the CLI flow. This enforces a specific locale for all users and does not offer a language choice or document a justified region-specific restriction.

Content

No source excerpt is available for this finding.

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 · print_file_for_skill.py (reported line 175)May include surrounding context.

python
"""通过 LibreOffice 将文件本地转换为 PDF,返回 PDF 文件路径。"""
    outdir = Path(tempfile.gettempdir())
    try:
        result = subprocess.run(
            [
                "libreoffice",
                "--headless",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill uploads the selected document to a cloud service and may also perform cloud-side conversion before sending print data, but the main flow does not provide a clear user-facing warning or explicit consent gate before transmitting potentially sensitive document contents off-host. In an automation context, this can silently exfiltrate confidential files to remote infrastructure and a network printer, which is especially relevant given the skill description explicitly emphasizes cloud upload and conversion.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The document provides ready-to-run print commands and explicitly describes cloud-side document conversion/upload behavior, but does not warn that document contents may be transmitted to remote services or that sending data to a printer on port 9100 can change device state and potentially disrupt connectivity. In this skill context, those omissions matter because the commands are designed for automation, so users may execute them non-interactively and unknowingly expose sensitive files or affect a network printer.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The entire skill document is written in Chinese and does not indicate any user opt-in, alternative language, or locale-specific justification. Under the stated policy, forcing a specific language without user choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The document instructs operators to POST printer metadata and a remote document URL to an external cloud endpoint and then download the generated print payload from another external URL. In this skill's context, that creates real data-exposure risk because sensitive documents and internal network details such as printer model and private IP may be transmitted to a third-party service outside the local environment.

Content

Scanner excerpt · references/pfs-empty-fileurl-debug.md (reported line 77)May include surrounding context.

bash
# 1. 直接调 _pfs 获取原始响应
curl -s -X POST "https://any.webprinter.cn/openapi/cdf/_pfs" \
  -H "Content-Type: application/json" -H "tid:cdf_ai_terminal" -H "ttp:AI" \
  -d '{"printer":{"driver":"EPSON L6270 Series","name":"EPSON L6270 Series","portType":"NET","portAddr":"192.168.66.139"},"url":"...PDF_URL...","config":{},"fileName":"test.pdf"}' \
  | python3 -m json.tool

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/session-20260515-pfs-cvturl.md (reported line 18)May include surrounding context.

验证 curl:

bash
# form-encoded → 404
curl -X POST .../_pfs -H "Content-Type: application/x-www-form-urlencoded" -d "printer={...}&url=..."

# JSON body → 200
curl -X POST .../_pfs -H "Content-Type: application/json" -d '{"printer":{...},"url":"..."}'

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The document explicitly recommends a fallback that sends raw PDF bytes directly to a printer over TCP port 9100. In this skill’s context, that can bypass the cloud service’s normal controls, omit print-job safeguards, and transmit document contents directly across the LAN without clear operator warning about confidentiality, integrity, and configuration limitations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The user-facing docstring, CLI description, argument help text, and later status messages are all written only in Chinese. This imposes a specific language on users without opt-in, which matches the language/locale policy violation criteria for natural-language content in code files.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.