Back to skill

Security audit

Word Track Changes

Security checks for vulnerabilities and agentic risk

Overview

This skill coherently edits user-provided Word documents to add tracked changes, with no evidence of hidden network access, credential use, persistence, or unrelated behavior.

Install only if you want agents to modify DOCX files with tracked revisions. Use explicit output paths to preserve originals, and avoid running it on untrusted or unusually large DOCX files because archive extraction is not size-limited.

Vulnerability Patterns
  • 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
  • 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)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/track_changes.py:297
Finding
Unbounded DOCX Archive Extraction and XML Parsing## Vulnerability Details **File Location**: `scripts/track_changes.py`, lines 297–305 **Vulnerability Type**: Uncontrolled resource consumption through untrusted archive extraction and XML parsing **Risk Level**: Medium ### Vulnerable Code ```python def __init__(self, docx_path): self.docx_path = docx_path self.temp_dir = tempfile.mkdtemp(prefix='word_track_changes_') with zipfile.ZipFile(docx_path, 'r') as z: z.extractall(self.temp_dir) self.tree = ET.parse(os.path.join(self.temp_dir, 'word/document.xml')) self.root = self.tree.getroot() ``` ### Technical Analysis The processor treats an input DOCX file as a trusted ZIP archive and extracts every member with `ZipFile.extractall()` before parsing `word/document.xml`. It does not enforce limits on: - The number of archive members - The total uncompressed size - The uncompressed size of an individual member - Compression ratios - The size or structural complexity of the XML input A maliciously constructed DOCX can therefore contain a ZIP bomb or an abnormally large `word/document.xml`. Extraction may consume all available temporary storage, while XML parsing may consume excessive memory or CPU. The temporary directory is created before archive extraction, but initialization and helper functions do not guarantee cleanup through a context manager or `try/finally`. If extraction, parsing, modification, or saving raises an exception, extracted document data may remain in the temporary directory. ### Attack Path 1. An attacker creates a DOCX file containing highly compressed data, an excessive number of ZIP members, or an oversized `word/document.xml`. 2. The attacker supplies the file for processing through any documented CLI or the `TrackChangesProcessor` API. 3. The constructor calls `z.extractall(self.temp_dir)` without validating archive metadata or enforcing extraction quotas. 4. The archive expands until temporary storage is exhausted, or the oversized XML document ...[truncated 827 chars]
Remediation
## Remediation Suggestions 1. Inspect every `ZipInfo` entry before extraction and reject archives that exceed defined limits for: - Member count - Total declared uncompressed size - Per-member uncompressed size - Compression ratio - Maximum permitted XML size 2. Extract only the OOXML parts required by the application instead of calling `extractall()` on the entire archive. 3. Normalize and validate member paths before extraction. Reject absolute paths, parent-directory components, and any destination that resolves outside the temporary directory. 4. Stream archive members while tracking the number of bytes actually written. Do not rely exclusively on attacker-controlled ZIP metadata. 5. Apply explicit XML input-size limits before calling `ET.parse()`. Where practical, use bounded or incremental parsing and reject documents with excessive structural complexity. 6. Guarantee temporary-file cleanup with `tempfile.TemporaryDirectory`, a context manager, or `try/finally`. Cleanup must occur after constructor, parsing, processing, or saving failures. 7. Return a controlled validation error when archive limits are exceeded, and document the supported maximum DOCX size.
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The visible code aligns partially with the description's core purpose of enabling Track Changes on a Word document: it is a CLI named enable_tracking.py and calls a helper named enable_track_changes on an input/output DOCX. However, the description includes substantially broader capabilities—cross-run text matching, paragraph-level replacement, and producing tracked insertions/deletions—that are not present in this code chunk. Because the supplied code only wraps a helper function and provides no implementation of those advanced editing features, the description overstates what this specific chunk actually does. There is no evidence of unrelated or harmful capabilities, but there is a material description-versus-behavior mismatch in scope.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
This code writes modified document contents to disk in save(), and multiple convenience APIs default to writing back to the original input path when output_path is not provided. Although the methods have docstrings, there is no user-facing prompt, warning, or visible disclosure that the original .docx may be modified or overwritten.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The section is labeled as a convenience API, and the exported function `insert_text_with_revision` suggests text insertion. In reality, it calls `replace_text_with_revision(search_text, new_text)`, which replaces the matched text and records both a deletion and an insertion, contradicting the apparent documented intent of an insertion helper.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The module docstring is written only in Chinese ("标记文本为删除"), which imposes a specific language choice in user-facing documentation. The policy allows locale constraints only when justified or when users are given a language/locale choice, neither of which is present here.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The module docstring is written only in Chinese ("在Word文档中启用修订追踪"), which indicates a language-specific user-facing description without offering a language choice or documenting a justified locale restriction. The policy requires avoiding forced language or locale constraints unless the user opts in or the regional limitation is explicitly justified.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
This Python file contains natural-language strings exclusively in Chinese, including the module docstring and printed usage text. Under the policy rule, forcing a specific language without opt-in can be a locale-policy violation when no alternative or justification is provided.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The module docstring presents the CLI description solely in Chinese and does not offer an alternative language or indicate that the tool is region-specific. This can violate language/locale policy when users are not given a choice or clear justification for the enforced language.

Missing User Warnings

Low
Confidence
81% confidence
Finding
This code saves a modified document to the user-supplied output path, which affects user data on disk. While the script prints a success message afterward, there is no pre-action warning, confirmation, or explanatory comment/docstring disclosing that it will write the resulting document file.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The file's natural-language documentation, comments, and user-visible strings are written in Chinese, including the module description and runtime messages. This imposes a specific language/locale on users and maintainers without any opt-in or alternative language path documented in the file.

Description-Behavior Mismatch

Low
Confidence
84% confidence
Finding
The manifest emphasizes enabling Word Track Changes using OOXML elements, but the exported helper `enable_track_changes` does more than toggling an in-memory flag: it unzips the document, parses XML, and repackages a new DOCX on disk. While file rewriting is an expected implementation detail for OOXML editing, the API behavior is broader than the narrow name/description of simply enabling Track Changes.

Static analysis

No suspicious patterns detected.