T09 · Insecure Skill Coding Practices
- Location
music_mcp.py:117- Finding
Broad Process Control Through an Unscoped Command-Line Pattern
- Content
View full analysis
str: try: subprocess.run(['pkill', '-f', PLAYER_CMD], check=False) return '已经停止播放。' except Exception as e: return f'停止失败:{str(e)}' @mcp.tool() def pause_music() -> str: try: subprocess.run(['pkill', '-STOP', '-f', PLAYER_CMD], check=False) return '音乐已暂停。' except Exception as e: return f'暂停失败:{str(e)}' @mcp.tool() def resume_music() -> str: try: subprocess.run(['pkill', '-CONT', '-f', PLAYER_CMD], check=False) return '继续播放。' except Exception as e: return f'继续播放失败:{str(e)}' ``` ### Technical Analysis The three remotely exposed MCP tools use `pkill -f` with the configured `PLAYER_CMD` as a process-matching pattern. The `-f` option matches against complete process command lines and is not restricted to player processes started by this application. Consequently, every accessible process whose command line matches the configured string may be terminated, suspended, or resumed. The code does not retain the `subprocess.Popen` object or PID created by `play_url`, verify process ownership beyond the operating system's ordinary user boundary, or confirm that a matched process is one of the application's players. Although the list-form subprocess invocation prevents ordinary shell metacharacter injection, it does not prevent overly broad process matching. The effect is particularly dangerous if `PLAYER_CMD` is short, generic, or incorrectly configured. ### Attack Path 1. The service starts with `PLAYER_CMD` set to a value that also appears in unrelated process command lines. 2. An attacker or unauthorized caller with access to the connected MCP endpoint invokes `stop_music`, `pause_music`, or `resume_music`. 3. The application executes `pkill -f` wit ...[truncated 965 chars]- Remediation
View remediation
