T09 · Insecure Skill Coding Practices
- Location
office-to-md/utils/pptConverter.js:65- Finding
Shell Command Injection Through a Crafted PPTX File Path
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This document-conversion skill has a coherent purpose, but its PPTX path can run shell commands from crafted filenames and may install Python packages automatically during conversion.
Review before installing. Use this only in a constrained workspace, avoid converting untrusted PPTX files, do not run it with privileged accounts, install dependencies explicitly in a controlled environment, and check for existing .md files before conversion. Treat preview output as document content and avoid using it on confidential files unless logs and agent responses are controlled.
office-to-md/utils/pptConverter.js:65Shell Command Injection Through a Crafted PPTX File Path
office-to-md/utils/pptConverter.js:53Automatic Installation of an Unpinned Python Dependency During Conversion
office-to-md/utils/pptConverter.js:49Predictable Shared Temporary Script Enables Symlink and Race-Condition Attacks
The documentation describes conversion behavior but does not clearly warn that the process writes a new .md file adjacent to the source path and may overwrite an existing Markdown file with the same basename. In an agent or automation context, this can cause unintended file modification or data loss because users may treat the operation as read-only parsing rather than a write operation.
The skill reads full document contents and several examples encourage printing previews, statistics, and excerpts to logs or console output, but the documentation does not include a privacy warning. In environments handling sensitive documents, this increases the risk of accidental disclosure through logs, previews, agent responses, or persisted debug output.
The module invokes external commands and generates/executess a temporary Python script to process input files, which expands the attack surface beyond ordinary in-process parsing. While the immediate command strings quote the file path, this design still relies on shell/process execution, ambient system tools, and a world-accessible temporary location, making the behavior more dangerous in an agent skill handling untrusted files.
This converter installs a Python package on the host at runtime using pip, which gives a file-conversion utility unnecessary software-management capability and changes the execution environment without user approval. In a shared or privileged environment, this can pull unpinned code from package indexes, enable dependency confusion or malicious package delivery, and create persistence or supply-chain risk well beyond document parsing.
Installing packages through a shell command without explicit user confirmation or policy checks is unsafe for a document conversion helper. It can unexpectedly mutate the host, download and execute third-party code during normal file handling, and violate least-privilege assumptions for users who only intended content extraction.
The code executes shell commands on user-supplied files during conversion, including running a generated Python script and, on fallback, unzip against the provided path. Even though the path is quoted, the behavior is not clearly disclosed and exposes the host to parser/tool vulnerabilities, denial-of-service conditions, and broader system interaction than users would expect from simple Markdown conversion.
The integration test accesses a hard-coded document under /root/clawd/downloads, causing the test script to read from a sensitive host-specific location outside its local test fixtures. Even though it first checks for existence, this still expands the skill's file-access scope and may expose private document contents in logs or downstream processing when the test is run in a privileged environment.
The usage example states Output file: /path/to/document.md, which indicates the skill creates a file on disk. The README does not provide any explicit user warning that running the skill will write output files into the source document's directory, which is a data-affecting behavior relevant for markdown-file warning requirements.
The dependency is specified with a caret range, which allows newer compatible releases to be installed than the one originally tested. This increases supply-chain risk and can also cause accidental uptake of a vulnerable or breaking release, especially for a document-conversion skill that processes untrusted files.
"author": "",
"license": "ISC",
"dependencies": {
"mammoth": "^1.6.0",
"office-text-extractor": "^2.0.0",
"pdf-parse": "^1.1.1",
"turndown": "^7.1.2",
The manifest does not pin mammoth, and mammoth has a known directory traversal advisory affecting some versions. In a skill designed to convert user-supplied office documents, a vulnerable parser is more dangerous because attackers may be able to craft malicious files that read unintended files or escape expected paths during processing.
The dependency is specified with a caret range, so installs are not fully reproducible and may pull in different versions over time. For a package that extracts text from office documents, this creates avoidable supply-chain exposure if a later release introduces malicious code or a security regression.
"license": "ISC",
"dependencies": {
"mammoth": "^1.6.0",
"office-text-extractor": "^2.0.0",
"pdf-parse": "^1.1.1",
"turndown": "^7.1.2",
"word-extractor": "^1.0.4"
Using a ranged version for pdf-parse means the installed code may vary between environments or over time. Because PDF parsing libraries handle complex untrusted input, silently absorbing dependency updates can increase exposure to newly introduced vulnerabilities or unexpected behavior.
"dependencies": {
"mammoth": "^1.6.0",
"office-text-extractor": "^2.0.0",
"pdf-parse": "^1.1.1",
"turndown": "^7.1.2",
"word-extractor": "^1.0.4"
}
The turndown dependency is not pinned to a single exact version, which weakens build determinism and expands supply-chain risk. While the direct impact is lower than a parser handling binary office files, it still allows unreviewed code changes to enter the runtime during future installs.
"mammoth": "^1.6.0",
"office-text-extractor": "^2.0.0",
"pdf-parse": "^1.1.1",
"turndown": "^7.1.2",
"word-extractor": "^1.0.4"
}
}
The word-extractor dependency uses a caret range, so future installs may resolve to different versions than the author tested. Since this library processes document content, that nondeterminism increases supply-chain and parser-related security risk when handling untrusted files.
"office-text-extractor": "^2.0.0",
"pdf-parse": "^1.1.1",
"turndown": "^7.1.2",
"word-extractor": "^1.0.4"
}
}
The function is named convertPdfToMd, suggesting conversion from PDF to Markdown, yet the code only reads the PDF text via pdf-parse, removes excessive blank lines, and returns plain text. The inline comments at L8-L10 also acknowledge it is returning text 'as is', which contradicts the stated conversion intent in the function/module naming.
The script repeatedly spawns a separate process to run another script rather than invoking local functions directly. Since no manifest is available establishing that subprocess execution is part of the skill's scope, this is an unjustified capability from a developer-intent perspective.
Detected: suspicious.dangerous_exec