Back to skill

Security audit

Docx Cn 1.0.1

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly for Word document workflows, but it uses under-disclosed LibreOffice macro/profile and native preload behavior that creates review-worthy local execution and persistence risk.

Review before installing. Use this only in an isolated workspace for documents you trust, avoid global npm installation where possible, and be aware that accepting tracked changes uses LibreOffice macro/profile state under /tmp and conversion may use LD_PRELOAD native code. Treat outputs as document mutations and keep backups of important files.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (5)

T07 · Tool Hijacking and Spoofing

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

Predictable shared LD_PRELOAD library enables local tool 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 code stores a native shared library at the fixed path `/tmp/lo_socket_shim.so`. If that path already exists, `_ensure_shim()` trusts it without checking its owner, permissions, file type, resolved path, or contents. When AF_UNIX socket creation is unavailable, the existing file is assigned to `LD_PRELOAD` and loaded into the LibreOffice process. `LD_PRELOAD` libraries execute native initialization code in the target process before normal application execution. Consequently, accepting an attacker-controlled file at this location creates a direct local code-execution primitive. The source file `/tmp/lo_socket_shim.c` is also predictable and written non-atomically. The implementation does not reject symbolic links or protect the check-then-use sequence from replacement races. ### Attack Path 1. A local attacker who can write to the shared temporary directory creates `/tmp/lo_socket_shim.so` as a malicious shared library, or replaces the file between validation and LibreOffice execution. 2. The Skill runs in an environment where `_needs_shim()` returns `True`. 3. `_ensure_shim()` det ...[truncated 814 chars]
Remediation
View remediation

T06 · System Persistence

Error
Location
scripts/accept_changes.py:14
Finding

Shared persistent LibreOffice profile permits macro and configuration 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 Skill uses a fixed LibreOffice profile under `/tmp` and retains it across executions. That profile can contain macros, application configuration, extensions, recovery data, and other LibreOffice state. The existing `Module1.xba` file is considered trusted if its text merely contains the string `AcceptAllTrackedChanges`. The complete macro content is not compared against the expected template, and ownership, permissions, regular-file status, and syml ...[truncated 1647 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/comment.py:35
Finding

Unescaped comment fields allow OOXML injection

Content
View full analysis
{text} """ ``` ```python def _append_xml(xml_path: Path, root_tag: str, content: str) -> None: dom = defusedxml.minidom.parseString(xml_path.read_text(encoding="utf-8")) root = dom.getElementsByTagName(root_tag)[0] ns_attrs = " ".join(f'xmlns:{k}="{v}"' for k, v in NS.items()) wrapper_dom = defusedxml.minidom.parseString(f"{content}") for child in wrapper_dom.documentElement.childNodes: if child.nodeType == child.ELEMENT_NODE: root.appendChild(dom.importNode(child, True)) output = _encode_smart_quotes(dom.toxml(encoding="UTF-8").decode("utf-8")) xml_path.write_text(output, encoding="utf-8") ``` ```python _append_xml( comments, "w:comments", COMMENT_XML.format( id=comment_id, author=author, date=ts, initials=initials, para_id=para_id, text=text, ), ) ``` ### Technical Analysis The `text`, `author`, and `initials` values can originate from command-line input and are interpolated directly into XML markup. The generated string is then parsed as XML, meaning supplied markup is interpreted structurally rather than encoded as text. Requiring callers to pre-escape XML is not a security control. It makes correct escaping dependent on every caller and intentionally permits well-formed in ...[truncated 1604 chars]
Remediation
View remediation
`, single and double quotes, namespace prefixes, and attempted closing tags. - Validate the resulting OOXML package before repacking it. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:61
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/unpack.py:52
Finding

Office archives are extracted without decompression resource limits

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The declared description focuses specifically on Word document processing (.docx) with user-facing capabilities like creating, reading, editing, formatting, tables, and images. The supplied code is a lower-level packaging utility that rebuilds Office files from an unpacked directory, condenses XML, and optionally validates/auto-repairs against schemas and redlining rules. It also supports .pptx and .xlsx outputs, which exceed the stated Word-only scope. While .docx support overlaps partially, the primary behavior is materially different from the declared purpose, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description says this skill processes Word documents directly (.docx creation, reading, editing, formatting, tables, images). However, the supplied code chunk is not document-processing logic. It is infrastructure code for running LibreOffice safely in sandboxed environments by detecting blocked AF_UNIX sockets, compiling a native shim, and preloading it into the soffice process. While this may support document conversion or office automation indirectly, the primary behavior shown is environment/runtime manipulation and subprocess execution, not Word document operations. That is a materially different purpose and includes undeclared capabilities such as runtime native compilation and LD_PRELOAD-based process injection.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The declared description suggests a general Word document manipulation skill focused on .docx content and features like formatting, tables, and images. The supplied code instead is a utility for unpacking Office Open XML containers and normalizing their internal XML representation. Its primary purpose is archive extraction and XML preprocessing, not direct document authoring or editing. It also supports PowerPoint and Excel files, which are outside the declared Word-only scope. While the DOCX-specific XML cleanup could support document editing workflows, the actual behavior is materially narrower and lower-level than the declared purpose, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description says this skill processes Word documents by creating, reading, and editing them, with support for formatting, tables, and images. The supplied code instead provides a CLI tool for validating Office document internals, including unpacking Office zip containers, running DOCX/PPTX schema validation, optional redlining validation, and limited XML auto-repair. This is a materially different primary purpose from document authoring/editing. It also extends beyond the declared Word-only scope by handling PPTX and XLSX file types. Therefore the description does not accurately represent the code’s actual behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

The declared description focuses on Word document manipulation features: creating, reading, editing, formatting, tables, and images for .docx files. The actual code chunk is an init.py for validator modules, exporting BaseSchemaValidator, DOCXSchemaValidator, PPTXSchemaValidator, and RedliningValidator. This indicates a validation-oriented component, not a document-processing implementation. It also references PPTX and redlining, which are outside the stated Word/.docx-only scope. While this may be part of a larger office-processing package, the supplied code chunk itself materially differs from the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description says the skill creates, reads, and edits Word .docx documents, emphasizing document authoring/manipulation features like formatting, tables, and images. The supplied code does not implement document creation or general editing. Instead, it is a validator for unpacked OOXML packages, with checks for XML well-formedness, namespaces, unique IDs, references, relationship IDs, content types, and XSD compliance. It also covers not just Word but also PowerPoint and Excel structures via schema mappings and namespaces. A small repair function exists, but it only adds xml:space='preserve' where needed, which is far narrower than general Word document editing. Therefore the code's primary purpose is materially different from the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description suggests a broad end-user Word document processing feature set (create/read/edit .docx, formatting, tables, images). The code chunk instead provides a narrow validator for DOCX XML contents and schema-like constraints, plus a small repair routine for durableId values. While it is related to Word documents and .docx internals, its primary purpose is validation of document structure rather than document authoring or editing. This is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear description-behavior mismatch. The declared purpose says the skill handles Word documents (.docx) for creation, reading, and editing with support for formatting, tables, and images. The supplied code is specifically a PPTXSchemaValidator for PowerPoint files, working on unpacked presentation XML and validating slide-related relationships and schema rules. Its primary purpose is validation of PowerPoint presentation package structure, not Word document manipulation. This is a materially different file type, domain, and capability set from what was declared.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The description promises a broad Word document processing skill for creating, reading, and editing .docx files, including formatting, tables, and images. The supplied code does not implement those general document operations. Instead, it specifically validates tracked changes in WordprocessingML by parsing document.xml, checking <w:ins>/<w:del> elements for a given author, unpacking the original .docx ZIP, normalizing/removing that author's tracked changes, comparing resulting text, and optionally invoking git diff for diagnostics. This is a materially different primary purpose: redlining validation rather than general Word document processing. While it is related to Word documents, the implemented capability is narrower and different enough that the declared description does not accurately represent the actual behavior.

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>

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill embeds and executes a LibreOffice Basic macro to operate on documents, adding executable macro capability to a feature advertised as normal Word document processing. Executing application macros on the host significantly increases risk because it introduces script execution inside a complex desktop suite and may enable persistence, profile abuse, or interaction with untrusted documents in ways users would not expect from the stated scope.

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

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill clearly instructs use of shell commands, file reads/writes, and document unpack/repack workflows, but it declares no explicit tool scope or allowed-tools. That creates unnecessary ambient authority and reduces reviewability, making it easier for the skill to invoke powerful capabilities without operator awareness.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger words include very broad everyday terms like 'Word' and '文档', which can cause the skill to activate in unrelated conversations and gain access to file/shell workflows unexpectedly. Overbroad activation increases the chance of accidental invocation on sensitive content or in contexts where document-manipulation tools should not run.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The instruction to use a fixed author name ('Claude') for tracked changes and comments alters document provenance without user consent. In legal, HR, academic, or audit-sensitive workflows, this can misattribute edits, undermine trust, and create integrity or compliance issues.

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,

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script modifies the host LibreOffice user profile under /tmp and installs a macro as part of ordinary document handling, which exceeds straightforward DOCX read/edit behavior and introduces persistent host-side state. That broadens the attack surface and can create cross-run interference, especially in shared or multi-tenant environments where another process could tamper with the profile or benefit from the installed macro.

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
86% confidence
Finding

The script writes a macro file into a LibreOffice profile and copies/modifies the output DOCX without any explicit consent or warning beyond normal function behavior. Silent host-state modification is dangerous in agent or automation contexts because operators may assume the tool only transforms the target document, not that it also installs executable artifacts on the system.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The function writes modified XML back to the input path in place, changing document contents without any confirmation prompt, visible log/print, or explicit warning in this file about the destructive nature of the operation. Because this alters user document data directly, users may not realize the original file contents are being overwritten.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Setting LD_PRELOAD causes the target process to load attacker-influenceable native code before its normal libraries. In this file, the preload target is a shared object placed in the temp directory, making the document-processing path significantly more dangerous because compromise of that file yields code execution whenever soffice runs.

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
94% confidence
Finding

Generating C code and compiling it during normal execution is dangerous because it expands the trust boundary from Python to the system compiler, loader, and writable temp storage. In this skill context, the compiled artifact is immediately used for process injection, so any tampering of the temp source or shared object can turn document processing into arbitrary native code execution.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

The code writes C source to a world-writable temporary directory and invokes gcc to compile a shared object that is later injected with LD_PRELOAD. Even though the embedded source is constant, using predictable temp-file paths creates a race/symlink attack surface where a local attacker could replace the source or output path and obtain arbitrary code execution in the soffice process context.

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,