T09 · Insecure Skill Coding Practices
- Location
scripts/voice_translate_app/notifier.py:47- Finding
Shell Command Injection Through Notification Hooks
- Content
View full analysis
None: if not command: return subprocess.run(command, input=text.encode("utf-8"), shell=True, check=True) def _run_audio_command(self, command: str | None, audio_file: Path) -> None: if not command: return if "{audio_file}" in command: resolved = command.format(audio_file=str(audio_file)) else: resolved = f'{command} "{audio_file}"' subprocess.run(resolved, shell=True, check=True) ``` Related standalone wrapper: ```python command = args.command_template.format(audio_file=shlex.quote(str(audio_path))) if args.dry_run: print(command) return subprocess.run(command, shell=True, check=True) ``` ### Technical Analysis Notification commands are accepted from command-line arguments or environment-backed command templates and passed to `subprocess.run` with `shell=True`. This causes the system shell to interpret command separators, substitutions, redirections, pipelines, and other metacharacters. The audio notifier introduces an additional injection boundary by interpolating `audio_file` directly into the shell command. In the placeholder branch, the path is inserted without any quoting. In the fallback branch, it is enclosed in double quotes but embedded quote characters are not escaped. Because the generated audio path includes the operator-provided output directory, an attacker who can influence that directory can potentially insert shell syntax into the resulting command. The standalone sender uses `shlex.quote` for the audio path, which protects that specif ...[truncated 1729 chars]- Remediation
View remediation
