Back to skill

Security audit

WPS PDF Processing

Security checks for vulnerabilities and agentic risk

Overview

This PDF skill is useful in purpose, but its OCR path uploads full PDFs to WPS using ambient session credentials without clear disclosure or consent.

Install only if you are comfortable with the OCR/PDF-to-Markdown path sending complete PDFs to WPS using local WPS session credentials. Avoid using it for confidential, regulated, financial, legal, or proprietary PDFs unless remote processing is explicitly acceptable, and review or constrain WPS_API_BASE and image download behavior before use.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/pdf_to_md.py:20
Finding

Unrestricted API Endpoint Allows Disclosure of PDF Content and WPS Session Credentials

Content
View full analysis
str: sid = ( os.environ.get("TMP_LX_UUID") or os.environ.get("wps_sid") or os.environ.get("WPS_SID") ) if not sid: raise SystemExit("缺少认证凭证:未设置环境变量 TMP_LX_UUID / wps_sid / WPS_SID") return sid class _Session: _HDR = { "Origin": "https://365.kdocs.cn", "Referer": "https://365.kdocs.cn/", } def __init__(self, sid: str): self._http = requests.Session() self._http.cookies.set("wps_sid", sid) self._http.cookies.set("csrf", sid) self._http.headers.update(self._HDR) ``` ```python def export_and_localize( pdf_path: Path, out_md: Path, images_subdir: str = "images", sid: Optional[str] = None, ) -> Path: pdf_path = pdf_path.resolve() if not pdf_path.is_file(): raise FileNotFoundError(pdf_path) session = _Session(sid or _resolve_sid()) name = pdf_path.name content = pdf_path.read_bytes() resp = session.post_multipart( f"{_API_BASE}/v7/longtask/exporter/export_file_content", files={"form_file": (name, content, "application/pdf")}, data={"format": "markdown", "include_elements": "all", "filename": name}, ) ``` ### Technical Analysis The script reads the complete local PDF into memory and uploads it through a session containing the WPS session identifier. The identifier is assigned to both the `wps_sid` and `csrf` cookies. The request destination is derived from the `WPS_API_BASE` environment variable without scheme validation, hostname allowlisting, or enforcement of the expected WPS API ori ...[truncated 1723 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/pdf_to_md.py:35
Finding

Server-Controlled Image URLs Enable SSRF and Unbounded Authenticated Downloads

Content
View full analysis
requests.Response: return self._http.post(url, files=files, data=data, timeout=timeout) def get_bytes(self, url: str, timeout: int = 120) -> bytes: r = self._http.get(url, timeout=timeout, stream=True) r.raise_for_status() return r.content ``` ```python def _public_url(url: str) -> str: """内网 KS3 地址 → 公网地址(与 cooffice/tools/parse_document.py 一致)""" if _KS3_INTERNAL in url: return url.replace(_KS3_INTERNAL, _KS3_PUBLIC) return url def _is_http(u: str) -> bool: return u.startswith("http://") or u.startswith("https://") ``` ```python md_text = (body.get("data") or {}).get("markdown") if md_text is None: raise RuntimeError("响应中无 data.markdown") out_md = out_md.resolve() out_dir = out_md.parent img_dir = out_dir / images_subdir out_dir.mkdir(parents=True, exist_ok=True) seq = [1] def replacer(m: re.Match) -> str: alt, raw = m.group(1), m.group(2).strip() idx = seq[0] seq[0] += 1 dest_parent = img_dir dest_parent.mkdir(parents=True, exist_ok=True) if raw.startswith("data:image/"): # base64 data URI → 直接解码写文件 try: img_bytes, ext = _decode_data_uri(raw) except Exception as e: raise RuntimeEr ...[truncated 3287 chars]
Remediation
View remediation

other

Warning
Location
SKILL.md:91
Finding

Skill Documentation Does Not Disclose Remote Processing of Local PDFs

Content
View full analysis
/content.md,图片写入 <输出目录>/images/ parse('', '<输出目录>') ``` The invoked implementation sends the entire file to a remote API: ```python session = _Session(sid or _resolve_sid()) name = pdf_path.name content = pdf_path.read_bytes() resp = session.post_multipart( f"{_API_BASE}/v7/longtask/exporter/export_file_content", files={"form_file": (name, content, "application/pdf")}, data={"format": "markdown", "include_elements": "all", "filename": name}, ) resp.raise_for_status() body = resp.json() ``` ### Technical Analysis The Skill documentation recommends `pdf_to_md.parse()` when ordinary extraction fails, including for scanned, photographed, and image-based PDFs. It states where Markdown and images will be written but does not disclose that: - The complete PDF is uploaded to a third-party WPS endpoint. - A WPS session identifier must be obtained from environment variables. - The credential is sent through an authenticated HTTP session. - Remote image URLs returned by the service are subsequently fetched. - Third-party privacy, retention, jurisdiction, and authorization requirements may apply. This omission is material because users may reasonably interpret an imported local Python module as performing local OCR. The implementation instead transfers potentially sensitive documents outside the local environment. ### Attack Path 1. A user has a sensitive PDF for which local text extraction produces little or no text. 2. Following the Skill instructions, the user invokes `parse()` as the recomm ...[truncated 853 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented behavior materially diverges from the declared purpose: the skill claims broad local PDF processing but references a script path that, per the finding, uploads local PDFs to a remote WPS API and downloads externally referenced images. That mismatch is dangerous because users and orchestrators may treat the skill as a local-only PDF utility while sensitive document contents are transmitted off-host and external content is written locally without clear disclosure or consent.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger condition is extremely broad: it says to use the skill whenever a user mentions a .pdf file or wants to generate a PDF. Overbroad activation increases the likelihood the skill will be invoked in routine conversations or low-risk contexts, which is especially dangerous here because the skill includes file operations and potentially undisclosed networked processing of user documents.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill documentation demonstrates capabilities that access environment variables, read/write local files, and invoke code paths that may perform network operations, yet it declares no explicit tool scope or permissions. This creates a transparency and policy-enforcement gap: an agent may invoke the skill without clear restrictions, increasing the chance of unintended file access or data egress during PDF handling.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The document describes sensitive operations such as decrypting PDFs, OCR extraction, image extraction, and batch writing files, but does not include clear warnings about privacy, confidential data handling, output locations, or downstream storage of extracted content. In the context of PDFs, which often contain personal, legal, or proprietary information, missing warnings and consent checkpoints can lead to accidental exposure or unsafe processing choices.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

L003 的描述全文使用中文并面向“当用户需要…时,使用本技能”的通用场景,但没有说明这是仅限中文用户或中文环境的技能,也未给出语言选择。按组织语言/locale 政策,若技能对输出或交互语言形成隐性强制,应提供用户选择或明确限定适用范围。

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 presented as operating on a local PDF, but it actually sends the full document to a remote WPS API for conversion. That mismatch creates a meaningful confidentiality risk because users may provide sensitive PDFs under the assumption processing is local, causing unintentional third-party disclosure.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code pulls authentication material from environment variables and uses it to access an external service, which expands the skill's trust boundary beyond ordinary file conversion. In this context, that is risky because a PDF utility skill does not obviously need ambient credentials, and users may not expect their local files to be processed under an external authenticated session.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code uploads the entire local PDF to a remote API with no explicit warning or consent step in the execution path. In a PDF-processing skill, this is dangerous because documents often contain sensitive personal, legal, financial, or internal business data, and silent transfer to a third party materially increases privacy and compliance risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

Natural-language strings in the module docstring, error messages, CLI description, and printed output are written only in Chinese, which imposes a specific language on users without opt-in. The file does not indicate that it is a region-specific or Chinese-only tool, nor does it offer locale selection.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstring describes results being written to output_path/content.md with images under output_path/images, implying ordinary relative project-local references. However, the replacer returns absolute paths for image links, which contradicts that interface description and the module-level statement about replacing with relative paths.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.