Back to skill

Security audit

Docx

Security checks for vulnerabilities and agentic risk

Overview

This DOCX skill mostly fits document editing, but unsafe LibreOffice shims/macros and under-disclosed Office-file scope need review before installation.

Review this skill before installing, especially on shared machines or when processing untrusted Office files. Prefer isolating it in a container, pinning and locally installing npm dependencies, restricting it to DOCX if that is the intended scope, and replacing the fixed /tmp LibreOffice profile and LD_PRELOAD shim with private per-run temporary directories or safer conversion settings.

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

T07 · Tool Hijacking and Spoofing

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

Predictable 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 shared library and C source use fixed, predictable names in the system-wide temporary directory: - `/tmp/lo_socket_shim.so` - `/tmp/lo_socket_shim.c` When `_SHIM_SO` already exists, `_ensure_shim()` trusts it without verifying its owner, permissions, type, content, or cryptographic digest. If Unix-domain sockets are unavailable, the unverified library is assigned to `LD_PRELOAD` and inherited by LibreOffice. `LD_PRELOAD` causes the dynamic loader to execute initialization code from the specified shared library before the target program's normal execution. Consequently, accepting an attacker-created library at this path is equivalent to executing attacker-controlled native code. There is also a race between checking whether the library exists, creating source and output files, and subsequently using the compiled library. Predictable paths in a shared temporary directory make symlink and replacement attacks possible. ### Attack Path 1. An attacker with local write access to the shared temporary directory creates `/tmp/lo_socket_shim.so`. 2. The malicious library contains a constructor that p ...[truncated 1004 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/accept_changes.py:13
Finding

Predictable LibreOffice Profile Allows Macro Hijacking

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 code uses the fixed profile `/tmp/libreoffice_docx_profile` and executes a Basic macro from that profile. An existing `Module1.xba` is trusted if its textual contents merely contain the string `AcceptAllTrackedChanges`. This substring test does not establish that the macro matches the expected implementation. An attacker- ...[truncated 1657 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:58
Finding

Unpinned Global npm Installation Introduces Supply-Chain Risk

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

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

Unbounded Office Archive Extraction Enables Resource Exhaustion

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

If the skill can operate on PPTX structures and PresentationML relationships while being advertised as DOCX-only, the agent may route unrelated presentation tasks into an unexpectedly powerful package-validation path. This broadens attack surface and breaks user expectations about what data and file types the skill may inspect or modify.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

If the skill can operate on PPTX structures and PresentationML relationships while being advertised as DOCX-only, the agent may route unrelated presentation tasks into an unexpectedly powerful package-validation path. This broadens attack surface and breaks user expectations about what data and file types the skill may inspect or modify.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

If the skill can operate on PPTX structures and PresentationML relationships while being advertised as DOCX-only, the agent may route unrelated presentation tasks into an unexpectedly powerful package-validation path. This broadens attack surface and breaks user expectations about what data and file types the skill may inspect or modify.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

If the skill can operate on PPTX structures and PresentationML relationships while being advertised as DOCX-only, the agent may route unrelated presentation tasks into an unexpectedly powerful package-validation path. This broadens attack surface and breaks user expectations about what data and file types the skill may inspect or modify.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

If the skill can operate on PPTX structures and PresentationML relationships while being advertised as DOCX-only, the agent may route unrelated presentation tasks into an unexpectedly powerful package-validation path. This broadens attack surface and breaks user expectations about what data and file types the skill may inspect or modify.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

If the skill can operate on PPTX structures and PresentationML relationships while being advertised as DOCX-only, the agent may route unrelated presentation tasks into an unexpectedly powerful package-validation path. This broadens attack surface and breaks user expectations about what data and file types the skill may inspect or modify.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the skill can operate on PPTX structures and PresentationML relationships while being advertised as DOCX-only, the agent may route unrelated presentation tasks into an unexpectedly powerful package-validation path. This broadens attack surface and breaks user expectations about what data and file types the skill may inspect or modify.

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 418)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 499)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>

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code copies the current environment, conditionally sets LD_PRELOAD, and launches LibreOffice, introducing system-level process and runtime-linker manipulation not disclosed by the skill's document-centric description. In this context, hidden process injection is more dangerous because users and reviewers would reasonably expect document handling, not native library interception.

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

A document-processing skill has no clear need to generate and inject a native LD_PRELOAD shim, making this behavior unusually powerful and risky for the declared purpose. The combination of compiling C code and preloading it into another process expands the attack surface from document conversion into arbitrary native-code execution within the spawned process.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest says this skill is for creating, reading, editing, or manipulating Word documents (.docx files), but this file implements validation logic for PowerPoint PresentationML content, slide layouts, and notes-slide relationships. Handling PPTX-specific internals is a different document format and capability than the manifest describes.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill clearly instructs use of shell commands, filesystem reads/writes, and external tooling, but it does not declare any explicit tool scope or permissions boundary. That mismatch increases the chance the agent will invoke broader capabilities than intended, making accidental file access, document conversion, or archive manipulation harder to constrain or audit.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger text is broad enough to capture generic requests like reports, memos, letters, or polished documents, even when the user did not ask for DOCX handling. In this context that is risky because invocation grants access to shell/file/archive workflows, so over-triggering can cause unnecessary processing of user files with a more privileged skill than needed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The script writes to a predictable global path under /tmp for the LibreOffice profile and macro storage, then later trusts existing content there if it contains the target function name. On a multi-user system, an attacker could pre-create or modify files in that location, potentially causing the process to execute attacker-controlled LibreOffice Basic code when the application macro is invoked.

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,

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

This code performs an in-place file write to the document XML, which changes user document content on disk. Although the module docstring explains the purpose of simplifying tracked changes, there is no explicit warning, confirmation, or user-facing disclosure at the point where the overwrite occurs.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file explicitly advertises support for PPTX and XLSX even though the skill manifest scopes the capability to DOCX/Word documents. This is a real scope-drift issue because it exposes undocumented functionality that downstream policy, review, and user expectations may not account for, increasing the chance of unsafe or unauthorized file handling.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The pack() function accepts .pptx and .xlsx outputs and processes them through the same packaging path, extending behavior beyond the declared DOCX-only skill contract. In an agent environment, undocumented capabilities are dangerous because routing, permissioning, and review may assume only Word document operations while this code can manipulate other Office container types.

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

The code writes C source into the system temp directory and invokes gcc to build a shared object, which is a file-write plus subprocess execution flow. Although the module docstring explains the shim at a high level, these safety-relevant actions have no local confirmation, logging, or explicit user-facing warning near the operation itself.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

This code compiles a native shared object at runtime from a world-writable temporary directory and later loads it through LD_PRELOAD. In a multi-user or adversarial local environment, predictable temp-path artifacts can be replaced, raced, or pre-created, causing attacker-controlled native code to execute whenever soffice is launched.

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,

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module docstring and argument validation explicitly support '.docx', '.pptx', and '.xlsx', and the code unpacks all three formats. The manifest, however, scopes the skill to Word documents (.docx) and says not to use it for spreadsheets, creating a semantic mismatch between claimed purpose and actual behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.