T09 · Insecure Skill Coding Practices
- Location
SKILL.md:20- Finding
Shell Command Injection Through Templated Voice Command Arguments
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill’s PT-BR voice assistant purpose is coherent, but it ships a malformed shell-templated `/voz` trigger and unverified executable/dependency installation paths that warrant Review before use.
Do not install this as-is in a shared or sensitive environment. The publisher should replace the `/voz` shell-string action with structured argument passing or remove the trigger, fix the malformed YAML, add integrity checks for downloaded Piper assets, and use locked dependency hashes. If you do install after review, leave ANTHROPIC_API_KEY unset for local-only responses and use a trusted private WORKSPACE path.
SKILL.md:20Shell Command Injection Through Templated Voice Command Arguments
install.sh:92Remote Piper Executable Is Downloaded and Installed Without Integrity Verification
install.sh:72Python Dependencies Are Installed Without Hash-Locked Reproducibility
scripts/synthesize_universal.py:56Predictable Shared Temporary Files Permit Race Conditions and Cross-Invocation Output Substitution
The file pins PyTorch to version 2.1.2, and the supplied finding indicates multiple published advisories affecting that version, including unsafe deserialization and memory safety issues. In an agent skill context, ML frameworks often process untrusted model files, checkpoints, or inputs, which makes dependency-level RCE, DoS, or memory corruption risks materially more dangerous rather than theoretical.
The file pins transformers to version 4.36.2, and the finding reports multiple known vulnerabilities for that release, including deserialization-related issues and potential RCE/ReDoS classes of bugs. Because agent skills commonly download models, tokenizers, configs, or process attacker-controlled text inputs, a vulnerable transformers version increases the chance that malicious artifacts or crafted inputs could trigger compromise or service degradation.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
if VENV_PY.exists():
try:
result = subprocess.run(
[str(VENV_PY), "-c", "import torch, torchaudio, transformers; print('ok')"],
check=True,
capture_output=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
ok_all &= check("python dependencies", False, str(exc))
try:
result = subprocess.run(
[str(VENV_PY), str(SCRIPT_DIR / "scripts" / "voice_config.py"), "get"],
check=True,
capture_output=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
if os.environ.get("ANTHROPIC_API_KEY"):
try:
result = subprocess.run(
[str(VENV_PY), "-c", "import anthropic; print('ok')"],
check=True,
capture_output=True,
The installer announces and proceeds to download PT-BR voice models specifically, and the file also defines only PT-BR voice assets. This is a natural-language locale constraint embedded in the skill behavior without any visible user choice or documented opt-in, which can violate language/locale policy expectations.
The script can forward a media directive containing the generated audio path to an external OpenClaw session target whenever --target is supplied, and it does so silently with errors suppressed. In a skill that processes potentially sensitive audio/transcript data, this creates a real risk of unintended data disclosure or message exfiltration because the user is not explicitly warned or asked to confirm the outbound transmission.
The code can send transcripts to an external API and also execute a local model CLI, but there is no visible trust boundary, consent flow, or policy gate controlling when sensitive input is allowed to leave the host or trigger local execution. In a voice/transcript adapter, this increases data exposure and operational risk, especially if users assume processing is local-only.
User transcript content is transmitted to Anthropic whenever the API key is present, with no notice, redaction, or consent mechanism in the code path. If transcripts contain personal, confidential, or regulated data, this can create a privacy and compliance issue rather than a memory-safe code flaw.
The embedded system instruction explicitly requires responses in Portuguese brasileiro, imposing a fixed language/locale behavior. The file does not offer user opt-in or language selection, and no region-specific justification is present here.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def get_openclaw_response(transcript: str, timeout: int) -> str:
try:
result = subprocess.run(
["openclaw", "infer", "model", "run", "--prompt", transcript, "--json"],
capture_output=True,
text=True,
The fallback response reflects up to 80 characters of the user transcript back into output, which can disclose secrets, personal data, or sensitive spoken content into logs, consoles, downstream consumers, or UI surfaces. This is especially risky because the fallback is used precisely when other providers fail, a condition that often increases logging and troubleshooting visibility.
The available voices are all mapped to pt_BR models, and there is no natural-language indication that output is locale-specific or that users can choose another language. This creates a locale constraint without explicit opt-in or justification, which matches the language/locale policy concern.
The script uses predictable filenames in the shared system temp directory and unlinks them if present before writing new output. In a multi-user environment this can clobber other users' files or interact dangerously with symlinks/hardlinks, and it also enables race conditions around file replacement.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
path.unlink()
try:
subprocess.run(
[str(piper_bin), "--model", str(model_path), "--output_file", str(wav_path)],
input=text.encode("utf-8"),
capture_output=True,
The executable path ultimately depends on the WORKSPACE environment variable, allowing an attacker who can influence the environment or workspace contents to redirect execution to a malicious binary. Because the script only checks existence and executability, a trojaned Piper binary in attacker-controlled storage would run with the privileges of the calling process.
path.unlink()
try:
subprocess.run(
[str(piper_bin), "--model", str(model_path), "--output_file", str(wav_path)],
input=text.encode("utf-8"),
capture_output=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
raise SynthesisError(exc.stderr.decode("utf-8", errors="ignore")) from exc
try:
subprocess.run(
[
"ffmpeg",
"-y",
The script pins the ASR model to a Portuguese-only model, which enforces a specific language behavior rather than offering a user-selectable locale. This matches the policy category for language/locale violations because there is no opt-in, alternative language selection, or justification that the skill is intentionally region-specific.
The script emits user-facing strings such as "Vozes disponíveis", "feminina", and "masculina" only in Portuguese. Under the policy for natural-language behavior, forcing a specific language without user opt-in is a locale-policy violation unless the constraint is explicitly justified, which is not present here.
Usage and status messages like "Voz definida para" are hard-coded in Portuguese and shown for normal command execution and errors. Because the file does not offer opt-in language selection or state that the tool is region-specific, this constitutes a natural-language locale policy issue.
The README states the user should talk to the agent in Brazilian Portuguese, presenting a fixed language requirement rather than offering a language choice. This matches the language/locale policy concern because the constraint is imposed in natural language without explicit user opt-in or broader locale selection.
The dependency specifier anthropic>=0.51.0,<1.0 is not pinned to a single known-safe release, so the installed version may vary across environments and could resolve to a release affected by published advisories. This creates supply-chain uncertainty and makes it impossible to verify from this file alone whether vulnerable versions are being deployed.
The script invokes external binaries (Piper and ffmpeg) to process supplied text, but it provides no print/log message or explanatory comment disclosing that subprocess execution occurs. Because subprocess execution is a safety-relevant operation, some visible disclosure should be present unless it is explicitly communicated as part of the skill's behavior.
No suspicious patterns detected.