Back to skill

Security audit

Docx Cn

Security checks for vulnerabilities and agentic risk

Overview

This Word document skill is mostly purpose-related, but it uses under-disclosed local code-execution and persistent temporary-profile mechanisms that need review before installation.

Install only if you are comfortable running local document-processing code that invokes LibreOffice, may compile and preload a native shim, writes to /tmp, and edits/unpacks Office files. Prefer a sandboxed environment, avoid processing untrusted Office files, pin and install npm dependencies locally, and clear or isolate LibreOffice temporary profiles before use.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (6)

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/office/soffice.py:27
Finding

Predictable Temporary Shared Library Enables LD_PRELOAD Hijacking

Content
View full analysis
dict: env = os.environ.copy() env["SAL_USE_VCLPLUGIN"] = "svp" if _needs_shim(): shim = _ensure_shim() env["LD_PRELOAD"] = str(shim) return env _SHIM_SO = Path(tempfile.gettempdir()) / "lo_socket_shim.so" def _ensure_shim() -> Path: if _SHIM_SO.exists(): return _SHIM_SO src = Path(tempfile.gettempdir()) / "lo_socket_shim.c" src.write_text(_SHIM_SOURCE) subprocess.run( ["gcc", "-shared", "-fPIC", "-o", str(_SHIM_SO), str(src), "-ldl"], check=True, capture_output=True, ) src.unlink() return _SHIM_SO ``` ### Technical Analysis The shared-library path is a fixed, predictable filename in the system-wide temporary directory. If `/tmp/lo_socket_shim.so` already exists, the code accepts it without verifying its ownership, file type, permissions, integrity, or expected contents. When Unix-domain sockets are unavailable, `get_soffice_env()` places this file in `LD_PRELOAD`. The operating system's dynamic loader will then load the library into the LibreOffice process before normal dependencies. Consequently, an attacker who can create the filename before the legitimate process can substitute an arbitrary shared library. The source file `/tmp/lo_socket_shim.c` is also created through a predictable path without exclusive creation or symlink checks, creating an additional race condition during compilation. ### Attack Path 1. A local attacker monitors or predicts use of the document conversion functionality. 2. Before the first legitimate invocation, the attacker creates `/tmp/lo_socket_shim.so` containing malicious constructor code. 3. The Skill runs in an environment where `_needs_shim()` returns `True`. 4. `_ensure_shim()` o ...[truncated 808 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/accept_changes.py:14
Finding

Predictable Shared LibreOffice Profile Enables Macro and Profile Poisoning

Content
View full analysis
bool: macro_dir = Path(MACRO_DIR) macro_file = macro_dir / "Module1.xba" if macro_file.exists() and "AcceptAllTrackedChanges" in macro_file.read_text(): return True if not macro_dir.exists(): subprocess.run( [ "soffice", "--headless", f"-env:UserInstallation=file://{LIBREOFFICE_PROFILE}", "--terminate_after_init", ], capture_output=True, timeout=10, check=False, env=get_soffice_env(), ) macro_dir.mkdir(parents=True, exist_ok=True) try: macro_file.write_text(ACCEPT_CHANGES_MACRO) return True except Exception as e: logger.warning(f"Failed to setup LibreOffice macro: {e}") return False ``` ### Technical Analysis The LibreOffice user profile and Basic macro are stored at a fixed path beneath `/tmp`. Existing macro content is trusted if it merely contains the string `AcceptAllTrackedChanges`. This substring check does not establish that the macro is the expected implementation and does not detect additional malicious Basic statements. LibreOffice profiles contain executable macros and other security-sensitive configuration. Reusing a predictable profile therefore permits both direct ...[truncated 1164 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/office/unpack.py:52
Finding

Unbounded Office Archive Extraction Allows Resource Exhaustion

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/office/validate.py:71
Finding

Validation Leaves Extracted Documents in Persistent Temporary Directories

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:59
Finding

Unpinned Global npm Installation Creates Supply-Chain Exposure

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/office/validators/base.py:146
Finding

Validators Parse Untrusted Office XML Without Consistent Parser Hardening

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (39)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The description presents a user-facing Word document processing capability focused on creating, reading, and editing .docx documents and their content/features. The code instead is a low-level Office packaging tool: it copies an unpacked directory, condenses XML/.rels files, optionally validates and auto-repairs against an original file, and writes a zipped Office container. It also supports .pptx and .xlsx, which exceeds the declared Word-only scope. While this may be part of a document-processing pipeline, the primary purpose and exposed capabilities differ materially from the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description suggests a user-facing Word document processing skill focused on creating, reading, and editing .docx files and supporting common document features like formatting, tables, and images. The actual code instead performs archive extraction of Office Open XML files and rewrites internal XML files for editing. It also supports PowerPoint and Excel files, which are outside the declared Word-only scope. While some DOCX-related editing support exists, it is specifically low-level XML/package manipulation (merge runs, simplify redlines), not the broadly described Word document operations. This is a material purpose/capability mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents a general Word document manipulation capability: create, read, and edit .docx documents with formatting, tables, and images. The supplied code does not implement document authoring or content editing features. Instead, its primary purpose is validation of Office document internals: schema validation, tracked-changes/redlining checks, unpacking Office files, and optional low-level XML auto-repair. It also supports .pptx and mentions .xlsx, which broadens scope beyond Word. While this is still related to Office documents, the actual behavior is materially different from the declared end-user functionality, so this is a clear mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
81% confidence
Finding

The declared description focuses on Word document processing operations such as creating, reading, and editing .docx files. The actual code shown is an init.py that exposes validator classes. It specifically includes a PPTXSchemaValidator, which extends beyond the declared Word-only scope, and the visible behavior is centered on validation module exports rather than Word document manipulation. Based on this code chunk alone, the implemented purpose does not accurately match the declared end-user functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents a user-facing Word document processing skill for creating, reading, and editing .docx files with content features like formatting, tables, and images. The supplied code does not implement document authoring or content editing. Instead, it provides backend validation and limited repair for unpacked OOXML document packages by parsing XML files, validating namespaces, uniqueness constraints, relationship references, content type declarations, and XSD conformance. It also clearly supports multiple Office formats via schema mappings for Word, PowerPoint, and Excel. This is a materially different primary purpose from the declared Word document processing description, so it is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description suggests a user-facing Word document manipulation skill: creating, reading, and editing .docx documents with support for formatting, tables, and images. The supplied code instead is a specialized validator for unpacked DOCX internal XML files, focused on correctness and schema compliance of document.xml/comments.xml/numbering.xml and related metadata. It does not implement general document authoring or editing features such as adding text, formatting, tables, or images. It also includes a repair routine for durableId values, which is a low-level XML correction capability absent from the description. While this code is related to Word documents, its primary purpose is materially different from the declared one, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This is a clear description-behavior mismatch. The declared purpose says the skill handles Word documents (.docx) for creation, reading, and editing. The supplied code is specifically a PPTX validator: class name PPTXSchemaValidator, file path validators/pptx.py, PresentationML namespace constants, and checks for slide masters, slide layouts, notes slides, and relationship files under ppt/.... There is no logic for Word document creation, reading, editing, formatting, tables, or images. The primary purpose and file type are materially different from the declaration.

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

CRITICAL: Use smart quotes for new content. When adding text with apostrophes or quotes, use XML entities to produce smart quotes:

xml
<!-- Use these entities for professional typography -->
<w:t>Here&#x2019;s a quote: &#x201C;Hello&#x201D;</w:t>

| Entity | Character |

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

xml
<w:p>
  <w:pPr>
    <w:numPr>...</w:numPr>  <!-- list numbering if present -->
    <w:rPr>
      <w:del w:id="1" w:author="Claude" w:date="2025-01-01T00:00:00Z"/>
    </w:rPr>

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

If LibreOffice times out, the function still returns a success message even though the operation did not complete normally. This can cause downstream systems or users to trust an output document that may still contain unaccepted tracked changes, be partially modified, or be otherwise inconsistent, creating integrity and workflow-security issues.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/office/soffice.py (reported line 25)May include surrounding context.

python
def get_soffice_env() -> dict:
    env = os.environ.copy()
    env["SAL_USE_VCLPLUGIN"] = "svp"

    if _needs_shim():

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Dynamically compiling a shared library and forcing it into another process with LD_PRELOAD is a highly privileged mechanism that changes process behavior at load time. In the context of a Word-processing skill, this is unusually powerful and expands the attack surface far beyond normal document conversion, especially if an attacker can influence the temp directory contents or the spawned environment.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill invokes shell commands and performs file read/write operations, but it does not declare any tool scope or allowed-tools restrictions. This increases the blast radius because an agent may execute filesystem and shell actions more broadly than intended when the skill is triggered.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger terms include very broad words like 'Word' and '文档', which can match ordinary conversation and cause unintended activation of a skill with shell and file-manipulation capabilities. Overbroad activation increases the risk of accidental document conversion, unpacking, or filesystem changes in unrelated contexts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The instruction to always use 'Claude' as the author for tracked changes/comments overrides user choice and can misattribute edits in legal, audit, or compliance-sensitive documents. This can corrupt provenance metadata and create accountability or integrity issues when document authorship matters.

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

python
]

    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The manifest describes Word document processing such as creating, reading, editing, formatting, tables, and images. This file implements that feature by creating a LibreOffice macro on disk and invoking external soffice subprocesses to execute it, which is a distinct capability not justified by the manifest text itself.

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

python
return True

    if not macro_dir.exists():
        subprocess.run(
            [
                "soffice",
                "--headless",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code performs a direct file write to the input document XML, modifying user data in place. Although the module docstring explains what the function does, there is no runtime confirmation, warning, or explicit disclosure near the write operation that the original file will be altered.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This file launches the soffice executable and, when needed, also launches gcc to compile native code. While invoking LibreOffice may be an implementation detail for document handling, spawning a compiler to alter runtime behavior is not an obvious requirement of the stated Word-processing functionality.

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

python
def run_soffice(args: list[str], **kwargs) -> subprocess.CompletedProcess:
    env = get_soffice_env()
    return subprocess.run(["soffice"] + args, env=env, **kwargs)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The helper silently writes C source into the system temporary directory and manages executable artifacts without clear controls. Beyond disclosure concerns, this is risky because temporary directories are commonly shared attack surfaces where insecure file creation can enable tampering or replacement by local adversaries.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
97% confidence
Finding

The code writes C source into a world-writable temporary directory, then invokes gcc to compile a shared object that is later injected via LD_PRELOAD. This introduces a dangerous code-execution path and creates opportunities for local file-race, symlink, or pre-placement attacks if another process can manipulate the temp files or output path.

Content

Scanner excerpt · scripts/office/soffice.py (reported line 59)May include surrounding context.

python
src = Path(tempfile.gettempdir()) / "lo_socket_shim.c"
    src.write_text(_SHIM_SOURCE)
    subprocess.run(
        ["gcc", "-shared", "-fPIC", "-o", str(_SHIM_SO), str(src), "-ldl"],
        check=True,
        capture_output=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The helper invokes gcc to compile a shared library, which is a subprocess execution with system impact, but there is no confirmation prompt, logging, or explicit nearby warning that an external compiler will be run. The stated purpose is running soffice, not compiling native code, so this side effect is not clearly disclosed to users of the function.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring presents this script as a command line tool to validate Office document XML files, but it also supports --auto-repair and invokes repair() on validators, which modifies document contents. Repairing document XML is a separate write/edit capability beyond straightforward validation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.