Back to skill

Security audit

PDF编辑器

Security checks for vulnerabilities and agentic risk

Overview

This PDF editor is mostly purpose-aligned, but it exposes sensitive PDF viewing and editing endpoints on all network interfaces without authentication while describing itself as local-only.

Review before installing. Use this only on a trusted machine and network, avoid opening sensitive PDFs while the server binds to all interfaces, and prefer changing the server to localhost-only with authentication before routine use. Treat delete, redaction, and save actions as potentially permanent and keep backup copies.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (1)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/web_server.py:121
Finding

Unauthenticated Network Access to Loaded PDF Documents and Editing Operations

Content
View full analysis

Vulnerability Details

File Location: scripts/web_server.py, lines 121–304 and 332
Vulnerability Type: Missing authentication and unsafe network exposure
Risk Level: High

Vulnerable Code

python
def do_GET(self):
    parsed = urlparse(self.path)
    path = parsed.path
    params = parse_qs(parsed.query)

    # ...

    elif path.startswith('/api/text-blocks/'):
        try:
            page_num = int(path.split('/')[-1])
            EditorState.ensure()
            spans = EditorState.editor.get_page_text(page_num)
            # ...
            self._send_json(blocks)
        except Exception as e:
            self._send_json({"error": str(e)}, 400)
python
def do_POST(self):
    parsed = urlparse(self.path)
    path = parsed.path

    try:
        if path == '/api/open':
            form = self._parse_multipart()
            file_item = form.get('file')
            if file_item and isinstance(file_item, tuple) and len(file_item) == 2:
                filename, file_data = file_item
                tmp_file = os.path.join(EditorState.tmp_dir, 'document.pdf')
                with open(tmp_file, 'wb') as f:
                    f.write(file_data)
                EditorState.open(tmp_file)
                self._send_json(EditorState.editor.info())

        # ...

        elif path == '/api/download':
            EditorState.ensure()
            import io
            buf = io.BytesIO()
            EditorState.editor.doc.save(buf)
            buf.seek(0)
            filename = os.path.basename(EditorState.filepath or 'edited.pdf')
            if not filename.endswith('.pdf'):
                filename += '.pdf'
            self._send_binary(buf.read(), filename)
python
def do_DELETE(self):
    parsed = urlparse(self.path)
    path = parsed.path

    try:
        if path.startswith('/api/delete-page/'):
            page_num =
...[truncated 2896 chars]
Remediation
View remediation

Remediation Suggestions

  1. Bind to the loopback interface by default:
    python
    server = HTTPServer(('127.0.0.1', args.port), Handler)
    
  2. Require an explicit, prominently warned command-line option before allowing non-loopback binding.
  3. Generate a cryptographically random authorization token for every server launch and require it on all API requests, including read-only endpoints.
  4. Reject requests with unexpected Host and Origin headers to reduce cross-origin and DNS-rebinding exposure.
  5. Replace the process-wide shared editor state with state isolated by authenticated session.
  6. Apply authorization checks uniformly to document download, text extraction, rendering, upload, editing, saving, and deletion endpoints.
  7. Consider CSRF protection for state-changing operations, even when loopback binding is used.
  8. Add request-size limits for uploaded files and JSON or multipart bodies to reduce resource-exhaustion exposure.
  9. Document the actual listening interface and security model accurately rather than describing the service as purely local while binding it to all interfaces.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (10)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · templates/editor.html (reported line 172)May include surrounding context.

html
</div>

    <div class="main">
        <!-- Dropzone -->
        <div class="dropzone" id="dropzone">
            <div class="dropzone-inner"
                 ondragover="event.preventDefault();this.style.borderColor='#4285f4';this.style.background='#e8f0fe'"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The delete_text method redacts matching text and fills the area with white, which changes the document content irreversibly once saved. Although the docstring says 'Delete text by redacting it,' there is no user-facing warning or confirmation in the CLI before this content-destructive action is performed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The delete_pages method permanently removes pages from the open PDF and immediately saves the modified file, but there is no confirmation prompt or warning at the point of execution. This is a destructive operation affecting user data, and the code provides no explicit disclosure beyond the method name.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The server binds to 0.0.0.0, making the PDF editing interface reachable from other hosts on the local network and possibly beyond depending on firewall/NAT configuration. Because the API exposes file upload, document modification, and download actions with no authentication or CSRF protections, unintended remote access could let another user on the network manipulate documents or abuse the service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The document declares lang="zh-CN", and the visible UI strings throughout the file are presented only in Simplified Chinese. This imposes a specific language/locale on all users without any opt-in, fallback, or indication that the skill is intentionally region-specific.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The UI explicitly claims '纯本地处理,隐私安全' ('pure local processing, privacy safe'), but the code uploads the PDF to '/api/open' and sends subsequent edit actions to multiple server-side endpoints. This is a trust and privacy vulnerability because users may upload sensitive documents under a false belief that no server receives their data.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill states that all processing is local and that there are no network requests, yet it embeds an unrelated external promotional link. Even if the PDF processing itself is local, this weakens the trustworthiness of the security claims and can socially engineer users into visiting a third-party service from within a tool presented as offline-only.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script prints its primary user-facing status messages in Chinese only ("PDF Editor 已启动", "地址", "按 Ctrl+C 退出"). This imposes a specific language on all users without opt-in or fallback, which matches the language/locale policy violation category.

Content

No source excerpt is available for this finding.