Back to skill

Security audit

8917 DOCX Official

Security checks for vulnerabilities and agentic risk

Overview

This document-conversion skill mostly matches its stated purpose, but its optional PDF path uses an under-disclosed native LibreOffice hook that users should review before installing.

Install only if you are comfortable with the PDF feature compiling native code and injecting it into LibreOffice. Prefer using only the DOCX path, or require the publisher to remove the LD_PRELOAD shim, avoid predictable /tmp shared objects, minimize the child-process environment, and clearly document any native helper behavior before use with sensitive documents.

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

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/md2docx.py:207
Finding

LibreOffice API hijacking through an unverified LD_PRELOAD socket shim

Content
View full analysis
#include #include #include #include #include static int (*real_socket)(int,int,int); static int (*real_socketpair)(int,int,int,int[2]); static int (*real_listen)(int,int); static int (*real_accept)(int,struct sockaddr*,socklen_t*); static int (*real_close)(int); static int (*real_read)(int,void*,size_t); static int is_shimmed[1024], peer_of[1024], wake_r[1024], wake_w[1024]; static int listener_fd=-1; __attribute__((constructor)) static void init(void){ real_socket=dlsym(RTLD_NEXT,"socket"); real_socketpair=dlsym(RTLD_NEXT,"socketpair"); real_listen=dlsym(RTLD_NEXT,"listen"); real_accept=dlsym(RTLD_NEXT,"accept"); real_close=dlsym(RTLD_NEXT,"close"); real_read=dlsym(RTLD_NEXT,"read"); for(int i=0;i<1024;i++){peer_of[i]=-1;wake_r[i]=-1;wake_w[i]=-1;} } int socket(int d,int t,int p){ if(d==AF_UNIX){int fd=real_socket(d,t,p);if(fd>=0)return fd; int sv[2];if(real_socketpair(d,t,p,sv)==0){ if(sv[0]>=0&&sv[0]<1024){is_shimmed[sv[0]]=1;peer_of[sv[0]]=sv[1]; int wp[2];if(pipe(wp)==0){wake_r[sv[0]]=wp[0];wake_w[sv[0]]=wp[1];}} return sv[0];}errno=EPERM;return -1;} return real_socket(d,t,p);} int listen(int s,int b){if(s>=0&&s<1024&&is_shimmed[s]){listener_fd=s;return 0;}return real_lis ...[truncated 4844 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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 (10)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This skill embeds C code, compiles it on the fly, and injects it into LibreOffice with LD_PRELOAD to alter low-level socket behavior. That is an extremely invasive technique commonly associated with sandbox bypasses or runtime hooking, and it can undermine host security assumptions far beyond normal document conversion.

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/md2docx.py (reported line 277)May include surrounding context.

python
def _get_soffice_env():
    """获取 LibreOffice 运行所需的环境变量(自动处理沙盒兼容)"""
    env = os.environ.copy()
    env["SAL_USE_VCLPLUGIN"] = "svp"
    if _needs_socket_shim():
        env["LD_PRELOAD"] = _ensure_shim()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises and instructs shell execution (python scripts/md2docx.py) plus file read/write and environment use, but declares no explicit tool scope or permission boundary. In an agent environment, this increases the chance of over-broad execution and unintended access to local files or command execution paths, especially because the workflow converts user-supplied content and may invoke external binaries like python3 and soffice.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

该 markdown 文件声明了触发词“正式文件”“官方格式”“转成 docx”等,其中部分短语在一般办公对话中也可能频繁出现,且未给出排除条件或负面示例来限定何时应激活本技能。根据规则,markdown 文件中的激活条件若缺乏明确边界,属于模糊触发风险。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module docstring states that the tool converts Markdown into documents compliant with Chinese official-document standards, and the rest of the usage text assumes that locale-specific format as the only mode. This is a natural-language locale constraint presented as mandatory behavior, with no opt-in or alternative locale selection documented.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
96% confidence
Finding

The code compiles a native shared object at runtime from embedded C source and later uses it for process injection via LD_PRELOAD. Even though the apparent goal is sandbox compatibility, runtime native compilation materially expands the attack surface: a writable temp directory, compiler invocation, and trust in dynamically produced native code can all be abused or can bypass intended execution restrictions.

Content

Scanner excerpt · scripts/md2docx.py (reported line 267)May include surrounding context.

python
return str(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,
    )

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/md2docx.py (reported line 300)May include surrounding context.

python
raise RuntimeError(
            "未找到 LibreOffice (soffice)。\n"
            "PDF 输出依赖 LibreOffice,请安装后重试:\n"
            "  Ubuntu/Debian: sudo apt install libreoffice\n"
            "  macOS: brew install --cask libreoffice\n"
            "  或从 https://www.libreoffice.org 下载"
        )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
86% confidence
Finding

The subprocess call launches LibreOffice on attacker-controlled document content, which is a high-risk parser/external application boundary. While arguments are passed safely as a list, converting untrusted documents through a large third-party application can expose the host to parser bugs, macro-like behaviors, or environment-based abuse—especially combined with the custom LD_PRELOAD injection path.

Content

Scanner excerpt · scripts/md2docx.py (reported line 319)May include surrounding context.

python
env = _get_soffice_env()

        result = subprocess.run(
            [soffice, '--headless', '--convert-to', 'pdf', tmp_docx, '--outdir', tmpdir],
            capture_output=True, text=True, timeout=120, env=env
        )

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The --pdf-only mode still writes an intermediate DOCX to a user-visible path before optionally deleting it, which can leave sensitive content exposed if deletion fails, races occur, or another process observes the file. For a document-generation tool handling potentially confidential government-style documents, this undermines user expectations about data minimization and transient artifact handling.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

描述中明确要求输出“符合中国党政机关公文/正式文件格式”的文档,但未说明这是仅在用户主动选择该地区/制度格式时适用,或是否支持其他语言/地区格式。该类自然语言约束可能构成语言/locale 方面的组织策略问题,尤其是在默认适用范围未清晰限定时。

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.