Back to skill

Security audit

Office Generator Py

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed local Office document generator, with ordinary setup and file-writing behavior but some dependency and spreadsheet-content risks to manage.

Install this only in an isolated environment you trust, because setup downloads unpinned Python packages. Do not generate spreadsheets from untrusted JSON unless formula-like values are sanitized, and choose output paths carefully because generated files may overwrite existing files.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Warning
Location
scripts/setup_engine.py:19
Finding

Unpinned Dependencies Installed from Mutable Package Sources

Content
View full analysis

Vulnerability Details

File Location: scripts/setup_engine.py:19-25; scripts/engine/requirements.txt:1-6
Vulnerability Type: Unpinned third-party dependencies and non-reproducible installation
Risk Level: Medium

Vulnerable Code

python
def main() -> int:
    if not REQUIREMENTS.exists():
        raise FileNotFoundError(f'Requirements file not found: {REQUIREMENTS}')
    if not VENV_DIR.exists():
        run([sys.executable, '-m', 'venv', str(VENV_DIR)])
    python_bin = VENV_DIR / 'bin/python'
    run([str(python_bin), '-m', 'pip', 'install', '--upgrade', 'pip'])
    run([str(python_bin), '-m', 'pip', 'install', '-r', str(REQUIREMENTS)])

The requirements file contains no version or integrity constraints:

text
python-docx
docxtpl
openpyxl
XlsxWriter
python-pptx
pydantic

Technical Analysis

The setup process upgrades pip and installs all dependencies using mutable package names without exact versions or cryptographic hashes. Consequently, two installations performed at different times can resolve to different package or transitive-dependency versions.

The project does not contain evidence that the currently named packages are malicious. The vulnerability is the absence of controls ensuring that reviewed dependency artifacts are the artifacts installed later. If a package account, release, dependency, configured package index, or distribution artifact is compromised, the setup process can install attacker-controlled code.

Python packages may execute build backend logic while being built or installed. Installed malicious code could also execute when the document generator imports the affected package.

Attack Path

  1. An attacker compromises a declared package, one of its transitive dependencies, or a package index trusted by the executing environment.
  2. The attacker publishes a malicious release that satisfies the unconstrained dependency declaration.

...[truncated 1081 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin every direct dependency to an exact, reviewed version.
  2. Generate a lock file that includes resolved transitive dependencies.
  3. Record SHA-256 hashes for every permitted distribution and install with pip --require-hashes.
  4. Use a controlled package index or an internal artifact mirror containing reviewed packages.
  5. Remove the unconditional pip upgrade, or pin pip to a reviewed version and hash.
  6. Run installation in a restricted environment without unnecessary credentials or filesystem access.
  7. Add automated dependency vulnerability and provenance scanning to release workflows.
  8. Regularly update pins through a review process rather than allowing installation-time resolution.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/engine/generators/xlsx_generator.py:19
Finding

Spreadsheet Formula Injection Through Untrusted Cell Values

Content
View full analysis

Vulnerability Details

File Location: scripts/engine/generators/xlsx_generator.py:19-35
Vulnerability Type: Spreadsheet formula injection
Risk Level: Medium

Vulnerable Code

python
sheets: List[Dict[str, Any]] = spec.get('contentSpec', {}).get('sheets', [])
if sheets:
    workbook.remove(default_sheet)
    for sheet_spec in sheets:
        ws = workbook.create_sheet(title=sheet_spec.get('name', 'Sheet'))
        columns = sheet_spec.get('columns', [])
        rows = sheet_spec.get('rows', [])
        if columns:
            ws.append(columns)
            for idx, cell in enumerate(ws[1], start=1):
                cell.font = Font(bold=True)
                width = max(12, len(str(columns[idx - 1])) + 4)
                ws.column_dimensions[get_column_letter(idx)].width = width
            ws.freeze_panes = 'A2'
            ws.auto_filter.ref = ws.dimensions
        for row in rows:
            ws.append(row)

Technical Analysis

Spreadsheet column and row values originate from the JSON request and are passed directly to openpyxl through Worksheet.append. No distinction is made between ordinary text and formulas.

In particular, openpyxl treats strings beginning with = as formulas when serializing workbook cells. Other leading characters such as +, -, or @ can also receive special interpretation depending on the spreadsheet application and import context.

An attacker who controls document content can therefore supply a value such as an external-reference or hyperlink formula rather than ordinary text. The resulting workbook remains structurally valid, so the dangerous content may only become apparent when a recipient opens it in spreadsheet software.

Formula behavior depends on the recipient's spreadsheet application, security settings, protected-view configuration, and whether the user approves external-content prompts. Arbitrary operating-system command execu ...[truncated 1598 chars]

Remediation
View remediation

Remediation Suggestions

  1. Treat all user-provided spreadsheet values as literal text by default.
  2. Before writing a string, detect formula-triggering prefixes such as =, +, -, and @, including values where whitespace or control characters precede the prefix.
  3. Neutralize dangerous textual values by prefixing them with an apostrophe or explicitly setting the cell data type to a literal string.
  4. If formulas are a required feature, define a separate, explicit formula field and permit formulas only for trusted callers.
  5. Validate permitted formulas against a restrictive allowlist and reject external references, hyperlinks, dynamic-data functions, and unsupported functions.
  6. Apply the same protection to both column headings and row values.
  7. Add regression tests confirming that malicious input is stored and displayed as text rather than serialized as a formula.
  8. Document whether the generator supports formulas so callers do not rely on ambiguous string handling.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (28)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill instructs use of Python scripts, environment variables, file reads/writes, and shell commands, but the manifest does not declare any tool scope such as permissions or allowed-tools. This creates a trust and containment gap: an agent may invoke broader capabilities than a reviewer or policy system can infer from the skill metadata, increasing the chance of unintended command execution or filesystem access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The slide title suffix uses fixed Chinese text (续 {idx}/{len(chunks)}), which imposes a specific language in generated output regardless of user preference. This is a natural-language locale choice embedded in the skill with no opt-in or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This JSON template hardcodes the title, purpose, section headings, and placeholder content in Chinese. Because the file provides no indication that the template is region-specific or that users can opt into another language, it appears to enforce a specific language by default, which matches the locale-policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The template title and all slide labels are hard-coded in Chinese, which imposes a specific language on generated content. The file provides no indication that language selection is optional or that the template is intended only for a Chinese-language or region-specific context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The title, purpose, and slide headings are all fixed in Chinese, which implies the skill enforces a specific language/locale by default. The file does not indicate user opt-in, language selection, or a justified region-specific limitation, so this is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The natural-language metadata and column labels are entirely in Chinese, and the file provides no indication that this is a region-specific template or that users can opt into this locale. That can violate language/locale policy when the skill is presented in environments where language choice is expected.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script allows the executable path to be fully overridden via OFFICE_GENERATOR_PYTHON, causing the skill to run an arbitrary interpreter or binary rather than the bundled engine runtime. In an agent/skill context, this expands the skill from document generation into general code execution if an attacker can influence environment variables or packaging, which is broader and materially more dangerous than the advertised capability.

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/engine/business_cli.py (reported line 53)May include surrounding context.

python
def run(cmd: list[str]) -> int:
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.stdout:
        print(result.stdout.strip())
    if result.stderr:

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

python
def run(cmd: list[str]) -> int:
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.stdout:
        print(result.stdout.strip())
    if result.stderr:

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

python
def run(cmd: list[str]) -> None:
    subprocess.run(cmd, check=True)


def main() -> int:

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This markdown file includes example titles and content in Chinese, which can imply a default or expected language for skill inputs. The document does not state that other languages are supported or that Chinese is only illustrative, so it may conflict with a language-choice policy.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This code creates parent directories and saves a generated document to the provided output path, which is a filesystem write operation. There is no confirmation prompt, logging/print statement, or explanatory comment/docstring disclosing that the skill will modify the local filesystem.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This code creates directories and saves a PowerPoint file to the path provided by out_path, which is a file-write operation. In this file there is no confirmation prompt, logging/print statement, or explanatory comment/docstring disclosing that the skill will write output to the filesystem.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code writes a workbook to the filesystem using a caller-provided path, which can affect user data or overwrite existing files. There is no confirmation prompt, logging/print statement, or explanatory comment/docstring in this file disclosing that behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This code invokes document generators with an output path, which implies writing files to disk, but the file itself provides no confirmation prompt, warning comment, or user-facing disclosure beyond a generic CLI description. For a code-file review under this rule, file writes should have some visible disclosure unless the behavior is clearly documented as part of the skill's stated purpose.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency list uses unpinned package names, so builds may resolve to different versions over time. This creates supply-chain risk and makes it impossible to verify whether vulnerable or breaking releases will be installed, especially for a document-generation engine that parses and emits complex Office/XML formats.

Content

Scanner excerpt · scripts/engine/requirements.txt (reported line 1)May include surrounding context.

text
python-docx
docxtpl
openpyxl
XlsxWriter

Unverifiable Dependency: python-docx has 2 known advisory(ies) (CVE-2016-5851 (Improper Restriction of XML External Entity Reference in python-docx); CVE-2016-5851 (python-docx before 0.8.6 allows context-dependent attackers to conduct XML Exter)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding

python-docx has known advisories, including XXE-related issues, but the manifest does not pin a version, so there is no way to determine whether deployed environments use a fixed release. In a skill that generates or may manipulate Office XML content, unresolved version ambiguity increases the chance of exposing XML parser weaknesses.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The docxtpl package is not version-pinned, allowing non-deterministic installs and increasing exposure to vulnerable or malicious upstream releases. In a templating component that generates Office documents, unexpected dependency changes can alter parsing/rendering behavior and widen attack surface.

Content

Scanner excerpt · scripts/engine/requirements.txt (reported line 2)May include surrounding context.

text
python-docx
docxtpl
openpyxl
XlsxWriter
python-pptx

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

openpyxl is unpinned, so the installed version may vary by environment or over time. Because this library processes spreadsheet/XML content and has had prior security advisories, leaving it unpinned prevents assurance that only fixed versions are used.

Content

Scanner excerpt · scripts/engine/requirements.txt (reported line 3)May include surrounding context.

text
python-docx
docxtpl
openpyxl
XlsxWriter
python-pptx
pydantic

Unverifiable Dependency: openpyxl has 2 known advisory(ies) (CVE-2017-5992 (Improper Restriction of XML External Entity Reference in Openpyxl); CVE-2017-5992 (Openpyxl 2.4.1 resolves external entities by default, which allows remote attack)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding

openpyxl has known XXE-related advisories, and because no version is pinned, the installed release cannot be verified as safe. Spreadsheet libraries often process attacker-influenced workbook structures, so uncertainty around patched status is a real security concern even if exploitability depends on broader usage context.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

XlsxWriter is specified without a version constraint, which weakens build reproducibility and opens the door to accidental adoption of unsafe or incompatible releases. Even if no specific advisory is cited here, unpinned dependencies are a recognized supply-chain hygiene problem.

Content

Scanner excerpt · scripts/engine/requirements.txt (reported line 4)May include surrounding context.

text
python-docx
docxtpl
openpyxl
XlsxWriter
python-pptx
pydantic

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

python-pptx is unpinned, meaning the package manager may fetch different versions in different installs. For an Office-generation skill, this increases supply-chain and stability risk because document-processing libraries often handle complex file structures and parsers.

Content

Scanner excerpt · scripts/engine/requirements.txt (reported line 5)May include surrounding context.

text
docxtpl
openpyxl
XlsxWriter
python-pptx
pydantic

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

pydantic is unpinned, preventing reliable control over which validation engine version is installed. Since this package has had multiple advisories, version ambiguity can expose the skill to known denial-of-service or parsing issues depending on the resolved release.

Content

Scanner excerpt · scripts/engine/requirements.txt (reported line 6)May include surrounding context.

text
openpyxl
XlsxWriter
python-pptx
pydantic

Unverifiable Dependency: pydantic has 4 known advisory(ies) (CVE-2021-29510 (Use of "infinity" as an input to datetime and date fields causes infinite loop i); CVE-2024-3772 (Pydantic regular expression denial of service); CVE-2021-29510 (Pydantic is a data validation and settings management using Python type hinting.) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding

pydantic has multiple published advisories, but the unpinned requirement makes it impossible to confirm whether the installed version includes the fixes. If the skill validates untrusted input, an affected version could enable denial-of-service or other parsing-related issues depending on the code paths used.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This manifest-like JSON template uses Chinese-only title, purpose, headings, and placeholder text, which imposes a specific language on users. The file does not indicate that Chinese is optional, user-selected, or justified as a region-specific template.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.