T09 · Insecure Skill Coding Practices
- Location
pdf_vocab_audio.py:177- Finding
Predictable Shared Output Path Permits Symlink-Based File Overwrite
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill does what it claims, but it can send PDF-derived text to an external TTS service and writes predictable output in /tmp without clear enough privacy and filesystem safety controls.
Install only if you are comfortable with PDF-derived text being processed by edge-tts and with generated MP3s being written to /tmp. Avoid confidential PDFs unless the publisher adds an explicit privacy notice, stricter extraction, a private output directory, and pinned dependencies.
pdf_vocab_audio.py:177Predictable Shared Output Path Permits Symlink-Based File Overwrite
pdf_vocab_audio.py:68PDF Text Is Transmitted to an External TTS Service Without Explicit Disclosure
SKILL.md:16Third-Party Python Dependencies Are Installed Without Version or Integrity Pinning
The skill documentation indicates capabilities to read files, write output, and invoke shell-accessible binaries (edge-tts, ffmpeg) but does not declare any explicit tool scope such as permissions or allowed-tools. This creates an authorization and review gap: an agent or platform may grant broader-than-necessary access, making misuse or accidental overreach harder to constrain, especially since the skill processes user-supplied PDFs and writes files to /tmp.
The security documentation claims all paths are temporary and non-sensitive, but the implementation reads from /root/.openclaw/media/inbound and writes to /tmp. Misleading security claims can cause operators to trust the skill with sensitive PDFs under false assumptions, increasing the chance of unintended disclosure.
The script extracts text from PDFs and sends it to an external TTS program without any explicit privacy warning or consent flow. In context, PDFs may contain proprietary or personal vocabulary lists, and users may not realize content is being passed to another component that could have network behavior or logging side effects.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"--text", word,
"--write-media", output_path
]
result = subprocess.run(
cmd,
capture_output=True,
text=True,
Using edge-tts and ffmpeg through subprocess.run gives the skill process-execution capability. While audio generation is consistent with the overall goal, spawning external binaries is a stronger capability than the manifest describes and is not explicitly declared in scope.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"-q:a", "9",
output_path
]
result = subprocess.run(cmd, capture_output=True, timeout=10)
return result.returncode == 0
The ffmpeg concat operation consumes a list file containing file paths written without escaping or rejecting special characters such as quotes or newlines. Because output file names are derived from the PDF basename and temporary/audio paths are then written into concat_list.txt, a crafted filename could corrupt the concat manifest and potentially make ffmpeg read unintended files or fail in unsafe ways.
"-c", "copy",
output_path
]
result = subprocess.run(cmd, capture_output=True, timeout=60)
return result.returncode == 0
finally:
if os.path.exists(list_file):
When no path is supplied, the script silently scans a hard-coded inbound directory and processes the newest PDF. This creates an implicit data access behavior not obvious from the skill description and could cause unintended processing of sensitive documents placed in that directory.
The markdown specifies a fixed British English male voice (en-GB-RyanNeural) and presents it as the default behavior, with no indication that users can choose another language or locale. This is a natural-language locale constraint and can violate language/locale policy when no opt-in or alternative is offered.
The docstring and all printed user-facing messages are written in Chinese, and the output filename also uses Chinese text. This imposes a specific language/locale on users without any documented choice, opt-in, or region-specific justification.
Writing the generated MP3 to a fixed world-known location under /tmp can expose output data to other local users or processes, depending on system configuration and file permissions. It also contradicts the stated design goal of keeping paths temporary and non-sensitive.
No suspicious patterns detected.